Exemplo n.º 1
0
        public void CastlingUndo()
        {
            ChessBoard b = CreateBoardFromMoves(new ChessMove[] {
                Move("g1", "h3"),
                Move("b8", "a6"),
                Move("e2", "e4"),
                Move("e7", "e5"),
                Move("f1", "e2"),
                Move("d8", "e7"),
                Move("a2", "a4"),
                Move("d7", "d6"),
                Move("b2", "b3"),
                Move("c8", "d7")
            });

            b.CurrentPlayer.Should().Be(1, "because after the set of moves it is white's turn again");

            var possMoves = b.GetPossibleMoves() as IEnumerable <ChessMove>;
            var whiteKing = GetMovesAtPosition(possMoves, Pos("e1"));

            whiteKing.Should().Contain(Move("e1", "g1")).And.Contain(Move("e1", "f1"))
            .And.HaveCount(2, "because you can move once and then you can castle");


            //Apply castle
            ApplyMove(b, Move("e1", "g1"));
            b.CurrentPlayer.Should().Be(2, "because after the castle it is black's turn");


            var expectedRook = b.GetPieceAtPosition(Pos("f1"));

            expectedRook.PieceType.Should()
            .Be(ChessPieceType.RookKing, "because after you castle the rook is this position");

            var expectedKing = b.GetPieceAtPosition(Pos("g1"));

            expectedKing.PieceType.Should()
            .Be(ChessPieceType.King, " because when you castle the king moves to this position");
            ChessView v = new ChessView();

            v.PrintView(Console.Out, b);
            b.UndoLastMove();
            v.PrintView(Console.Out, b);
            b.CurrentPlayer.Should().Be(1, "because we undid the move so it is white's turn again");

            //king and castle need to be in their starting positions

            var originalKing = b.GetPieceAtPosition(Pos("e1"));

            originalKing.PieceType.Should().Be(ChessPieceType.King, "because we undid the move the king goes back to the original position");
            var originalRook = b.GetPieceAtPosition(Pos("h1"));

            originalRook.PieceType.Should().Be(ChessPieceType.RookKing, "because we undid the move the rook goes back to the original position");

            //king should still be able to castle after undo

            var king = GetMovesAtPosition(possMoves, Pos("e1"));

            king.Should().Contain(Move("e1", "g1"), "because the king should still be able to castle after the undo");
        }
        public void UndoPromotion2()
        {
            ChessView  v = new ChessView();
            ChessBoard b = CreateBoardWithPositions(
                Pos("a7"), ChessPieceType.Pawn, 1,
                Pos("e1"), ChessPieceType.King, 1,
                Pos("b6"), ChessPieceType.Knight, 2,
                Pos("e8"), ChessPieceType.King, 2);

            ApplyMove(b, Move("a7", "a8"));             //player 1
            ApplyMove(b, Move("(a8, Queen)"));          //player 1
            v.PrintView(Console.Out, b);
            var shouldBeQueen = b.GetPieceAtPosition(Pos(0, 0)).PieceType;

            v.PrintView(Console.Out, b);
            shouldBeQueen.Should().Be(ChessPieceType.Queen,
                                      "Pawn should have been promoted to queen");
            b.IsCheck.Should().Be(true, "player 2 should be on check");            // player 2 is in check
            Console.WriteLine($"ayyy {b.MoveHistory.Count}");
            v.PrintView(Console.Out, b);

            b.UndoLastMove();             //player 2 undoes
            v.PrintView(Console.Out, b);

            var shouldBePawn = b.GetPieceAtPosition(Pos(0, 0)).PieceType;

            shouldBePawn.Should().Be(ChessPieceType.Pawn,
                                     "Promoted pawn is back at selection of which piece to promote to");
            ApplyMove(b, Move("(a8, Bishop)"));                              //player 1
            b.IsCheck.Should().Be(false, "player 2 should not be on check"); //player 2 no longer in check
        }
