public void testKingsideCastlingMoveIsExecutedCorrectly()
        {
            DoktorChessAIBoard ourBoard = new DoktorChessAIBoard(gameType.normal, boardSearchConfig.getDebugConfig());
            square ourKing = ourBoard.addPiece(pieceType.king, pieceColour.white, 4, 0);
            square ourRook = ourBoard.addPiece(pieceType.rook, pieceColour.white, 7, 0);
            ourBoard.addPiece(pieceType.king, pieceColour.black, 0, 0);

            // Make our castling move..
            move castlingMove = new move(ourKing, ourBoard[6, 0]);
            ourBoard.doMove(castlingMove);

            // Verify that the rook and king have both moved to their correct squares.
            Assert.IsTrue(ourBoard[6, 0] == ourKing);
            Assert.IsTrue(ourBoard[5, 0] == ourRook);
        }
        public void testKingsideCastlingMoveIsNotAfterRookHasMoved()
        {
            DoktorChessAIBoard ourBoard = new DoktorChessAIBoard(gameType.normal, boardSearchConfig.getDebugConfig());
            square ourKing = ourBoard.addPiece(pieceType.king, pieceColour.white, 4, 0);
            square ourRook = ourBoard.addPiece(pieceType.rook, pieceColour.white, 6, 0);
            ourBoard.addPiece(pieceType.king, pieceColour.black, 0, 0);

            // Move the rook to 7,0.
            ourBoard.doMove(new move(ourRook, ourBoard[7,0]));

            // Now make sure we cannot castle.
            sizableArray<move> possibleMoves = ourKing.getPossibleMoves(ourBoard);

            // None of these moves should end up at (6,0).
            if (Array.Find(possibleMoves.getArray(), a => a.dstPos.isSameSquareAs(new squarePos(6, 0))) != null)
                throw new AssertFailedException("Castling found after rook has moved");
        }
