package ai;
import gui.PlayNetGameScreen;
import java.util.List;
import utility.GuiUtility;
import logic.Move;
import models.Board;
import models.Game;
import models.Piece;
import models.Square;
import com.google.common.collect.Lists;
/**
* AIAdapter.java
*
* Class to implement the Adapter Pattern and give AI plug ins an interface of
* methods to call to get information about the Game being played.
*
* @author Drew Hannay
*
* CSCI 335, Wheaton College, Spring 2011 Phase 3 April 11, 2011
*/
public class AIAdapter
{
/**
* The Game being viewed by the AI plug in
*/
private Game mGame;
/**
* The array of boards for reference.
*/
private AIBoard[] mBoards;
/**
* Constructor
*
* @param game The Game being played
*/
public AIAdapter(Game game)
{
mGame = game;
}
/**
* @return The game
*/
public Game getGame()
{
return mGame;
}
/**
* @param aiPlugin The AI logical analysis plugin for decision trees
*/
public void runGame(AIPlugin aiPlugin)
{
if (m_playNetGameScreen == null)
try
{
m_playNetGameScreen = GuiUtility.getChessCrafter().getNetGameScreen();
}
catch (Exception e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
m_playNetGameScreen.setIsRunning(true);
while (m_playNetGameScreen.isRunning())
{
while (mGame.isBlackMove())
{
try
{
Thread.sleep(200);
}
catch (InterruptedException e)
{
}
AIBoard[] boards = getBoards();
FakeMove fm = aiPlugin.getMove(boards);
playMove(fm);
}
try
{
Thread.sleep(0);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
/**
* @param move The move that it wishes to try
* @return Whether it moved there or not.
*/
public boolean playMove(FakeMove move)
{
try
{
Board board = mGame.getBoards()[move.mBoardIndex];
mGame.playMove(new Move(board, board.getSquare(move.mOriginRow, move.mOriginColumn), board.getSquare(move.mDestinationRow,
move.mDestinationColumn), move.mPromotionPieceName));
return true;
}
catch (Exception e)
{
return false;
}
}
/**
* @return The array of boards in terms of AIBoard type.
*/
public synchronized AIBoard[] getBoards()
{
if (mGame.isStaleLegalDests())
mGame.genLegalDests();
mBoards = new AIBoard[mGame.getBoards().length];
for (int i = 0; i < mBoards.length; i++)
mBoards[i] = new AIBoard(mGame.getBoards()[i]);
return mBoards;
}
/**
* @author Drew Hannay The AIBoard class. This is the board the AI "sees"
* and acts upon, similar to networking games.
*/
public class AIBoard
{
/**
* Two dimensional Array of AISquares representing the AIBoard
*/
protected AISquare squares[][];
/**
* If movement beyond the East and West edges of the board results in
* further relocation.
*/
private boolean wraparound;
/**
* The max column for this AIBoard
*/
private int maxColumn;
/**
* The max row for this AIBoard
*/
private int maxRow;
/**
* @param b The AI board for reference to all of its components.
*/
public AIBoard(Board b)
{
wraparound = b.isWrapAround();
squares = new AISquare[b.getMaxRow()][b.getMaxCol()];
maxColumn = b.getMaxCol();
maxRow = b.getMaxRow();
for (int row = 1, col = 1; row <= b.getMaxRow(); row++)
{
for (col = 1; col <= b.getMaxCol(); col++)
{
// Initialize the AISquares.
// ignore counting from zero.
squares[row - 1][col - 1] = new AISquare((row), (col), b.getSquare(row, col).isHabitable(), null);
}
}
for (int row = 1, col = 1; row <= b.getMaxRow(); row++)
{
for (col = 1; col <= b.getMaxCol(); col++)
{
// Initialize the AISquares.
// ignore counting from zero.
if (b.getSquare(row, col).getPiece() != null)
squares[row - 1][col - 1].setPiece(new AIPiece(b.getSquare(row, col).getPiece(), this));
}
}
}
/**
* @return If the board is a wraparound board (if right and left edges
* connect)
*/
public boolean isWraparound()
{
return wraparound;
}
/**
* @return The max col for the AI Board
*/
public int maxCol()
{
return maxColumn;
}
/**
* @return The max row for the AI Board
*/
public int maxRow()
{
return maxRow;
}
/**
* Getter method for AISquares at specified position.
*
* @param row Row number
* @param col Column number
* @return The Square at specified position.
*/
public AISquare getSquare(int row, int col)
{
// Use x-1 and y-1 so that we can maintain the illusion of counting
// from
// 1.
return squares[row - 1][col - 1];
}
}
/**
* @author Drew Hannay The class for AI squares.
*/
public class AISquare
{
/**
* Row Index of AISquare
*/
private int row;// File
/**
* Column Index of AISquare
*/
private int col;// Rank
/**
* If the AISquare is able to be occupied.
*/
private boolean isHabitable;
/**
* The AIPiece occupying this AISquare
*/
private AIPiece piece;
/**
* Constructor
*
* @param row The row number
* @param col The col number
* @param isHabitable If it can hold a piece
* @param piece The piece on it, if there is one.
*/
public AISquare(int row, int col, boolean isHabitable, AIPiece piece)
{
this.row = row;
this.col = col;
this.isHabitable = isHabitable;
this.piece = piece;
}
/**
* Getter method for index to Row
*
* @return Index to Row
*/
public int getRow()
{
return row;
}
/**
* Setter for piece.
*
* @param p The new piece.
*/
public void setPiece(AIPiece p)
{
piece = p;
}
/**
* Getter method for index to Column
*
* @return Index to Column
*/
public int getCol()
{
return col;
}
/**
* Getter method for Piece occupying the Square
*
* @return Piece occupying the Square.
*/
public AIPiece getPiece()
{
return piece;
}
/**
* Getter method for ability of AISquare to be occupied.
*
* @return If AISquare can be occupied.
*/
public boolean isHabitable()
{
return isHabitable;
}
}
/**
* @author Drew Hannay This is the AIPiece class to distinguish between
* normal and AI pieces.
*/
public class AIPiece
{
/**
* The name of this AIPiece
*/
private String name;
/**
* The color of this AIPiece
*/
private boolean isBlack;
/**
* The Board this AIPiece is on
*/
private AIBoard board;
/**
* List of legal AISquares for this AIPiece to move to
*/
protected List<AISquare> legalDests;
/**
* @param p The piece we are extracting data from
* @param b The board the AI piece is on
*/
public AIPiece(Piece p, AIBoard b)
{
name = p.getName();
isBlack = p.isBlack();
board = b;
legalDests = transformLegalDests(p.getLegalDests());
}
/**
* @param legalDests The legal destinations of the piece in standard
* terms
* @return The legal destinations of the piece in terms of AI Squares
*/
private synchronized List<AISquare> transformLegalDests(List<Square> legalDests)
{
List<AISquare> toReturn = Lists.newArrayList();
for (Square s : legalDests)
if (board.getSquare(s.getRow(), s.getCol()) != null)
toReturn.add(board.getSquare(s.getRow(), s.getCol()));
return toReturn;
}
/**
* @return Name of piece
*/
public String getName()
{
return name;
}
/**
* @return Color of piece
*/
public boolean isBlack()
{
return isBlack;
}
/**
* @return Board this piece is on
*/
public AIBoard getBoard()
{
return board;
}
/**
* @return Legal destinations for this piece
*/
public List<AISquare> getLegalDests()
{
return legalDests;
}
}
private PlayNetGameScreen m_playNetGameScreen;
}