Exemplo n.º 3
0
        public void UndoKnightCapture()
        {
            // Create board with knight going to capture pawn
            ChessBoard b = CreateBoardFromMoves(new ChessMove[] {
                Move("g1", "h3"),
                Move("g7", "g5")
            });
            ChessView v = new ChessView();

            //v.PrintView(Console.Out, b);

            b.Value.Should().Be(0, "nothing has been captured");
            b.GetPieceAtPosition(Pos("g5")).PieceType.Should().Be(ChessPieceType.Pawn, "space should have pawn before capture");
            b.GetPieceAtPosition(Pos("h3")).PieceType.Should().Be(ChessPieceType.Knight, "space should have knight before capture");
            v.PrintView(Console.Out, b);
            // Knight captures pawn
            ApplyMove(b, Move("h3, g5"));
            v.PrintView(Console.Out, b);
            b.Value.Should().Be(b.GetPieceValue(ChessPieceType.Pawn), "value should now be the value of the pawn that was captured");
            b.GetPieceAtPosition(Pos("g5")).PieceType.Should().Be(ChessPieceType.Knight, "space should have knight after capture");

            // Undo knight capture
            b.UndoLastMove();

            // Pieces should be in original places
            b.Value.Should().Be(0, "capture has been undone, nothing captured");
            b.GetPieceAtPosition(Pos("g5")).PieceType.Should().Be(ChessPieceType.Pawn, "space should have pawn after undoing capture");
            b.GetPieceAtPosition(Pos("h3")).PieceType.Should().Be(ChessPieceType.Knight, "space should have knight after undoing capture");
        }
        public void PawnPromotionVerification()
        {
            ChessBoard b = CreateBoardFromMoves(new ChessMove[] {
                Move("h2", "h4"),
                Move("b8", "a6"),
                Move("h4", "h5"),
                Move("a6", "b8"),
                Move("h5", "h6"),
                Move("b8", "a6"),
                Move("h6", "g7"),
                Move("a6", "b8"),
            });

            ApplyMove(b, Move("g7, h8"));
            ChessView v = new ChessView();

            v.PrintView(Console.Out, b);
            b.GetPieceAtPosition(Pos(0, 7)).PieceType.Should().Be(ChessPieceType.Pawn, "Pawn should be waiting to be promoted after capture");
            b.CurrentPlayer.Should().Be(1, "Player should still have it's 'turn' as a means to select promotion");
            ApplyMove(b, Move("h8, Queen"));
            b.GetPieceAtPosition(Pos(0, 7)).PieceType.Should().Be(ChessPieceType.Queen, "Pawn should be Queen after Promotion");
            b.CurrentPlayer.Should().Be(2, "Player should still have it's 'turn' as a means to select promotion");
            b.UndoLastMove();
            b.GetPieceAtPosition(Pos(0, 7)).PieceType.Should().Be(ChessPieceType.Pawn, "Queen should be Pawn after Undo");
            b.CurrentPlayer.Should().Be(1, "Player should be 1 after undo");
            ApplyMove(b, Move("h8, Bishop"));
            b.GetPieceAtPosition(Pos(0, 7)).PieceType.Should().Be(ChessPieceType.Bishop, "Pawn should be Bishop after promotion");
        }
Exemplo n.º 5
0
        public void KingCheck2()
        {
            //Boxes in the king so all but one move is in a check
            ChessBoard board = CreateBoardWithPositions(
                Pos("d8"), ChessPieceType.King, 2,
                Pos("g4"), ChessPieceType.Pawn, 2,
                Pos("a7"), ChessPieceType.RookKing, 1,
                Pos("b1"), ChessPieceType.RookQueen, 1,
                Pos("a1"), ChessPieceType.King, 1);

            ApplyMove(board, Move("b1", "d1"));             //Move our Queen over to make the king uncomfortable
            ChessView v = new ChessView();

            v.PrintView(Console.Out, board);
            var  kingMoves         = board.GetPossibleMoves() as IEnumerable <ChessMove>;
            var  kingMovesExpected = GetMovesAtPosition(kingMoves, Pos("d8"));
            bool check             = board.IsCheck;

            check.Should().BeTrue("The queen threatens the king, but our king can still escape.");
            kingMovesExpected.Should().Contain(Move("d8", "e8")).And.Contain(Move("d8", "c8")).And.
            HaveCount(2, "King is in check and can only move to the left or the right, but not in the diagonals due to the rook.");
            var pawnMovesExpected = GetMovesAtPosition(kingMoves, Pos("g4"));

            pawnMovesExpected.Should().HaveCount(0, "The king is forced to move, all other pieces should be unable to move.");
        }