示例#3
0
        public void testMoveDoingUndoingWithPawnPromotion()
        {
            DoktorChessAIBoard ourBoard = new DoktorChessAIBoard(gameType.normal, boardSearchConfig.getDebugConfig());
            ourBoard.addPiece(pieceType.pawn, pieceColour.white, 1, 6);

            string origBoard = ourBoard.ToString();

            sizableArray<move> potentialMoves = ourBoard.getMoves(pieceColour.white);

            if (potentialMoves.Length == 0)
                Assert.Inconclusive("No pawn moves found");

            // Find promotion moves
            move[] promotionMoves = Array.FindAll(potentialMoves.getArray(), a => a.isPawnPromotion);

            if (promotionMoves.Length == 0)
                Assert.Inconclusive("No promotion moves found");

            foreach (move thisMove in promotionMoves)
            {
                ourBoard.doMove(thisMove);

                if (ourBoard.ToString() == origBoard)
                    throw new AssertFailedException("After a pawn promotion move, the board has not changed");

                // Additionally, verify that the pawn has been promoted
                if (ourBoard[thisMove.dstPos].type != thisMove.typeToPromoteTo)
                    throw new AssertFailedException("Pawn was not promoted");
                if (ourBoard[thisMove.dstPos].GetType() == typeof(pawnSquare))
                    throw new AssertFailedException("Pawn was not promoted, but type has changed");
                if (ourBoard[thisMove.dstPos].colour != pieceColour.white)
                    throw new AssertFailedException("Pawn was promoted to wrong colour");

                ourBoard.undoMove(thisMove);

                if (ourBoard.ToString() != origBoard)
                    throw new AssertFailedException("After a pawn promotion move undo, the board has changed");
            }
        }
        public void testKingsideCastlingMoveIsUnExecutedCorrectly()
        {
            DoktorChessAIBoard ourBoard = new DoktorChessAIBoard(gameType.normal, boardSearchConfig.getDebugConfig());
            square ourKing = ourBoard.addPiece(pieceType.king, pieceColour.white, 4, 0);
            square ourRook = ourBoard.addPiece(pieceType.rook, pieceColour.white, 7, 0);
            ourBoard.addPiece(pieceType.king, pieceColour.black, 0, 0);

            string origBoard = ourBoard.ToString();

            // Make out castling move
            move castlingMove = new move(ourKing, ourBoard[6, 0]);
            ourBoard.doMove(castlingMove);

            Assert.AreNotEqual(origBoard, ourBoard.ToString(), "Castling did not affect the board");

            // Now undo our castling and verify that we get back to the original position.
            ourBoard.undoMove(castlingMove);

            Assert.AreEqual(origBoard, ourBoard.ToString(), "Castling and then un-castling did not return the original board");
        }
        public void testThatEnPassantOccursWhenItShouldAsBlack()
        {
            DoktorChessAIBoard ourBoard = new DoktorChessAIBoard(gameType.normal, boardSearchConfig.getDebugConfig());
            // En passant requires that the enemy pawn has just advanced two squares. Because of this, we make this move on a board and then check that en passant can occur.
            square ourPawn = ourBoard.addPiece(pieceType.pawn, pieceColour.black, 6, 3);
            square enemyPawn = ourBoard.addPiece(pieceType.pawn, pieceColour.white, 7, 1);

            // Advance the enemy pawn
            move advanceTwo = new move(enemyPawn, ourBoard[enemyPawn.position.up(2)]);
            ourBoard.doMove(advanceTwo);

            // Now verify that the enemy pawn is captured.
            sizableArray<move> possibleMoves = ourPawn.getPossibleMoves(ourBoard);
            move enPassantCapture = null;
            foreach (move thisMove in possibleMoves)
            {
                if (thisMove.isCapture)
                {
                    if (enPassantCapture != null)
                        throw new AssertFailedException("More than one capture was found");

                    // Note that our dest square is not the enemy square here.
                    Assert.IsTrue(thisMove.srcPos.isSameSquareAs(ourPawn.position));
                    Assert.IsTrue(thisMove.dstPos.isSameSquareAs(ourPawn.position.rightOne().downOne() ));
                    Assert.AreSame(thisMove.capturedSquare, enemyPawn);

                    enPassantCapture = thisMove;
                }
            }
            if (enPassantCapture == null)
                throw new AssertFailedException("En passant capture did not occur");

            // Make sure that the en passant capture ends up putting our pawn in the square above the enemy pawn
            Assert.IsTrue(enemyPawn.position.downOne().isSameSquareAs( enPassantCapture.dstPos) );
        }
        public void verifyFiftyMoveRule(DoktorChessAIBoard ourBoard, int moveOffset)
        {
            for (int n = 0; n < 100 - moveOffset; n++)
            {
                Assert.AreEqual(gameStatus.inProgress, ourBoard.getGameStatus(pieceColour.white), "Game declared drawn at move " + n.ToString());

                switch (n % 4)
                {
                    case 0:
                        // Play Nc3
                        ourBoard.doMove(new move(ourBoard[1, 0], ourBoard[2, 2]));
                        break;
                    case 1:
                        // Play Nc6
                        ourBoard.doMove(new move(ourBoard[1, 7], ourBoard[2, 5]));
                        break;
                    case 2:
                        // And move knights back again.
                        // Nb1
                        ourBoard.doMove(new move(ourBoard[2, 2], ourBoard[1, 0]));
                        break;
                    case 3:
                        // nb8
                        ourBoard.doMove(new move(ourBoard[2, 5], ourBoard[1, 7]));
                        break;
                    default:
                        throw new ArgumentException();
                }
            }
            // 50 moves have elapsed! It's a draw!
            Assert.AreEqual(gameStatus.drawn, ourBoard.getGameStatus(pieceColour.white));
        }
