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);
        }
Ejemplo n.º 6
0
        /// <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));
        }
Ejemplo n.º 7
0
        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);
        }
Ejemplo n.º 8
0
        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);
        }
Ejemplo n.º 9
0
        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);
        }
Ejemplo n.º 12
0
        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);
        }
Ejemplo n.º 13
0
 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);
        }
Ejemplo n.º 15
0
        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);
        }
Ejemplo n.º 21
0
        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);
        }
Ejemplo n.º 22
0
        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);
        }
Ejemplo n.º 24
0
 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;
 }
Ejemplo n.º 26
0
 /// <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));
 }
Ejemplo n.º 27
0
 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);
                                }
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 29
0
 public bool ApplyMove(BoardPieceMove move)
 {
     return(MovePiece(move));
 }
Ejemplo n.º 30
0
        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();
        }