Exemplo n.º 6
0
        public void CastlingAndEnPassantWhite()          //Tricky moves:En passant & castling for white side  with queen side rook
        {
            ChessBoard c = CreateBoardFromMoves(new ChessMove[]
            {
                Move("c2", "c4"),
                Move("c7", "c5"),
                Move("b2", "b4"),
                Move("b7", "b5"),
                Move("d2", "d4"),
                Move("d7", "d5"),
                Move("d1", "a4"),
                Move("d8", "a5"),
                Move("c1", "f4"),
                Move("c8", "f5"),
                Move("b1", "a3"),
                Move("b8", "a6")
            });
            ChessView v = new ChessView();

            v.PrintView(Console.Out, c);
            var poss1    = c.GetPossibleMoves() as IEnumerable <ChessMove>;
            var castling = GetMovesAtPosition(poss1, Pos("e1"));

            castling.Should().Contain(Move("e1", "c1"), "King and rook both haven't moved and the spaces between them are clear to allow castling");
            ChessBoard b = CreateBoardFromMoves(new ChessMove[] {
                Move("g2", "g4"),
                Move("a7", "a6"),
                Move("g4", "g5"),
                Move("h7", "h5")
            });
            var poss      = b.GetPossibleMoves() as IEnumerable <ChessMove>;
            var enpassant = GetMovesAtPosition(poss, Pos("g5"));

            enpassant.Should().Contain(Move("g5", "h6"), "Enemy pawn moved 2 spaces and fits criteria for en passant");
        }
Exemplo n.º 7
0
        public void EnPassant3()
        {
            ChessBoard b1 = CreateBoardWithPositions(
                Pos("f1"), ChessPieceType.King, 1,
                Pos("c5"), ChessPieceType.Pawn, 1,
                Pos("b7"), ChessPieceType.Pawn, 2,
                Pos("g8"), ChessPieceType.King, 2
                );

            b1.CurrentPlayer.Should().Be(1, "Player 1 turn");
            ApplyMove(b1, Move("f1", "e1"));
            b1.CurrentPlayer.Should().Be(2, "Player 2 turn");
            ApplyMove(b1, Move("b7", "b5"));
            b1.CurrentPlayer.Should().Be(1, "Player 1 turn");

            var possMoves = b1.GetPossibleMoves();

            foreach (ChessMove m  in possMoves)
            {
                Console.WriteLine(m.ToString());
            }
            ChessView v = new ChessView();

            v.PrintView(Console.Out, b1);
            possMoves.Should().HaveCount(7, "There are 2 possible moves for the pawn, and 5 for the King");
            ApplyMove(b1, Move("c5", "b6"));             //en passant
        }
Exemplo n.º 8
0
        public void Castling5()
        {
            ChessBoard b = CreateBoardWithPositions(
                Pos("a2"), ChessPieceType.RookKing, 1,
                Pos("e1"), ChessPieceType.King, 1,
                Pos("e8"), ChessPieceType.King, 2,
                Pos("h8"), ChessPieceType.RookKing, 2,
                Pos("f7"), ChessPieceType.Pawn, 2,
                Pos("g7"), ChessPieceType.Pawn, 2,
                Pos("h7"), ChessPieceType.Pawn, 2);
            //put the king in check
            ChessView v = new ChessView();

            v.PrintView(Console.Out, b);
            ApplyMove(b, Move("a2", "e2"));
            v.PrintView(Console.Out, b);
            var possMoves        = b.GetPossibleMoves() as IEnumerable <ChessMove>;
            var checkedKingMoves = GetMovesAtPosition(possMoves, Pos("e8"));

            checkedKingMoves.Should().NotContain(Move("e8", "g8")).And.HaveCount(3, "The king can not castle in a check.");

            b.UndoLastMove();
            //Keeping the rook away this time
            ApplyMove(b, Move("a2", "a3"));

            var availRookMoves     = b.GetPossibleMoves() as IEnumerable <ChessMove>;
            var expectedCastleRook = GetMovesAtPosition(availRookMoves, Pos("h8"));

            expectedCastleRook.Should().Contain(Move("h8", "f8")).And.HaveCount(2, "Rook only has the three spaces to its right when locked in by pawns and a king.");

            var availKingMoves     = b.GetPossibleMoves() as IEnumerable <ChessMove>;
            var expectedCastleKing = GetMovesAtPosition(availKingMoves, Pos("e8"));

            expectedCastleKing.Should().Contain(Move("e8", "d7")).And.Contain(Move("e8", "f8")).And.
            Contain(Move("e8", "e7")).And.Contain(Move("e8", "g8")).And.HaveCount(5, "The standard 1-space king moves with the addition with the available castling location.");

            //Castle applied
            ApplyMove(b, Move("e8", "g8"));
            var castledRook = b.GetPieceAtPosition(Pos("f8"));

            castledRook.PieceType.Should().Be(ChessPieceType.RookKing, "Rook moves to the right of the of the king's old position.");
            var castledKing = b.GetPieceAtPosition(Pos("g8"));

            castledKing.PieceType.Should().Be(ChessPieceType.King, "King moved 2 spaces to the right to hide behind the rook.");
        }