示例#7
0
        public void testThreatMapDeep_pawnCapture()
        {
            DoktorChessAIBoard ourBoard = new DoktorChessAIBoard(gameType.queenAndPawns, boardSearchConfig.getDebugConfig());
            square ourPawn = ourBoard.addPiece(pieceType.pawn, pieceColour.white, 4, 1);
            square enemyPawn = ourBoard.addPiece(pieceType.pawn, pieceColour.black, 3, 2);

            if (ourBoard.getCoverLevel(new squarePos(3, 2), pieceColour.white) != 1 ||
                ourBoard.getCoverLevel(new squarePos(5, 2), pieceColour.white) != 1)
                throw new AssertFailedException("Threatmap created wrongly");

            if (ourBoard.getCoverLevel(new squarePos(2, 1), pieceColour.white) != -1 ||
                ourBoard.getCoverLevel(new squarePos(4, 1), pieceColour.white) != -1)
                throw new AssertFailedException("Enemy pawn create with no threatened squares");

            if (ourPawn.coveredSquares.Count != 2)
                throw new AssertFailedException("Pawn created not covering two squares");

            if ((!ourPawn.coveredSquares[3, 2]) ||
                (!ourPawn.coveredSquares[5, 2])   )
                throw new AssertFailedException("Pawn created with incorrect .coveredSquares");

            if (((threatMap)ourBoard.coverLevel).piecesWhichThreatenSquare[3, 2].Count != 1 ||
                ((threatMap)ourBoard.coverLevel).piecesWhichThreatenSquare[3, 2].Count != 1)
                throw new AssertFailedException("Pawn created with incorrect .piecesWhichThreatenSquare count");

            //if (((threatMap)ourBoard.coverLevel).piecesWhichThreatenSquare[3, 2][ourPawn.position.flatten()] != ourPawn ||
            //    ((threatMap)ourBoard.coverLevel).piecesWhichThreatenSquare[5, 2][ourPawn.position.flatten()] != ourPawn)
            //    throw new AssertFailedException("Pawn created with incorrect .piecesWhichThreatenSquare contents");

            move ourMove = new move(ourPawn, ourBoard[3, 2]);
            ourBoard.doMove(ourMove);

            if (ourBoard.getCoverLevel(new squarePos(2, 3), pieceColour.white) != 1 ||
                ourBoard.getCoverLevel(new squarePos(4, 3), pieceColour.white) != 1)
                throw new AssertFailedException("Threatmap did not update cover levels correctly");

            if (ourBoard.getCoverLevel(new squarePos(2, 1), pieceColour.white) != 0 ||
                ourBoard.getCoverLevel(new squarePos(4, 1), pieceColour.white) != 0)
                throw new AssertFailedException("Captured pawn still has threatened squares");

            if (ourPawn.coveredSquares.Count != 2)
                throw new AssertFailedException("Pawn updated not covering two squares");

            if (!ourPawn.coveredSquares[2, 3] ||
                !ourPawn.coveredSquares[4, 3]   )
                throw new AssertFailedException("Pawn updated with incorrect .coveredSquares");

            if (((threatMap)ourBoard.coverLevel).piecesWhichThreatenSquare[3, 2].Count != 0 ||
                ((threatMap)ourBoard.coverLevel).piecesWhichThreatenSquare[3, 2].Count != 0)
                throw new AssertFailedException("Pawn's pre-update .piecesWhichThreatenSquare was not changed");

            if (((threatMap)ourBoard.coverLevel).piecesWhichThreatenSquare[2, 3].Count != 1 ||
                ((threatMap)ourBoard.coverLevel).piecesWhichThreatenSquare[4, 3].Count != 1)
                throw new AssertFailedException("Pawn updated with incorrect .piecesWhichThreatenSquare count");

            //if (((threatMap)ourBoard.coverLevel).piecesWhichThreatenSquare[2, 3][ourPawn.position.flatten()] != ourPawn ||
            //    ((threatMap)ourBoard.coverLevel).piecesWhichThreatenSquare[4, 3][ourPawn.position.flatten()] != ourPawn)
            //    throw new AssertFailedException("Pawn updated with incorrect .piecesWhichThreatenSquare contents");
        }
示例#8
0
        public void testThreatMapDeep_discoveredPromotion()
        {
            DoktorChessAIBoard ourBoard = new DoktorChessAIBoard(gameType.queenAndPawns, boardSearchConfig.getDebugConfig());
            square ourPawn = ourBoard.addPiece(pieceType.pawn, pieceColour.white, 3, 6);
            square enemyPawn = ourBoard.addPiece(pieceType.pawn, pieceColour.black, 3, 7);
            square ourRook = ourBoard.addPiece(pieceType.rook, pieceColour.white, 0, 7);

            move ourMove = new move(ourPawn, ourBoard[3, 7], pieceType.queen);
            ourBoard.doMove(ourMove);

            // Observe the squares to the right of our pawn - they should not be accessible to the rook
            for (int x = 4; x < 7; x++)
            {
                if (ourBoard.getCoverLevel(new squarePos(x, 7), pieceColour.white) != 1)
                    throw new AssertFailedException("Threatmap did not update cover levels correctly");
            }

            // the pawn itself is protected once.
            if (ourBoard.getCoverLevel(new squarePos(3, 7), pieceColour.white) != 1)
                throw new AssertFailedException("Threatmap did not update cover levels of promoted piece correctly");
        }
