import java.util.*; // We are making this an *immutable* class. The state that an object has when constructed is its state permanently. // Instead of making changes to objects we create new ones (with attemptMove() and the constructor). public class GameState { Square[] boardSquares; //Tracks the game board as a 1D array of Square objects (effectively 12 x 12) with 2 layers of sentinel squares all around. boolean isWhitesTurn; //Knows whose turn it is public GameState() { //Set turn to white isWhitesTurn = true; //Initialize squares with legal starting position. boardSquares = new Square[] { new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.ROOK, true), new Square(Square.KNIGHT, true), new Square(Square.BISHOP, true), new Square(Square.KING, true), new Square(Square.QUEEN, true), new Square(Square.BISHOP, true), new Square(Square.KNIGHT, true), new Square(Square.ROOK, true), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), //white new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.PAWN, true), new Square(Square.PAWN, true), new Square(Square.PAWN, true), new Square(Square.PAWN, true), new Square(Square.PAWN, true), new Square(Square.PAWN, true), new Square(Square.PAWN, true), new Square(Square.PAWN, true), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), //white pawns new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.EMPTY), new Square(Square.EMPTY), new Square(Square.EMPTY), new Square(Square.EMPTY), new Square(Square.EMPTY), new Square(Square.EMPTY), new Square(Square.EMPTY), new Square(Square.EMPTY), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.EMPTY), new Square(Square.EMPTY), new Square(Square.EMPTY), new Square(Square.EMPTY), new Square(Square.EMPTY), new Square(Square.EMPTY), new Square(Square.EMPTY), new Square(Square.EMPTY), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.EMPTY), new Square(Square.EMPTY), new Square(Square.EMPTY), new Square(Square.EMPTY), new Square(Square.EMPTY), new Square(Square.EMPTY), new Square(Square.EMPTY), new Square(Square.EMPTY), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.EMPTY), new Square(Square.EMPTY), new Square(Square.EMPTY), new Square(Square.EMPTY), new Square(Square.EMPTY), new Square(Square.EMPTY), new Square(Square.EMPTY), new Square(Square.EMPTY), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.PAWN, false), new Square(Square.PAWN, false), new Square(Square.PAWN, false), new Square(Square.PAWN, false), new Square(Square.PAWN, false), new Square(Square.PAWN, false), new Square(Square.PAWN, false), new Square(Square.PAWN, false), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), //white pawns new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.ROOK, false), new Square(Square.KNIGHT, false), new Square(Square.BISHOP, false), new Square(Square.KING, false), new Square(Square.QUEEN, false), new Square(Square.BISHOP, false), new Square(Square.KNIGHT, false), new Square(Square.ROOK, false), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), //black new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), new Square(Square.OUT_OF_BOUNDS), }; } // zero-based index for col and row. Note that -1 and -2 are valid indices into the array, just OUT_OF_BOUNDS. public Square getSquare(int col, int row) { return boardSquares[12*2 + 2 + col + row * 12]; } public GameState getStateAfterMove(Move m) { //See if it is legal. If not, return null. //Create a new object based on this one, update the board state accordingly. return null; } public ArrayList getAllPossibleMoves() { ArrayList moves = new ArrayList(); //Loop through all squares for(int index = 0; index < boardSquares.length; index++) { int type = boardSquares[index].getType(); if (type == Square.OUT_OF_BOUNDS) continue; if (type == Square.EMPTY) continue; //For each square, find all possible places that piece can move to. if (type == Square.KING) moves.addAll(findAllMovesFor(index, new int[] {1,-1,12,-12,13,-13,11,-11}, false)); if (type == Square.QUEEN) moves.addAll(findAllMovesFor(index, new int[] {1,-1,12,-12,13,-13,11,-11}, true)); if (type == Square.BISHOP) moves.addAll(findAllMovesFor(index, new int[] {13,-13,11,-11}, true)); if (type == Square.ROOK) moves.addAll(findAllMovesFor(index, new int[] {1,-1,12,-12}, true)); if (type == Square.KNIGHT) moves.addAll(findAllMovesFor(index, new int[] {10,14,23,25,-10,-14,-23,-25}, false)); } return moves; } private ArrayList findAllMovesFor(int index, int[] directions, boolean canMoveMultipleSquares) { ArrayList moves = new ArrayList(); //loop through the directions, see if they work - return the resulting arraylist. for(int dir : directions) { int destIndex = index + dir; int type = boardSquares[destIndex].getType(); if (boardSquares[index].isWhite() != isWhitesTurn) continue; //don't move other person's pieces! if (type == Square.OUT_OF_BOUNDS) continue; if (type == Square.EMPTY || boardSquares[destIndex].isWhite() != isWhitesTurn) { moves.add(new Move(index, destIndex)); } } return moves; } // returns something like "checkmate", "stalemate", etc. public String getFeedback() { return null; } }