Exemplo n.º 9
0
        public void test1()
        {
            ChessBoard b = CreateBoardWithPositions(Pos("e1"), ChessPieceType.King, 1, Pos("h1"), ChessPieceType.RookKing, 1);

            ApplyMove(b, Move("e1,g1"));
            //b.UndoLastMove();
            ChessView v = new ChessView();

            v.PrintView(Console.Out, b);
            ChessMove x = b.MoveHistory[0] as ChessMove;
        }
Exemplo n.º 10
0
        public void PawnPromotionTrick()
        {
            ChessBoard b = CreateBoardWithPositions(
                Pos("d7"), ChessPieceType.Pawn, 1,
                Pos("a2"), ChessPieceType.Pawn, 2,
                Pos("f3"), ChessPieceType.Queen, 2,
                Pos("e1"), ChessPieceType.King, 1,
                Pos("a6"), ChessPieceType.RookKing, 1,
                Pos("h8"), ChessPieceType.King, 2);
            ChessView v = new ChessView();

            var possMoves = b.GetPossibleMoves() as IEnumerable <ChessMove>;

            possMoves = b.GetPossibleMoves() as IEnumerable <ChessMove>;
            b.CurrentPlayer.Should().Be(1, "Player 1 starts the game");
            var pawnpromotionexpected = GetMovesAtPosition(possMoves, Pos("d7"));

            pawnpromotionexpected.Should().HaveCount(1, "Pawn should be able to move up to 8th rank");

            ApplyMove(b, Move("d7", "d8"));

            possMoves = b.GetPossibleMoves() as IEnumerable <ChessMove>;

            ApplyMove(b, Move("(d8, Queen)"));

            var pawnpromotion = b.GetPieceAtPosition(Pos("d8"));

            v.PrintView(Console.Out, b);
            pawnpromotion.PieceType.Should().Be(ChessPieceType.Queen, "White pawn should be Queen");
            v.PrintView(Console.Out, b);
            possMoves = b.GetPossibleMoves() as IEnumerable <ChessMove>;
            v.PrintView(Console.Out, b);
            possMoves.Should().HaveCount(3).And.NotContain(Move("a2", "a1"));
            ApplyMove(b, Move("h8", "h7"));
            ApplyMove(b, Move("d8", "c8"));
            ApplyMove(b, Move("a2", "a1"));
            ApplyMove(b, Move("(a1, Queen)"));

            pawnpromotion.PieceType.Should().Be(ChessPieceType.Queen, "Black pawn should be Queen");
        }