示例#9
0
        public void testThreatMapDeep_discoveredCapture()
        {
            DoktorChessAIBoard ourBoard = new DoktorChessAIBoard(gameType.queenAndPawns, boardSearchConfig.getDebugConfig());

            square ourPawn = ourBoard.addPiece(pieceType.pawn, pieceColour.white, 0, 1);
            square enemyPawn = ourBoard.addPiece(pieceType.pawn, pieceColour.black, 1, 2);
            square ourRook = ourBoard.addPiece(pieceType.rook, pieceColour.white, 0, 0);
            square enemyRook = ourBoard.addPiece(pieceType.rook, pieceColour.black, 0, 7);

            move ourMove = new move(ourPawn, enemyPawn);
            ourBoard.doMove(ourMove);

            // Squares between rooks our pawn should be threatened by both rooks, so should have a threat
            // level of 0, apart from the one at y=3, which is threatened by a pawn.
            for (int x = 1; x < 7; x++)
            {
                if (x == 3)
                {
                    if (ourBoard.getCoverLevel(new squarePos(0, x), pieceColour.black) != -1)
                        throw new AssertFailedException("Threatmap did not update cover levels correctly for discovered spaces");
                }
                else
                {
                    if (ourBoard.getCoverLevel(new squarePos(0, x), pieceColour.black) != 0)
                        throw new AssertFailedException("Threatmap did not update cover levels correctly for discovered spaces");
                }
            }

            // Both rooks should be threatened once, by the other rook.
            if (ourBoard.getCoverLevel(new squarePos(0, 0), pieceColour.black) !=  1 ||
                ourBoard.getCoverLevel(new squarePos(0, 7), pieceColour.white) !=  1   )
                throw new AssertFailedException("Threatmap did not update cover levels correctly for rooks");
        }
示例#10
0
        public void testThreatMapDeep_discovered()
        {
            DoktorChessAIBoard ourBoard = new DoktorChessAIBoard(gameType.queenAndPawns, boardSearchConfig.getDebugConfig()  );
            square ourPawn = ourBoard.addPiece(pieceType.pawn, pieceColour.white, 4, 1);
            square ourRook = ourBoard.addPiece(pieceType.rook, pieceColour.white, 0, 1);

            move ourMove = new move(ourPawn, ourBoard[4, 2]);
            ourBoard.doMove(ourMove);

            // Observe the squares to the right of our pawn - they should now be accessible to the rook

            for (int x = 1; x < 7; x++)
            {
                if (ourBoard.getCoverLevel(new squarePos(x, 1), pieceColour.white) != 1)
                    throw new AssertFailedException("Threatmap did not update cover levels correctly");
            }
        }
示例#11
0
        public void testMoveUndoingThreatmap_Castling()
        {
            DoktorChessAIBoard ourBoard = new DoktorChessAIBoard(gameType.normal, boardSearchConfig.getDebugConfig());
            square ourKing = ourBoard.addPiece(pieceType.king, pieceColour.white, 4, 0);
            square ourRook = ourBoard.addPiece(pieceType.rook, pieceColour.white, 7, 0);

            square enemyPawn = ourBoard.addPiece(pieceType.pawn, pieceColour.black, 6, 6);

            string origThreatMap = ourBoard.coverLevel.ToString();

            int[,] threatCounts = new int[DoktorChessAIBoard.sizeX,DoktorChessAIBoard.sizeY];
            for (int x = 0; x < DoktorChessAIBoard.sizeX; x++)
            {
                for (int y = 0; y < DoktorChessAIBoard.sizeY; y++)
                {
                    threatCounts[x, y] = ourBoard[x, y].coveredSquares.Count;
                }
            }

            move castling = new move(ourKing, ourBoard[6, 0]);

            ourBoard.doMove(castling);

            if (ourBoard.coverLevel.ToString() == origThreatMap)
                throw new AssertFailedException("After a move, the threat map has not changed");

            ourBoard.undoMove(castling);

            if (ourBoard.coverLevel.ToString() != origThreatMap)
            {
                Debug.WriteLine("Expected:");
                Debug.WriteLine(origThreatMap);
                Debug.WriteLine("Actual:");
                Debug.WriteLine(ourBoard.coverLevel.ToString());
                throw new AssertFailedException("After a move undo, the threat map has changed");
            }

            for (int x = 0; x < DoktorChessAIBoard.sizeX; x++)
            {
                for (int y = 0; y < DoktorChessAIBoard.sizeY; y++)
                {
                    if (threatCounts[x, y] != ourBoard[x, y].coveredSquares.Count)
                        throw new AssertFailedException("Piece covered count incorrect");
                }
            }
        }