// this is an algorithm to determine whether the player is in check // this is acheievd by searching the other players pieces and seeing whether the friendly king // is occupying one of the other players piece's possible moves public bool isInCheck(Board gameBoard) { PieceSet[] pieceSets = gameBoard.getPieceSets(); PieceSet BlackPieces = pieceSets[0]; PieceSet WhitePieces = pieceSets[1]; Piece kingToCheck = null; if (this.getPlayerColour() == Piece.Piececolour.BLACK) { foreach (Piece piece in BlackPieces.getPieceSet()) { if (piece.getType() == Piece.pieceType.KING) { kingToCheck = piece; } } } if (this.getPlayerColour() == Piece.Piececolour.WHITE) { foreach (Piece piece in WhitePieces.getPieceSet()) { if (piece.getType() == Piece.pieceType.KING) { kingToCheck = piece; // set the piece variable with this king piece. } } } if (kingToCheck != null) // makes sure that the piece is not null. { if (this.getPlayerColour() == Piece.Piececolour.BLACK) { foreach (Piece piece in WhitePieces.getPieceSet()) { if (piece.getPossibleMoves(gameBoard).Contains(kingToCheck.getPosition())) // populates each pieces possible moves and then scans those possible moves to see whether the kingToCheck has the same position as one of those moves { return(true); } } return(false); } else // otherwise the player is using black pieces { foreach (Piece piece in BlackPieces.getPieceSet()) { if (piece.getPossibleMoves(gameBoard).Contains(kingToCheck.getPosition())) { return(true); } } return(false); } } return(false); // if the piece is null then return false as their is no comparisons made. }
//sets up the board by creating two piecelists, initiallising those lists. //also initallising the square object array. public void setUpBoard(Piece.Piececolour player1colour) { //instantiates square objects for (int j = 0; j < 8; j++) { for (int k = 0; k < 8; k++) { squares[j, k] = new Square(); } } PieceSet blackPieces = new PieceSet(); PieceSet whitePieces = new PieceSet(); // invokes methods which set all the properties if each piece blackPieces.setInitalPieceList(Piece.Piececolour.BLACK, squares, player1colour); whitePieces.setInitalPieceList(Piece.Piececolour.WHITE, squares, player1colour); pieceSets[0] = blackPieces; pieceSets[1] = whitePieces; //assigns the x and y co-ordinate properties to the squares of the board for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { squares[i, j].X = i; squares[i, j].Y = j; } } //sets the squares that the pieces are on, to occupied status foreach (Piece piece in blackPieces.getPieceSet()) { piece.getPosition().occ = true; } foreach (Piece piece in whitePieces.getPieceSet()) { piece.getPosition().occ = true; } }
// this checks whether the current player is in the checkmate game state private bool isCheckMated() { //the clicked piece variable is going to change as a result of a temporary move // so it is stored temporarily to return to the current game state Piece tempPieceHolder = clickedPiece; int nullCounter = 0; // a null counter to count all the pieces that have no possible moves if (BoardAdmin.game1.getTurn() == Piece.Piececolour.WHITE) { PieceSet WhitePieces = gameBoard.getPieceSets()[1]; foreach (Piece aPiece in WhitePieces.getPieceSet()) { possiblemoves = aPiece.getPossibleMoves(gameBoard); clickedPiece = aPiece; foreach (Square possiblemove in possiblemoves) { if (possiblemove != aPiece.getPosition()) { makeTempMove(possiblemove); // makes the temporary move from that possible move in the list, the makeTempMove algorithm will make any non-valid moves null. } else // otherwise, make the move null as you cant move to the current square. { int index = Array.IndexOf(possiblemoves, possiblemove); // gets index of the position of the possible move possiblemoves[index] = null; } } bool a = false; // a boolean flag to store a simple result of whether all moves are invalid. int nullcounter2 = 0; // a counter to count how many possible moves are null for an individual piece foreach (Square possiblemove in possiblemoves) { if (possiblemove == null) { nullcounter2++; } } // if ALL possible moves are null then set the boolean flag to true if (nullcounter2 == possiblemoves.Length) { a = true; } // otherwise set the boolean flag to false if (nullcounter2 != possiblemoves.Length) { a = false; } if (a == true) { nullCounter++; } //clear the possible moves array for the next piece in the for loop Array.Clear(possiblemoves, 0, possiblemoves.Length); } clickedPiece = tempPieceHolder; if (nullCounter == WhitePieces.getPieceSet().Count) { return(true); } else { return(false); } } else // runs to check whether BLACK is in check mate then runs the same code but for black pieces specifically. { PieceSet BlackPieces = gameBoard.getPieceSets()[0]; foreach (Piece aPiece in BlackPieces.getPieceSet()) { possiblemoves = aPiece.getPossibleMoves(gameBoard); clickedPiece = aPiece; foreach (Square possiblemove in possiblemoves) { if (possiblemove != aPiece.getPosition()) { makeTempMove(possiblemove); } else { int index = Array.IndexOf(possiblemoves, possiblemove); possiblemoves[index] = null; } } bool a = false; int nullcounter2 = 0; foreach (Square possiblemove in possiblemoves) { if (possiblemove == null) { nullcounter2++; } } if (nullcounter2 == possiblemoves.Length) { a = true; } if (nullcounter2 != possiblemoves.Length) { a = false; } if (a == true) { nullCounter++; } Array.Clear(possiblemoves, 0, possiblemoves.Length); } clickedPiece = tempPieceHolder; if (nullCounter == BlackPieces.getPieceSet().Count) { return(true); } else { return(false); } } }
// evaluates whether the king can perform the castle procedure by finding the kingside rook and determining // whether both the king and rook havent moved yet and whether the spaces between them are empty public bool canCastle(Square targetPosition, Board gameBoard) { // if the target position is castling then the square will be 2 x - coordinates away if (Math.Abs(targetPosition.X - this.getPosition().X) == 2) { PieceSet blackpieces = gameBoard.getPieceSets()[0]; PieceSet whitepieces = gameBoard.getPieceSets()[1]; Rook kingsideRook = null; if (this.getColour() == Piececolour.BLACK) { foreach (Piece piece in blackpieces.getPieceSet()) { if (piece.getType() == pieceType.ROOK) { if (Math.Abs(this.getPosition().X - piece.getPosition().X) == 3) { kingsideRook = (Rook)piece; } } } } if (this.getColour() == Piececolour.WHITE) { foreach (Piece piece in whitepieces.getPieceSet()) { if (piece.getType() == pieceType.ROOK) { if (Math.Abs(this.getPosition().X - piece.getPosition().X) == 3) { kingsideRook = (Rook)piece; } } } } if (kingsideRook != null) { if (kingsideRook.getMoveCount() == 0) { if (this.getMoveCount() == 0) { if (targetPosition.Y == this.getPosition().Y&& targetPosition.occ != true) // checks that the y cooridnate of the target square is the same as the king's and also that the target square is not occupied { for (int i = this.getPosition().X - 1; i > kingsideRook.getPosition().X; i--) // loops through between the rook and the king, to check the squares in between to make sure they are not occupied. { if (gameBoard.getSquares()[i, this.getPosition().Y].occ == true) { return(false); } } if (targetPosition.X < this.getPosition().X) // ensures that the algorithm only returns true for the correct target square ( in between rook and king ) and not the other side of the king { return(true); } else { return(false); } } else // otherwise, if the square is occupied or the y coordinates are not the same { return(false); } } else // if the king has already moved then return false { return(false); } } else // if the rook has already moved before then return false { return(false); } } else // if the kingside rook variable is null then return false { return(false); } } else // if the target square is not 2 x-coordinates away then return false { return(false); } }
// this is where the moves of the game are made, and where the moves are added to history public void makeMove(Square targetposition, Board gameBoard, Piece movingPiece) { PieceSet[] pieceSets = gameBoard.getPieceSets(); PieceSet BlackPieces = pieceSets[0]; PieceSet WhitePieces = pieceSets[1]; //Move object created and populated Move aMove = new Move(); aMove.finalPosition = targetposition; aMove.initialPosition = movingPiece.getPosition(); aMove.PieceMoved = movingPiece; if (BoardAdmin.game1.getTurn() == BoardAdmin.game1.getPlayer1().getPlayerColour()) { aMove.PlayerMoved = BoardAdmin.game1.getPlayer1(); if (BoardAdmin.game1.getPlayer1().getPlayerColour() == Piece.Piececolour.WHITE) { foreach (Piece piece in gameBoard.getPieceSets()[0].getPieceSet()) { if (piece.getPosition() == targetposition) { aMove.pieceCaptured = piece; } } BlackPieces.getPieceSet().Remove(aMove.pieceCaptured); } if (BoardAdmin.game1.getPlayer1().getPlayerColour() == Piece.Piececolour.BLACK) { foreach (Piece piece in gameBoard.getPieceSets()[1].getPieceSet()) { if (piece.getPosition() == targetposition) { aMove.pieceCaptured = piece; } } WhitePieces.getPieceSet().Remove(aMove.pieceCaptured); } } else // otherwise it is player 2's turn so do exactly the same but for player 2 { aMove.PlayerMoved = BoardAdmin.game1.getPlayer2(); if (BoardAdmin.game1.getPlayer2().getPlayerColour() == Piece.Piececolour.WHITE) { foreach (Piece piece in gameBoard.getPieceSets()[0].getPieceSet()) { if (piece.getPosition() == targetposition) { aMove.pieceCaptured = piece; } } BlackPieces.getPieceSet().Remove(aMove.pieceCaptured); } if (BoardAdmin.game1.getPlayer2().getPlayerColour() == Piece.Piececolour.BLACK) { foreach (Piece piece in gameBoard.getPieceSets()[1].getPieceSet()) { if (piece.getPosition() == targetposition) { aMove.pieceCaptured = piece; } } WhitePieces.getPieceSet().Remove(aMove.pieceCaptured); } } if (movingPiece.getType() == Piece.pieceType.KING) // if the moving piece is a king, castling may occur { King movingKing = (King)movingPiece; if (movingKing.canCastle(targetposition, gameBoard) == true) // invokes the canCastle method of the king class to check whether castling can occur { BoardAdmin.isCastling = true; Rook movingRook = null; if (this.getPlayerColour() == Piece.Piececolour.WHITE) { foreach (Piece piece in WhitePieces.getPieceSet()) { if (piece.getType() == Piece.pieceType.ROOK && Math.Abs(piece.getPosition().X - movingKing.getPosition().X) == 3) { movingRook = (Rook)piece; } } } if (this.getPlayerColour() == Piece.Piececolour.BLACK) { foreach (Piece piece in BlackPieces.getPieceSet()) { if (piece.getType() == Piece.pieceType.ROOK && Math.Abs(piece.getPosition().X - movingKing.getPosition().X) == 3) { movingRook = (Rook)piece; } } } BoardAdmin.KingsideRook = movingRook; movingKing.PerformCastle(BoardAdmin.KingsideRook, movingKing, targetposition, gameBoard); // invokes the performCastle method in the king class to make the castling move. if (BoardAdmin.TempMoving == false) // if temp moving is true, then the move needs to be retracted so the boolean representing castling needs to remain true otherwise the kingside rook will not be moved back aswell as the king { BoardAdmin.isCastling = false; // so if temp moving is false, the castling can be made false aswell as the move is not temporary. } } } // adjusts properties of the piece moving and the squares involved movingPiece.getPosition().occ = false; movingPiece.setPosition(targetposition); movingPiece.getPosition().occ = true; movingPiece.IncrementMoveCount(1); if (movingPiece.getType() == Piece.pieceType.PAWN) // if the moving piece is a pawn, promototion may occur { if (movingPiece.getPosition().Y == 0 || movingPiece.getPosition().Y == 7) //if either the bottom or the top of the board is reached { if (BoardAdmin.TempMoving == false) // only promotes pawn if it is not a temporary move { movingPiece.promotePawn(); // invokes the promotePawn method to perform the move. } } } BoardAdmin.game1.addTomoveHistory(aMove); }