Exemplo n.º 11
0
        public void Castling2()
        {
            ChessBoard b = CreateBoardWithPositions(
                Pos("e1"), ChessPieceType.King, 1,
                Pos("a1"), ChessPieceType.RookQueen, 1,
                Pos("h1"), ChessPieceType.RookKing, 1);

            b.GetPossibleMoves().Should().Contain(Move("e1", "c1"), "King should be able to castle with king side rook")
            .And.Contain(Move("e1", "g1"), "King should be able to castle with queen side rook");
            ChessView v = new ChessView();

            //castle left
            // v.PrintView(Console.Out, b);
            ApplyMove(b, Move("e1", "c1"));

            b.GetPieceAtPosition(new BoardPosition(7, 3)).PieceType.Should().Be(ChessPieceType.RookQueen,
                                                                                "Queen side rook should have moved right");
            b.PositionIsEmpty(new BoardPosition(7, 4)).Should().BeTrue("King no longer where it was after castling");
            b.GetPieceAtPosition(new BoardPosition(7, 2)).PieceType.Should().Be(ChessPieceType.King, "King should be to left of rook");
            // v.PrintView(Console.Out, b);
            b.UndoLastMove();
            // v.PrintView(Console.Out, b);
            b.GetPieceAtPosition(new BoardPosition(7, 4)).PieceType.Should().Be(ChessPieceType.King,
                                                                                "King should be returned to correct position after undoing castling");
            b.GetPieceAtPosition(new BoardPosition(7, 0)).PieceType.Should().Be(ChessPieceType.RookQueen,
                                                                                "Rook should be returned to correct position after undoing castling");

            //castle right
            ApplyMove(b, Move("e1", "g1"));
            b.GetPieceAtPosition(new BoardPosition(7, 5)).PieceType.Should().Be(ChessPieceType.RookKing,
                                                                                "King side rook should have moved left");
            b.PositionIsEmpty(new BoardPosition(7, 4)).Should().BeTrue("King no longer where it was after castling");
            b.GetPieceAtPosition(new BoardPosition(7, 6)).PieceType.Should().Be(ChessPieceType.King, "King should be to right of rook");
            // v.PrintView(Console.Out, b);
            b.UndoLastMove();
            // v.PrintView(Console.Out, b);
            b.GetPieceAtPosition(new BoardPosition(7, 4)).PieceType.Should().Be(ChessPieceType.King,
                                                                                "King should be returned to correct position after undoing castling");
            b.GetPieceAtPosition(new BoardPosition(7, 0)).PieceType.Should().Be(ChessPieceType.RookQueen,
                                                                                "Rook should be returned to correct position after undoing castling");

            //castle with pieces in way
            b = CreateBoardWithPositions(
                Pos("e1"), ChessPieceType.King, 1,
                Pos("a1"), ChessPieceType.RookQueen, 1,
                Pos("h1"), ChessPieceType.RookKing, 1,
                Pos("b1"), ChessPieceType.Knight, 1,
                Pos("g1"), ChessPieceType.Knight, 1);
            v.PrintView(Console.Out, b);
            b.GetPossibleMoves().Should().NotContain(Move("e1", "c1"), "King should not be able to castle with king side rook with piece in the way")
            .And.NotContain(Move("e1", "g1"), "King should not be able to castle with queen side rook with piece in the way");
        }
Exemplo n.º 12
0
 protected static string ToString(ChessBoard b)
 {
     using (MemoryStream s = new MemoryStream()) {
         StreamWriter writer = new StreamWriter(s, Encoding.Unicode);
         writer.WriteLine();
         writer.WriteLine("Board: ");
         BlankView.PrintView(writer, b);
         writer.WriteLine(BlankView.GetPlayerString(b.CurrentPlayer) + "'s turn");
         writer.Flush();
         var ret = Encoding.Unicode.GetString(s.ToArray());
         return(ret);
     }
 }
Exemplo n.º 13
0
        public void Pawns2SpaceThen1()
        {
            ChessBoard b = new ChessBoard();

            ApplyMove(b, Move("c2", "c4"));
            ApplyMove(b, Move("c7", "c5"));
            ChessView v = new ChessView();

            v.PrintView(Console.Out, b);
            b.GetPossibleMoves().Should().NotContain(Move("c4", "c5"),
                                                     "Pawn will collide with another pawn");
            ApplyMove(b, Move("a2", "a4"));
            ApplyMove(b, Move("h7", "h5"));
            b.GetPossibleMoves().Should().NotContain(Move("a4", "a6"),
                                                     "Pawn should only be able to move 1 foreward");
            ApplyMove(b, Move("a4", "a5"));
            b.GetPossibleMoves().Should().NotContain(Move("h5", "h3"),
                                                     "Pawn should only be able to move 1 foreward");
            ApplyMove(b, Move("h5", "h4"));
        }
Exemplo n.º 14
0
        public void EnPassant4()
        {
            ChessBoard b = CreateBoardFromMoves(new ChessMove[] {
                Move("e2", "e4"),
                Move("a7", "a6"),
                Move("e4", "e5"),
                Move("d7", "d5"),
                Move("e5", "d6"),
            });
            ChessView v = new ChessView();

            v.PrintView(Console.Out, b);
            var captured = b.GetPieceAtPosition(Pos("d5"));

            captured.Player.Should().Be(0, "Piece is captured and should be empty");

            b.UndoLastMove();
            captured = b.GetPieceAtPosition(Pos("d5"));
            captured.Player.Should().Be(2, "THe piece is returned because of the undo");
        }
