public void InvalidMove() { char[,] boardLayout = { {'C', 'N', 'B', 'Q', 'K', 'B', 'N', 'C'}, {'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P'}, {'e', 'e', 'e', 'e', 'e', 'e', 'e', 'e'}, {'e', 'e', 'e', 'e', 'e', 'e', 'e', 'e'}, {'e', 'e', 'e', 'e', 'e', 'e', 'e', 'e'}, {'c', 'e', 'e', 'e', 'e', 'e', 'e', 'e'}, {'e', 'p', 'p', 'p', 'p', 'p', 'p', 'p'}, {'e', 'n', 'b', 'q', 'k', 'b', 'n', 'c'} }; boardLayout = boardLayout.RotateArray(); Board board = BoardFactory.CreateBoard(boardLayout); BasicPlayer player1 = new BasicPlayer(board, Player.PlayerOne); board.AddPlayer(player1); BasicPlayer player2 = new BasicPlayer(board, Player.PlayerTwo); board.AddPlayer(player2); Vector2I castlePos = new Vector2I(0, 2); Assert.IsTrue(board.BoardPieces[castlePos.X, castlePos.Y].PieceType == PieceType.Castle); Vector2I castleDest = new Vector2I(2, 4); Assert.IsTrue(board.BoardPieces[castleDest.X, castleDest.Y].PieceType == PieceType.None); BoardPieceMove move = new BoardPieceMove(castlePos, castleDest); Assert.IsFalse(player1.ApplyMove(move)); Assert.IsTrue(board.BoardPieces[castlePos.X, castlePos.Y].PieceType == PieceType.Castle); Assert.IsTrue(board.BoardPieces[castleDest.X, castleDest.Y].PieceType == PieceType.None); }
public void PawnInvalidMovePieceTest() { Board board = BoardFactory.CreateBoard(); BasicPlayer player1 = new BasicPlayer(board, Player.PlayerOne); board.AddPlayer(player1); BasicPlayer player2 = new BasicPlayer(board, Player.PlayerTwo); board.AddPlayer(player2); Vector2I pawnPos = new Vector2I(3, 1); Assert.IsTrue(board.BoardPieces[pawnPos.X, pawnPos.Y].PieceType == PieceType.Pawn); Vector2I pawnDest = new Vector2I(3, 4); Assert.IsTrue(board.BoardPieces[pawnDest.X, pawnDest.Y].PieceType == PieceType.None); BoardPieceMove move = new BoardPieceMove(pawnPos, pawnDest); Assert.IsFalse(player1.ApplyMove(move)); Assert.IsTrue(board.BoardPieces[pawnPos.X, pawnPos.Y].PieceType == PieceType.Pawn); Assert.IsTrue(board.BoardPieces[pawnDest.X, pawnDest.Y].PieceType == PieceType.None); }
private static void GetKnightMoveOptions(Vector2I piecePosition, BoardPiece currentPiece, BoardPiece[,] boardBoardPieces, HashSet <BoardPieceMove> moves) { //Moves to the RIGHT. var move = new BoardPieceMove(piecePosition.X, piecePosition.Y, piecePosition.X + 2, piecePosition.Y + 1); CheckMoveValidityAndStoreMove(move, currentPiece.PieceOwner, boardBoardPieces, moves); move.To.Y = piecePosition.Y - 1; CheckMoveValidityAndStoreMove(move, currentPiece.PieceOwner, boardBoardPieces, moves); //Moves to the LEFT. move.To.X = piecePosition.X - 2; move.To.Y = piecePosition.Y + 1; CheckMoveValidityAndStoreMove(move, currentPiece.PieceOwner, boardBoardPieces, moves); move.To.Y = piecePosition.Y - 1; CheckMoveValidityAndStoreMove(move, currentPiece.PieceOwner, boardBoardPieces, moves); //Moves ABOVE. move.To.X = piecePosition.X + 1; move.To.Y = piecePosition.Y - 2; CheckMoveValidityAndStoreMove(move, currentPiece.PieceOwner, boardBoardPieces, moves); move.To.X = piecePosition.X - 1; CheckMoveValidityAndStoreMove(move, currentPiece.PieceOwner, boardBoardPieces, moves); //Moves BELOW. move.To.X = piecePosition.X + 1; move.To.Y = piecePosition.Y + 2; CheckMoveValidityAndStoreMove(move, currentPiece.PieceOwner, boardBoardPieces, moves); move.To.X = piecePosition.X - 1; CheckMoveValidityAndStoreMove(move, currentPiece.PieceOwner, boardBoardPieces, moves); }
private static void GetDiagonalMoveOptions(Vector2I piecePosition, BoardPiece currentPiece, BoardPiece[,] boardPieces, HashSet <BoardPieceMove> moves) { BoardPieceMove move; //ABOVE & LEFT for (int yPos = piecePosition.Y - 1, xPos = piecePosition.X - 1; yPos >= 0 && xPos >= 0; yPos--, xPos--) { //Keep checking moves until one is invalid. move = new BoardPieceMove(piecePosition.X, piecePosition.Y, xPos, yPos); if (CheckMoveValidityAndStoreMove(move, currentPiece.PieceOwner, boardPieces, moves) == false) { break; } } //ABOVE & RIGHT for (int yPos = piecePosition.Y - 1, xPos = piecePosition.X + 1; yPos >= 0 && xPos < Board.BOARD_DIMENSIONS; yPos--, xPos++) { //Keep checking moves until one is invalid. move = new BoardPieceMove(piecePosition.X, piecePosition.Y, xPos, yPos); if (CheckMoveValidityAndStoreMove(move, currentPiece.PieceOwner, boardPieces, moves) == false) { break; } } //BELOW & LEFT for (int yPos = piecePosition.Y + 1, xPos = piecePosition.X - 1; yPos < Board.BOARD_DIMENSIONS && xPos >= 0; yPos++, xPos--) { //Keep checking moves until one is invalid. move = new BoardPieceMove(piecePosition.X, piecePosition.Y, xPos, yPos); if (CheckMoveValidityAndStoreMove(move, currentPiece.PieceOwner, boardPieces, moves) == false) { break; } } //BELOW & RIGHT for (int yPos = piecePosition.Y + 1, xPos = piecePosition.X + 1; yPos < Board.BOARD_DIMENSIONS && xPos < Board.BOARD_DIMENSIONS; yPos++, xPos++) { //Keep checking moves until one is invalid. move = new BoardPieceMove(piecePosition.X, piecePosition.Y, xPos, yPos); if (CheckMoveValidityAndStoreMove(move, currentPiece.PieceOwner, boardPieces, moves) == false) { break; } } }
public void InvalidCastlingTest() { char[,] boardLayout = { { 'C', 'N', 'B', 'Q', 'K', 'B', 'N', 'C' }, { 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P' }, { 'e', 'e', 'e', 'e', 'e', 'e', 'e', 'e' }, { 'e', 'e', 'e', 'e', 'e', 'e', 'e', 'e' }, { 'e', 'e', 'e', 'e', 'e', 'p', 'p', 'e' }, { 'e', 'e', 'e', 'e', 'e', 'n', 'e', 'b' }, { 'p', 'p', 'p', 'p', 'p', 'e', 'e', 'c' }, { 'c', 'n', 'b', 'q', 'k', 'e', 'e', 'e' } }; boardLayout = boardLayout.RotateArray(); Board board = BoardFactory.CreateBoard(boardLayout); BasicPlayer player1 = new BasicPlayer(board, Player.PlayerOne); board.AddPlayer(player1); BasicPlayer player2 = new BasicPlayer(board, Player.PlayerTwo); board.AddPlayer(player2); // Castle moves, can no longer perform castling Vector2I castlePos = new Vector2I(7, 1); Assert.IsTrue(board.BoardPieces[castlePos.X, castlePos.Y].PieceType == PieceType.Castle); Vector2I castleDest = new Vector2I(7, 0); Assert.IsTrue(board.BoardPieces[castleDest.X, castleDest.Y].PieceType == PieceType.None); BoardPieceMove move = new BoardPieceMove(castlePos, castleDest); player1.ApplyMove(move); Assert.IsTrue(board.BoardPieces[castlePos.X, castlePos.Y].PieceType == PieceType.None); Assert.IsTrue(board.BoardPieces[castleDest.X, castleDest.Y].PieceType == PieceType.Castle); board.PlayerTurn = Player.PlayerOne; Vector2I kingPos = new Vector2I(4, 0); Assert.IsTrue(board.BoardPieces[kingPos.X, kingPos.Y].PieceType == PieceType.King); Vector2I kingDest = new Vector2I(6, 0); Assert.IsTrue(board.BoardPieces[kingDest.X, kingDest.Y].PieceType == PieceType.None); move = new BoardPieceMove(kingPos, kingDest); Assert.IsFalse(player1.ApplyMove(move)); Assert.IsTrue(board.BoardPieces[kingPos.X, kingPos.Y].PieceType == PieceType.King); Assert.IsTrue(board.BoardPieces[kingDest.X, kingDest.Y].PieceType == PieceType.None); Assert.IsTrue(board.BoardPieces[7, 0].PieceType == PieceType.Castle); }
/// <summary> /// Lets the board know that this player has made a move. /// </summary> /// <param name="boardPieceMove"></param> /// <returns></returns> protected bool MovePiece(BoardPieceMove boardPieceMove) { // Make sure it is our turn if (Board.PlayerTurn != Player) { return(false); } // Apply move to the core data structure return(OnMoveMade != null && OnMoveMade.Invoke(boardPieceMove)); }
private BoardChange KingMove(BoardPieceMove move) { BoardChange change; //Are we moving 2 spaces??? This indicates CASTLING. if (move.To.X - move.From.X == 2) { //Moving 2 spaces to the right - Move the ROOK on the right into its new position. BoardPieces[move.From.X + 3, move.From.Y].HasMoved = true; BoardPieces[move.From.X + 1, move.From.Y] = BoardPieces[move.From.X + 3, move.From.Y]; BoardPieces[move.From.X + 3, move.From.Y] = new BoardPiece(); // Castling change = (new CastlingChange { Type = BoardChangeType.Castling, CastleMove = new BoardPieceMove(new Vector2I(move.From.X + 3, move.From.Y), new Vector2I(move.From.X + 1, move.From.Y)), KingMove = move, Player = PlayerTurn }); // Move the king StandardMoveBoardChange(BoardPieces, move); } else if (move.To.X - move.From.X == -2) { //Moving 2 spaces to the left - Move the ROOK on the left into its new position. //Move the piece into new position. BoardPieces[move.From.X - 4, move.From.Y].HasMoved = true; BoardPieces[move.From.X - 1, move.From.Y] = BoardPieces[move.From.X - 4, move.From.Y]; BoardPieces[move.From.X - 4, move.From.Y] = new BoardPiece(); // Castling change = (new CastlingChange { Type = BoardChangeType.Castling, CastleMove = new BoardPieceMove(new Vector2I(move.From.X - 4, move.From.Y), new Vector2I(move.From.X - 1, move.From.Y)), KingMove = move, Player = PlayerTurn }); // Move the king StandardMoveBoardChange(BoardPieces, move); } else { // No castling, standard move change = StandardMove(move); } return(change); }
public void CheckMateRegisteredTest() { char[,] boardLayout = { { 'e', 'e', 'e', 'e', 'K', 'e', 'e', 'e' }, { 'e', 'e', 'e', 'e', 'e', 'e', 'e', 'c' }, { 'e', 'e', 'e', 'e', 'e', 'e', 'e', 'e' }, { 'e', 'e', 'e', 'e', 'e', 'e', 'e', 'e' }, { 'e', 'e', 'e', 'e', 'e', 'e', 'e', 'e' }, { 'e', 'e', 'e', 'e', 'e', 'e', 'e', 'e' }, { 'e', 'e', 'e', 'e', 'e', 'e', 'e', 'e' }, { 'e', 'e', 'e', 'e', 'k', 'e', 'c', 'e' } }; boardLayout = boardLayout.RotateArray(); Board board = BoardFactory.CreateBoard(boardLayout); BasicPlayer player1 = new BasicPlayer(board, Player.PlayerOne); board.AddPlayer(player1); BasicPlayer player2 = new BasicPlayer(board, Player.PlayerTwo); board.AddPlayer(player2); bool checkMate = false; Player winningPlayer = Player.None; board.OnGameStateChanged += delegate(GameState state) { if (state != GameState.WonByCheckmate) { return; } checkMate = true; winningPlayer = board.PlayerTurn; }; Vector2I castlePos = new Vector2I(6, 0); Assert.IsTrue(board.BoardPieces[castlePos.X, castlePos.Y].PieceType == PieceType.Castle); Vector2I castleDest = new Vector2I(6, 7); Assert.IsTrue(board.BoardPieces[castleDest.X, castleDest.Y].PieceType == PieceType.None); BoardPieceMove move = new BoardPieceMove(castlePos, castleDest); player1.ApplyMove(move); Assert.IsTrue(checkMate); Assert.AreEqual(GameState.WonByCheckmate, board.GameState); Assert.AreEqual(winningPlayer, Player.PlayerOne); }
private bool ApplyMove(BoardPieceMove move) { // Check the moving piece belongs to the correct player and is a valid move if (BoardPieces[move.From.X, move.From.Y].PieceOwner != PlayerTurn || !ValidMovesCalc.IsMoveValid(move, PlayerTurn, this) || (GameState != GameState.Playing)) { // Move is invalid return(false); } List <BoardChange> boardChanges = ApplyMoveToBoard(move); CheckPawnPromotion(move, boardChanges); // Store changes for (int i = 0; i < boardChanges.Count; i++) { GameChanges.Push(boardChanges[i]); } OnBoardChanged?.Invoke(boardChanges); if (ValidMovesCalc.IsPlayerInCheck(BoardPieces, BoardHelpers.GetOpponentPlayer(PlayerTurn))) { if (ValidMovesCalc.PlayerCanMove(this, BoardHelpers.GetOpponentPlayer(PlayerTurn))) { // CHECKMATE ChangeGameState(GameState.WonByCheckmate); return(true); } // IN CHECK OnPlayerInCheck?.Invoke(BoardHelpers.GetOpponentPlayer(PlayerTurn)); } else { if (ValidMovesCalc.PlayerCanMove(this, BoardHelpers.GetOpponentPlayer(PlayerTurn))) { // STALEMATE ChangeGameState(GameState.WonByStaleMate); return(true); } } ClearEnPassant(); SwapPlayerTurns(); return(true); }
private static void GetUpDownMoveOptions(Vector2I piecePosition, BoardPiece currentPiece, BoardPiece[,] boardPieces, HashSet <BoardPieceMove> moves) { BoardPieceMove move; //Vertical DOWN the board. for (int yPos = piecePosition.Y + 1; yPos < Board.BOARD_DIMENSIONS; yPos++) { //Keep checking moves until one is invalid. move = new BoardPieceMove(piecePosition.X, piecePosition.Y, piecePosition.X, yPos); if (CheckMoveValidityAndStoreMove(move, currentPiece.PieceOwner, boardPieces, moves) == false) { break; } } //Vertical UP the board. for (int yPos = piecePosition.Y - 1; yPos >= 0; yPos--) { //Keep checking moves until one is invalid. move = new BoardPieceMove(piecePosition.X, piecePosition.Y, piecePosition.X, yPos); if (CheckMoveValidityAndStoreMove(move, currentPiece.PieceOwner, boardPieces, moves) == false) { break; } } //Horizontal LEFT of the board. for (int xPos = piecePosition.X - 1; xPos >= 0; xPos--) { //Keep checking moves until one is invalid. move = new BoardPieceMove(piecePosition.X, piecePosition.Y, xPos, piecePosition.Y); if (CheckMoveValidityAndStoreMove(move, currentPiece.PieceOwner, boardPieces, moves) == false) { break; } } //Horizontal RIGHT of the board. for (int xPos = piecePosition.X + 1; xPos < Board.BOARD_DIMENSIONS; xPos++) { //Keep checking moves until one is invalid. move = new BoardPieceMove(piecePosition.X, piecePosition.Y, xPos, piecePosition.Y); if (CheckMoveValidityAndStoreMove(move, currentPiece.PieceOwner, boardPieces, moves) == false) { break; } } }
public static bool IsMoveValid(BoardPieceMove moveToCheck, Player player, Board board) { var moves = new HashSet <BoardPieceMove>(); GetValidMovesForPlayer(board, player, moves); if (!moves.Contains(moveToCheck)) { return(false); } BoardPiece[,] tempBoard = BoardHelpers.DuplicateBoard(board.BoardPieces); if (moveToCheck.To.X >= 0 && moveToCheck.To.X < Board.BOARD_DIMENSIONS && moveToCheck.To.Y >= 0 && moveToCheck.To.Y < Board.BOARD_DIMENSIONS) { // We check with colour passed in to enable the same functions to construct attacked spaces // as well as constructing the positions we can move to. if (tempBoard[moveToCheck.To.X, moveToCheck.To.Y].PieceType == PieceType.None) { // Will this leave us in check? tempBoard[moveToCheck.To.X, moveToCheck.To.Y] = tempBoard[moveToCheck.From.X, moveToCheck.From.Y]; tempBoard[moveToCheck.From.X, moveToCheck.From.Y] = new BoardPiece(); if (!IsPlayerInCheck(tempBoard, player)) { return(true); } } else { // A piece so no more moves after this, but can we take it? if (tempBoard[moveToCheck.To.X, moveToCheck.To.Y].PieceOwner != player) { // Will this leave us in check? tempBoard[moveToCheck.To.X, moveToCheck.To.Y] = tempBoard[moveToCheck.From.X, moveToCheck.From.Y]; tempBoard[moveToCheck.From.X, moveToCheck.From.Y] = new BoardPiece(); if (!IsPlayerInCheck(tempBoard, player)) { return(true); } } } } return(false); }
public void CheckRegisteredTest() { char[,] boardLayout = { { 'C', 'N', 'B', 'Q', 'K', 'B', 'N', 'C' }, { 'P', 'P', 'P', 'P', 'P', 'e', 'P', 'P' }, { 'e', 'e', 'e', 'e', 'e', 'e', 'e', 'e' }, { 'e', 'e', 'e', 'e', 'e', 'P', 'e', 'e' }, { 'e', 'e', 'e', 'e', 'e', 'e', 'e', 'e' }, { 'e', 'e', 'e', 'b', 'p', 'e', 'e', 'e' }, { 'p', 'p', 'p', 'p', 'e', 'p', 'p', 'p' }, { 'c', 'n', 'b', 'q', 'k', 'e', 'n', 'c' } }; boardLayout = boardLayout.RotateArray(); Board board = BoardFactory.CreateBoard(boardLayout); BasicPlayer player1 = new BasicPlayer(board, Player.PlayerOne); board.AddPlayer(player1); BasicPlayer player2 = new BasicPlayer(board, Player.PlayerTwo); board.AddPlayer(player2); bool inCheck = false; Player playerInCheck = Player.None; board.OnPlayerInCheck += delegate(Player player) { inCheck = true; playerInCheck = player; }; Vector2I queenPos = new Vector2I(3, 0); Assert.IsTrue(board.BoardPieces[queenPos.X, queenPos.Y].PieceType == PieceType.Queen); Vector2I queenDest = new Vector2I(7, 4); Assert.IsTrue(board.BoardPieces[queenDest.X, queenDest.Y].PieceType == PieceType.None); BoardPieceMove move = new BoardPieceMove(queenPos, queenDest); player1.ApplyMove(move); Assert.IsTrue(inCheck); Assert.AreEqual(playerInCheck, Player.PlayerTwo); }
private void CheckPawnPromotion(BoardPieceMove move, List <BoardChange> changes) { //Check if we need to promote a pawn. if (BoardPieces[move.To.X, move.To.Y].PieceType == PieceType.Pawn && (move.To.Y == 0 || move.To.Y == 7)) { // Time to promote. changes.Add(new PromotePawnChange { Type = BoardChangeType.PromotePawn, NewPieceType = PieceType.Queen, Player = PlayerTurn, PawnPosition = move.To }); BoardPieces[move.To.X, move.To.Y].PieceType = PieceType.Queen; } }
/// <summary> /// Check the current move is valid and if it is, add it to the hashset of moves /// </summary> /// <param name="moveToCheck">The move to check the validity of</param> /// <param name="player">The player that is performing the move</param> /// <param name="board">The board to check the move on</param> /// <param name="moves">The hashset containing all the moves</param> /// <returns>True if the move is valid</returns> private static bool CheckMoveValidityAndStoreMove(BoardPieceMove moveToCheck, Player player, BoardPiece[,] board, HashSet <BoardPieceMove> moves) { BoardPiece[,] tempBoard = BoardHelpers.DuplicateBoard(board); if (moveToCheck.To.X >= 0 && moveToCheck.To.X < Board.BOARD_DIMENSIONS && moveToCheck.To.Y >= 0 && moveToCheck.To.Y < Board.BOARD_DIMENSIONS) { // We check with colour passed in to enable the same functions to construct attacked spaces // as well as constructing the positions we can move to. if (tempBoard[moveToCheck.To.X, moveToCheck.To.Y].PieceType == PieceType.None) { // Will this leave us in check? tempBoard[moveToCheck.To.X, moveToCheck.To.Y] = tempBoard[moveToCheck.From.X, moveToCheck.From.Y]; tempBoard[moveToCheck.From.X, moveToCheck.From.Y] = new BoardPiece(); if (!IsPlayerInCheck(tempBoard, player)) { moves.Add(moveToCheck); } } else { // A piece so no more moves after this, but can we take it? if (tempBoard[moveToCheck.To.X, moveToCheck.To.Y].PieceOwner != player) { // Will this leave us in check? tempBoard[moveToCheck.To.X, moveToCheck.To.Y] = tempBoard[moveToCheck.From.X, moveToCheck.From.Y]; tempBoard[moveToCheck.From.X, moveToCheck.From.Y] = new BoardPiece(); if (!IsPlayerInCheck(tempBoard, player)) { moves.Add(moveToCheck); } } // Hit a piece, so no more moves in this direction. return(false); } return(true); } return(false); }
private BoardChange EnPassantMove(BoardPieceMove move) { int pawnDirectionOpposite = BoardHelpers.GetPlayerDirection(BoardHelpers.GetOpponentPlayer(PlayerTurn)); BoardChange change = (new EnPassantTakePieceChange { Type = BoardChangeType.EnPassantTakePiece, Move = move, Player = PlayerTurn, TakingPieceType = BoardPieces[move.From.X, move.From.Y].PieceType, TakenPawnPosition = new Vector2I(move.To.X, move.To.Y + pawnDirectionOpposite) }); // Move piece StandardMoveBoardChange(BoardPieces, move); // Remove pawn BoardPieces[move.To.X, move.To.Y + pawnDirectionOpposite] = new BoardPiece(); return(change); }
public void PieceTakenEnPassantTest() { char[,] boardLayout = { { 'C', 'N', 'B', 'Q', 'K', 'B', 'N', 'C' }, { 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P' }, { 'e', 'e', 'e', 'e', 'e', 'e', 'e', 'e' }, { 'e', 'e', 'e', 'p', 'e', 'e', 'e', 'e' }, // Pawn take pawn { 'e', 'e', 'e', 'e', 'e', 'e', 'e', 'e' }, { 'e', 'e', 'e', 'e', 'e', 'e', 'e', 'e' }, { 'p', 'p', 'p', 'e', 'p', 'p', 'p', 'p' }, { 'c', 'n', 'b', 'q', 'k', 'b', 'n', 'c' } }; boardLayout = boardLayout.RotateArray(); Board board = BoardFactory.CreateBoard(boardLayout); BasicPlayer player1 = new BasicPlayer(board, Player.PlayerOne); board.AddPlayer(player1); BasicPlayer player2 = new BasicPlayer(board, Player.PlayerTwo); board.AddPlayer(player2); board.PlayerTurn = Player.PlayerTwo; var pawnPos = new Vector2I(4, 6); // Move enemy pawn var pawnDest = new Vector2I(4, 4); var move = new BoardPieceMove(pawnPos, pawnDest); player2.ApplyMove(move); pawnPos = new Vector2I(3, 4); // En passant take pawnDest = new Vector2I(4, 5); move = new BoardPieceMove(pawnPos, pawnDest); player1.ApplyMove(move); Assert.IsTrue(board.BoardPieces[pawnPos.X, pawnPos.Y].PieceType == PieceType.None); Assert.IsTrue(board.BoardPieces[pawnDest.X, pawnDest.Y].PieceType == PieceType.Pawn && board.BoardPieces[pawnDest.X, pawnDest.Y].PieceOwner == Player.PlayerOne); Assert.IsTrue(board.BoardPieces[4, 4].PieceType == PieceType.None); }
public void CastlingTest() { char[,] boardLayout = { { 'C', 'N', 'B', 'Q', 'K', 'B', 'N', 'C' }, { 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P' }, { 'e', 'e', 'e', 'e', 'e', 'e', 'e', 'e' }, { 'e', 'e', 'e', 'e', 'e', 'e', 'e', 'e' }, { 'e', 'e', 'e', 'e', 'e', 'p', 'p', 'e' }, { 'e', 'e', 'e', 'e', 'e', 'n', 'e', 'b' }, { 'p', 'p', 'p', 'p', 'p', 'e', 'e', 'p' }, { 'c', 'n', 'b', 'q', 'k', 'e', 'e', 'c' } }; boardLayout = boardLayout.RotateArray(); Board board = BoardFactory.CreateBoard(boardLayout); BasicPlayer player1 = new BasicPlayer(board, Player.PlayerOne); board.AddPlayer(player1); BasicPlayer player2 = new BasicPlayer(board, Player.PlayerTwo); board.AddPlayer(player2); // Move right twice Vector2I kingPos = new Vector2I(4, 0); Assert.IsTrue(board.BoardPieces[kingPos.X, kingPos.Y].PieceType == PieceType.King); Vector2I kingDest = new Vector2I(6, 0); Assert.IsTrue(board.BoardPieces[kingDest.X, kingDest.Y].PieceType == PieceType.None); BoardPieceMove move = new BoardPieceMove(kingPos, kingDest); player1.ApplyMove(move); Assert.IsTrue(board.BoardPieces[kingPos.X, kingPos.Y].PieceType == PieceType.None); Assert.IsTrue(board.BoardPieces[kingDest.X, kingDest.Y].PieceType == PieceType.King); Assert.IsTrue(board.BoardPieces[kingDest.X - 1, kingDest.Y].PieceType == PieceType.Castle); }
public void ValidMovementLeftDiagonalBackwards() { char[,] boardLayout = { { 'C', 'N', 'B', 'Q', 'K', 'B', 'N', 'C' }, { 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P' }, { 'e', 'e', 'e', 'e', 'e', 'e', 'e', 'e' }, { 'e', 'e', 'e', 'e', 'e', 'e', 'e', 'e' }, { 'e', 'e', 'e', 'e', 'e', 'e', 'e', 'e' }, { 'e', 'e', 'e', 'b', 'p', 'e', 'e', 'e' }, { 'p', 'p', 'p', 'p', 'e', 'p', 'p', 'p' }, { 'c', 'n', 'b', 'q', 'k', 'e', 'n', 'c' } // Bishop movement }; boardLayout = boardLayout.RotateArray(); Board board = BoardFactory.CreateBoard(boardLayout); BasicPlayer player1 = new BasicPlayer(board, Player.PlayerOne); board.AddPlayer(player1); BasicPlayer player2 = new BasicPlayer(board, Player.PlayerTwo); board.AddPlayer(player2); Vector2I bishopPos = new Vector2I(3, 2); Assert.IsTrue(board.BoardPieces[bishopPos.X, bishopPos.Y].PieceType == PieceType.Bishop); Vector2I bishopDest = new Vector2I(5, 0); Assert.IsTrue(board.BoardPieces[bishopDest.X, bishopDest.Y].PieceType == PieceType.None); BoardPieceMove move = new BoardPieceMove(bishopPos, bishopDest); player1.ApplyMove(move); Assert.IsTrue(board.BoardPieces[bishopPos.X, bishopPos.Y].PieceType == PieceType.None); Assert.IsTrue(board.BoardPieces[bishopDest.X, bishopDest.Y].PieceType == PieceType.Bishop); }
public void PawnInvalidMovePieceTest3() { char[,] boardLayout = { { 'C', 'N', 'B', 'Q', 'K', 'B', 'N', 'C' }, { 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P' }, { 'e', 'e', 'e', 'e', 'e', 'e', 'e', 'e' }, { 'e', 'e', 'e', 'p', 'e', 'e', 'e', 'e' }, { 'e', 'e', 'e', 'e', 'e', 'e', 'e', 'e' }, { 'e', 'e', 'e', 'e', 'e', 'e', 'e', 'e' }, // Pawn has already moved { 'p', 'p', 'p', 'e', 'p', 'p', 'p', 'p' }, { 'c', 'n', 'b', 'q', 'k', 'b', 'n', 'c' } }; boardLayout = boardLayout.RotateArray(); Board board = BoardFactory.CreateBoard(boardLayout); BasicPlayer player1 = new BasicPlayer(board, Player.PlayerOne); board.AddPlayer(player1); BasicPlayer player2 = new BasicPlayer(board, Player.PlayerTwo); board.AddPlayer(player2); var pawnPos = new Vector2I(3, 4); Assert.IsTrue(board.BoardPieces[pawnPos.X, pawnPos.Y].PieceType == PieceType.Pawn); var pawnDest = new Vector2I(3, 3); Assert.IsTrue(board.BoardPieces[pawnDest.X, pawnDest.Y].PieceType == PieceType.None); var move = new BoardPieceMove(pawnPos, pawnDest); Assert.IsFalse(player1.ApplyMove(move)); Assert.IsTrue(board.BoardPieces[pawnPos.X, pawnPos.Y].PieceType == PieceType.Pawn); Assert.IsTrue(board.BoardPieces[pawnDest.X, pawnDest.Y].PieceType == PieceType.None); }
public void ValidMoveVertical() { char[,] boardLayout = { { 'C', 'N', 'B', 'Q', 'K', 'B', 'N', 'C' }, { 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P' }, { 'e', 'e', 'e', 'e', 'e', 'e', 'e', 'e' }, { 'e', 'e', 'e', 'e', 'e', 'e', 'e', 'e' }, { 'e', 'e', 'e', 'e', 'e', 'e', 'e', 'e' }, { 'e', 'e', 'e', 'e', 'e', 'e', 'e', 'e' }, { 'p', 'p', 'p', 'e', 'p', 'p', 'p', 'p' }, { 'c', 'n', 'b', 'q', 'k', 'b', 'n', 'c' } }; boardLayout = boardLayout.RotateArray(); Board board = BoardFactory.CreateBoard(boardLayout); BasicPlayer player1 = new BasicPlayer(board, Player.PlayerOne); board.AddPlayer(player1); BasicPlayer player2 = new BasicPlayer(board, Player.PlayerTwo); board.AddPlayer(player2); Vector2I queenPos = new Vector2I(3, 0); Assert.IsTrue(board.BoardPieces[queenPos.X, queenPos.Y].PieceType == PieceType.Queen); Vector2I queenDest = new Vector2I(3, 5); Assert.IsTrue(board.BoardPieces[queenDest.X, queenDest.Y].PieceType == PieceType.None); BoardPieceMove move = new BoardPieceMove(queenPos, queenDest); player1.ApplyMove(move); Assert.IsTrue(board.BoardPieces[queenPos.X, queenPos.Y].PieceType == PieceType.None); Assert.IsTrue(board.BoardPieces[queenDest.X, queenDest.Y].PieceType == PieceType.Queen); }
private BoardChange StandardMove(BoardPieceMove move) { BoardChange change; //Move the piece into new position. BoardChangeType changeType = BoardPieces[move.To.X, move.To.Y].PieceType != PieceType.None ? BoardChangeType.TakePiece : BoardChangeType.MovePiece; if (changeType == BoardChangeType.MovePiece) { // Piece movement change = new MovePieceChange { Type = changeType, Move = move, Player = PlayerTurn, MovedPieceType = BoardPieces[move.From.X, move.From.Y].PieceType }; } else { // Piece take change = new TakePieceChange { Type = changeType, Move = move, Player = PlayerTurn, TakingPieceType = BoardPieces[move.From.X, move.From.Y].PieceType, TakenPieceType = BoardPieces[move.To.X, move.To.Y].PieceType }; } StandardMoveBoardChange(BoardPieces, move); return(change); }
private List <BoardChange> ApplyMoveToBoard(BoardPieceMove move) { List <BoardChange> boardChanges = new List <BoardChange>(); //If this was an en'passant move the taken piece will not be in the square we moved to. if (BoardPieces[move.From.X, move.From.Y].PieceType == PieceType.Pawn) { //If the pawn is on its start position and it double jumps, then en'passant may be available for opponent. if ((move.From.Y == 1 && move.To.Y == 3) || (move.From.Y == 6 && move.To.Y == 4)) { BoardPieces[move.From.X, move.From.Y].CanEnPassant = true; } } //En'Passant removal of enemy pawn. //If our pawn moved into an empty position to the left or right, then must be En'Passant. if (BoardPieces[move.From.X, move.From.Y].PieceType == PieceType.Pawn && BoardPieces[move.To.X, move.To.Y].PieceType == PieceType.None && ((move.From.X < move.To.X) || (move.From.X > move.To.X))) { boardChanges.Add(EnPassantMove(move)); } // Special king moves including castling else if (BoardPieces[move.From.X, move.From.Y].PieceType == PieceType.King) { boardChanges.Add(KingMove(move)); } // Standard move or take else { boardChanges.Add(StandardMove(move)); } return(boardChanges); }
public void KingDiagonalMovementTest() { char[,] boardLayout = { { 'C', 'N', 'B', 'Q', 'K', 'B', 'N', 'C' }, { 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P' }, { 'e', 'e', 'e', 'e', 'e', 'e', 'e', 'e' }, { 'e', 'e', 'e', 'e', 'e', 'e', 'e', 'e' }, { 'e', 'e', 'e', 'e', 'k', 'e', 'e', 'e' }, { 'e', 'e', 'e', 'e', 'e', 'e', 'e', 'e' }, { 'p', 'p', 'p', 'p', 'e', 'p', 'p', 'p' }, { 'c', 'n', 'b', 'q', 'e', 'b', 'n', 'c' } }; boardLayout = boardLayout.RotateArray(); Board board = BoardFactory.CreateBoard(boardLayout); BasicPlayer player1 = new BasicPlayer(board, Player.PlayerOne); board.AddPlayer(player1); BasicPlayer player2 = new BasicPlayer(board, Player.PlayerTwo); board.AddPlayer(player2); // Move up-right Vector2I kingPos = new Vector2I(4, 3); Assert.IsTrue(board.BoardPieces[kingPos.X, kingPos.Y].PieceType == PieceType.King); Vector2I kingDest = new Vector2I(5, 4); Assert.IsTrue(board.BoardPieces[kingDest.X, kingDest.Y].PieceType == PieceType.None); BoardPieceMove move = new BoardPieceMove(kingPos, kingDest); player1.ApplyMove(move); Assert.IsTrue(board.BoardPieces[kingPos.X, kingPos.Y].PieceType == PieceType.None); Assert.IsTrue(board.BoardPieces[kingDest.X, kingDest.Y].PieceType == PieceType.King); // Move down-right board.PlayerTurn = Player.PlayerOne; kingPos = kingDest; Assert.IsTrue(board.BoardPieces[kingPos.X, kingPos.Y].PieceType == PieceType.King); kingDest = new Vector2I(6, 3); Assert.IsTrue(board.BoardPieces[kingDest.X, kingDest.Y].PieceType == PieceType.None); move = new BoardPieceMove(kingPos, kingDest); player1.ApplyMove(move); Assert.IsTrue(board.BoardPieces[kingPos.X, kingPos.Y].PieceType == PieceType.None); Assert.IsTrue(board.BoardPieces[kingDest.X, kingDest.Y].PieceType == PieceType.King); // Move down-left board.PlayerTurn = Player.PlayerOne; kingPos = kingDest; Assert.IsTrue(board.BoardPieces[kingPos.X, kingPos.Y].PieceType == PieceType.King); kingDest = new Vector2I(5, 2); Assert.IsTrue(board.BoardPieces[kingDest.X, kingDest.Y].PieceType == PieceType.None); move = new BoardPieceMove(kingPos, kingDest); player1.ApplyMove(move); Assert.IsTrue(board.BoardPieces[kingPos.X, kingPos.Y].PieceType == PieceType.None); Assert.IsTrue(board.BoardPieces[kingDest.X, kingDest.Y].PieceType == PieceType.King); // Move up-left board.PlayerTurn = Player.PlayerOne; kingPos = kingDest; Assert.IsTrue(board.BoardPieces[kingPos.X, kingPos.Y].PieceType == PieceType.King); kingDest = new Vector2I(4, 3); Assert.IsTrue(board.BoardPieces[kingDest.X, kingDest.Y].PieceType == PieceType.None); move = new BoardPieceMove(kingPos, kingDest); player1.ApplyMove(move); Assert.IsTrue(board.BoardPieces[kingPos.X, kingPos.Y].PieceType == PieceType.None); Assert.IsTrue(board.BoardPieces[kingDest.X, kingDest.Y].PieceType == PieceType.King); }
private static void StandardMoveBoardChange(BoardPiece[,] board, BoardPieceMove move) { board[move.From.X, move.From.Y].HasMoved = true; board[move.To.X, move.To.Y] = board[move.From.X, move.From.Y]; board[move.From.X, move.From.Y] = new BoardPiece(); }
public BoardPieceMoveScore(BoardPieceMove move, float score) { Move = move; Score = score; }
/// <summary> /// Called when a player makes a move and returns if the move was valid or not. /// </summary> /// <param name="move"></param> /// <returns></returns> private bool PlayerOnOnMoveMade(BoardPieceMove move) { return(ApplyMove(move)); }
public static string ConvertMoveIntoStringRep(BoardPieceMove move) { return(ConvertPositionIntoStringRep(move.From) + ConvertPositionIntoStringRep(move.To)); }
private static void GetKingMoveOptions(Vector2I piecePosition, BoardPiece kingPiece, Board board, HashSet <BoardPieceMove> moves) { BoardPieceMove move; //Start at position top left of king and move across and down. for (int yPos = piecePosition.Y - 1; yPos <= piecePosition.Y + 1; yPos++) { for (int xPos = piecePosition.X - 1; xPos <= piecePosition.X + 1; xPos++) { if (yPos >= 0 && yPos < Board.BOARD_DIMENSIONS && xPos >= 0 && xPos < Board.BOARD_DIMENSIONS) { //Check if move is valid and store it. We dont care about the return value as we are only // checking one move in each direction. move = new BoardPieceMove(piecePosition.X, piecePosition.Y, xPos, yPos); CheckMoveValidityAndStoreMove(move, kingPiece.PieceOwner, board.BoardPieces, moves); } } } // Fixes the recursive issue. Only check moves and fetch opponent moves for the current player turn on the board if (board.PlayerTurn == kingPiece.PieceOwner) { Player opponent = kingPiece.PieceOwner == Player.PlayerOne ? Player.PlayerTwo : Player.PlayerOne; //Compile all the moves available to our opponent. Duplicate the board BUT keep the player turn the same. var tempBoard = BoardHelpers.DuplicateBoard(board); HashSet <BoardPieceMove> allOpponentMoves = new HashSet <BoardPieceMove>(); GetValidMovesForPlayer(tempBoard, opponent, allOpponentMoves); //Can CASTLE if not in CHECK. if (!IsPlayerInCheck(tempBoard.BoardPieces, kingPiece.PieceOwner)) { //CASTLE to the right. BoardPiece king = tempBoard.BoardPieces[piecePosition.X, piecePosition.Y]; if (!king.HasMoved) { BoardPiece rightRook = tempBoard.BoardPieces[piecePosition.X + 3, piecePosition.Y]; if (rightRook.PieceType == PieceType.Castle && !rightRook.HasMoved) { if (tempBoard.BoardPieces[piecePosition.X + 1, piecePosition.Y].PieceType == PieceType.None && tempBoard.BoardPieces[piecePosition.X + 2, piecePosition.Y].PieceType == PieceType.None) { //Cannot CASTLE through a CHECK position. bool canCastle = true; foreach (var oppMove in allOpponentMoves) { if (oppMove.To.X == piecePosition.X + 2 && oppMove.To.Y == piecePosition.Y || oppMove.To.X == piecePosition.X + 1 && oppMove.To.Y == piecePosition.Y) { canCastle = false; } } //Check if the final position is valid. if (canCastle) { move = new BoardPieceMove(piecePosition.X, piecePosition.Y, piecePosition.X + 2, piecePosition.Y); CheckMoveValidityAndStoreMove(move, kingPiece.PieceOwner, tempBoard.BoardPieces, moves); } } } //CASTLE to the left. tempBoard = BoardHelpers.DuplicateBoard(board); BoardPiece leftRook = tempBoard.BoardPieces[piecePosition.X - 4, piecePosition.Y]; if (leftRook.PieceType == PieceType.Castle && !leftRook.HasMoved) { if (tempBoard.BoardPieces[piecePosition.X - 1, piecePosition.Y].PieceType == PieceType.None && tempBoard.BoardPieces[piecePosition.X - 2, piecePosition.Y].PieceType == PieceType.None && tempBoard.BoardPieces[piecePosition.X - 3, piecePosition.Y].PieceType == PieceType.None) { //Cannot CASTLE through a CHECK position. bool canCastle = true; foreach (var oppMove in allOpponentMoves) { if (oppMove.To.X == piecePosition.X - 1 && oppMove.To.Y == piecePosition.Y || oppMove.To.X == piecePosition.X - 2 && oppMove.To.Y == piecePosition.Y || oppMove.To.X == piecePosition.X - 3 && oppMove.To.Y == piecePosition.Y) { canCastle = false; } } //Check if the final position is valid. if (canCastle) { move = new BoardPieceMove(piecePosition.X, piecePosition.Y, piecePosition.X - 2, piecePosition.Y); CheckMoveValidityAndStoreMove(move, kingPiece.PieceOwner, tempBoard.BoardPieces, moves); } } } } } } }
public bool ApplyMove(BoardPieceMove move) { return(MovePiece(move)); }
public static void Main(string[] args) { // Create the board var board = BoardFactory.CreateBoard(); BasicPlayer player1 = new BasicPlayer(board, Player.PlayerOne); board.AddPlayer(player1); BasicPlayer player2 = new BasicPlayer(board, Player.PlayerTwo); board.AddPlayer(player2); // Loop until the game is over while (board.GameState != GameState.Ended) { // Render the board in the console PrintBoardToConsole(board); // Fetch the current players turn Console.Write(board.PlayerTurn.ToFriendlyString() + " enter your move: "); var moveString = Console.ReadLine(); // Ensure the input is in the correct format (xFrom,yFrom,xTo,yTo) - no commas and must be in the correct chess notation e.g. a1a3 if (!BoardHelpers.ValidMoveRepresentation(moveString)) { Console.WriteLine("Invalid string, please enter it again."); continue; } // Fetch the available moves for the player var validMoves = new HashSet <BoardPieceMove>(); ValidMovesCalc.GetValidMovesForPlayer(board, board.PlayerTurn, validMoves); // Create an instance of the move var from = BoardHelpers.ConvertStringRepIntoPos(moveString.Substring(0, 2)); var to = BoardHelpers.ConvertStringRepIntoPos(moveString.Substring(2, 2)); var move = new BoardPieceMove(from, to); // Make sure the move is legal if (!validMoves.Contains(move)) { Console.WriteLine("Invalid move, please enter it again."); continue; } // Apply the move if (board.PlayerTurn == Player.PlayerOne) { player1.ApplyMove(move); } else { player2.ApplyMove(move); } } PrintBoardToConsole(board); Console.WriteLine(board.PlayerTurn.ToFriendlyString() + " wins!"); Console.ReadLine(); }