Exemplo n.º 15
0
        public void KnightCapturesAQueen()
        {
            ChessBoard b    = new ChessBoard();
            ChessView  view = new ChessView();

            ApplyMove(b, Move("d2", "d4"));
            ApplyMove(b, Move("e7", "e5"));
            ApplyMove(b, Move("b1", "c3"));
            ApplyMove(b, Move("d7", "d5"));

            ApplyMove(b, Move("d4", "e5"));
            view.PrintView(Console.Out, b);
            Console.WriteLine("!!!!!" + b.GetPieceAtPosition(Pos(3, 4)).PieceType.ToString() + b.GetPieceAtPosition(Pos(3, 4)).Player.ToString());

            ApplyMove(b, Move("d5", "d4"));
            view.PrintView(Console.Out, b);

            ApplyMove(b, Move("c3", "e4"));
            view.PrintView(Console.Out, b);

            ApplyMove(b, Move("d8", "d5"));
            view.PrintView(Console.Out, b);

            ApplyMove(b, Move("e4", "c3"));
            view.PrintView(Console.Out, b);

            ApplyMove(b, Move("d5", "e4"));
            Console.WriteLine("!!!!!" + b.GetPieceAtPosition(Pos(5, 2)).PieceType.ToString() + b.GetPieceAtPosition(Pos(5, 2)).Player.ToString());

            //KNight eats the queen
            //var possMoves = b.GetPossibleMoves() as IEnumerable<ChessMove>;
            //possMoves.Should().Contain(Move("c3", "e4"));
            //possMoves.Should().BeEmpty();
            ApplyMove(b, Move("c3", "e4"));

            Console.WriteLine("!!!!!" + b.GetPieceAtPosition(Pos(5, 2)).PieceType.ToString() + b.GetPieceAtPosition(Pos(5, 2)).Player.ToString());

            view.PrintView(Console.Out, b);
            b.GetPieceAtPosition(Pos("c3")).PieceType.Should().Be(ChessPieceType.Empty, "The peice is no longer there its empty was eaten");
            b.GetPieceAtPosition(Pos("e4")).PieceType.Should().Be(ChessPieceType.Knight, "The new occupied space is a knight");
        }
Exemplo n.º 16
0
        static void Main(string[] args)
        {
            // Even though this project only involves chess, it is written in a way that any other implementation of
            // IGameBoard could be used in this main.
            IGameBoard board = new ChessBoard();
            IGameView  view  = new ChessView();

            while (true)
            {
                // Print the view.
                Console.WriteLine();
                Console.WriteLine();
                view.PrintView(Console.Out, board);
                Console.WriteLine();
                Console.WriteLine();

                // Print the possible moves.
                var possMoves = board.GetPossibleMoves();
                Console.WriteLine("Possible moves:");
                Console.WriteLine(String.Join(", ", possMoves));

                // Print the turn indication.
                Console.WriteLine();
                Console.Write("{0}'s turn: ", view.GetPlayerString(board.CurrentPlayer));

                string input = Console.ReadLine();
                if (input.StartsWith("move "))
                {
                    IGameMove move      = view.ParseMove(input.Substring(5));
                    bool      foundMove = false;
                    foreach (var poss in possMoves)
                    {
                        if (poss.Equals(move))
                        {
                            board.ApplyMove(poss);
                            foundMove = true;
                            break;
                        }
                    }
                    if (!foundMove)
                    {
                        Console.WriteLine("That is not a possible move, please try again.");
                    }
                }
                else if (input.StartsWith("undo "))
                {
                    // Parse the number of moves to undo and repeatedly undo one move.
                    int undoCount = Convert.ToInt32(input.Substring(5));
                    while (undoCount > 0 && board.MoveHistory.Count > 0)
                    {
                        board.UndoLastMove();
                        undoCount--;
                    }
                }
                else if (input == "showHistory")
                {
                    // Show the move history in reverse order.
                    Console.WriteLine("History:");
                    int player = -board.CurrentPlayer;
                    foreach (var move in board.MoveHistory.Reverse())
                    {
                        Console.WriteLine("{0}: {1}", player == 1 ? "Black" : "White", move);
                        player = -player;
                    }
                }
                else if (input == "showValue")
                {
                    Console.WriteLine("Value: {0}", board.Value);
                }
            }
        }