Example #1
0
        public void Board_MakeUnMake_WhiteEnPassantCapture()
        {
            var board = CreateBitBoard("K6k/8/8/3Pp3/8/8/8/8 w - e6");

            var rootKey = KeyGenerator.Hash(board, Colour.White);

            var enPassantCapture = MoveBuilder.Create(Colour.White, PieceType.Pawn, SquareFlag.D5.ToSquare(), SquareFlag.E6.ToSquare(), PieceType.Pawn, MoveType.EnPassant);

            var beforeKey = board.Key;

            board.MakeMove(enPassantCapture);

            var hashKey   = KeyGenerator.Hash(board, Colour.Black);
            var updateKey = KeyGenerator.UpdateHash(rootKey, enPassantCapture);

            Assert.Equal(hashKey, board.Key);
            Assert.Equal(updateKey, board.Key);

            var afterKey = board.Key;

            board.UnMakeMove(enPassantCapture);

            var hashKey2   = KeyGenerator.Hash(board, Colour.White);
            var updateKey2 = KeyGenerator.UpdateHash(updateKey, enPassantCapture);

            Assert.Equal(hashKey2, board.Key);
            Assert.Equal(updateKey2, board.Key);

            Assert.NotEqual(beforeKey, afterKey);
            Assert.Equal(beforeKey, board.Key);
        }
Example #2
0
        public void E4_16Moves_8Captures_Correct()
        {
            var gameState = FenHelpers.Parse("K7/8/2p1p1p1/8/2p1Q1p1/8/2p1p1p1/k7 w - -");

            var board = CreateBoard(gameState);

            var moves = new List <uint>(10);

            MoveGenerator.Generate(board, gameState.ToPlay, moves);

            var moveCount    = moves.Count;
            var captureViews = GetCaptureMoveViews(moves);

            var capture1 = MoveBuilder.Create(Colour.White, PieceType.Queen, SquareFlag.E4.ToSquare(), SquareFlag.C6.ToSquare(), PieceType.Pawn, MoveType.Ordinary);
            var capture2 = MoveBuilder.Create(Colour.White, PieceType.Queen, SquareFlag.E4.ToSquare(), SquareFlag.E6.ToSquare(), PieceType.Pawn, MoveType.Ordinary);
            var capture3 = MoveBuilder.Create(Colour.White, PieceType.Queen, SquareFlag.E4.ToSquare(), SquareFlag.G6.ToSquare(), PieceType.Pawn, MoveType.Ordinary);
            var capture4 = MoveBuilder.Create(Colour.White, PieceType.Queen, SquareFlag.E4.ToSquare(), SquareFlag.C4.ToSquare(), PieceType.Pawn, MoveType.Ordinary);
            var capture5 = MoveBuilder.Create(Colour.White, PieceType.Queen, SquareFlag.E4.ToSquare(), SquareFlag.G4.ToSquare(), PieceType.Pawn, MoveType.Ordinary);
            var capture6 = MoveBuilder.Create(Colour.White, PieceType.Queen, SquareFlag.E4.ToSquare(), SquareFlag.C2.ToSquare(), PieceType.Pawn, MoveType.Ordinary);
            var capture7 = MoveBuilder.Create(Colour.White, PieceType.Queen, SquareFlag.E4.ToSquare(), SquareFlag.E2.ToSquare(), PieceType.Pawn, MoveType.Ordinary);
            var capture8 = MoveBuilder.Create(Colour.White, PieceType.Queen, SquareFlag.E4.ToSquare(), SquareFlag.G2.ToSquare(), PieceType.Pawn, MoveType.Ordinary);

            var captures = captureViews.Select(x => x.Value);

            Assert.Contains(capture1, captures);
            Assert.Contains(capture2, captures);
            Assert.Contains(capture3, captures);
            Assert.Contains(capture4, captures);
            Assert.Contains(capture5, captures);
            Assert.Contains(capture6, captures);
            Assert.Contains(capture7, captures);
            Assert.Contains(capture8, captures);
        }
Example #3
0
        public void White_Empty_OnePush_Promotion()
        {
            var board = CreateBitBoard("K6k/3P4/8/8/8/8/8/8 w - -");

            var rootKey = KeyGenerator.Hash(board, Colour.White);

            var promotion1 = MoveBuilder.Create(Colour.White, PieceType.Pawn, SquareFlag.D7.ToSquare(), SquareFlag.D8.ToSquare(), PieceType.None, MoveType.PromotionQueen);
            var promotion2 = MoveBuilder.Create(Colour.White, PieceType.Pawn, SquareFlag.D7.ToSquare(), SquareFlag.D8.ToSquare(), PieceType.None, MoveType.PromotionRook);
            var promotion3 = MoveBuilder.Create(Colour.White, PieceType.Pawn, SquareFlag.D7.ToSquare(), SquareFlag.D8.ToSquare(), PieceType.None, MoveType.PromotionBishop);
            var promotion4 = MoveBuilder.Create(Colour.White, PieceType.Pawn, SquareFlag.D7.ToSquare(), SquareFlag.D8.ToSquare(), PieceType.None, MoveType.PromotionKnight);

            var beforeKey = board.Key;

            board.MakeMove(promotion1);

            var hashKey   = KeyGenerator.Hash(board, Colour.Black);
            var updateKey = KeyGenerator.UpdateHash(rootKey, promotion1);

            Assert.Equal(hashKey, board.Key);
            Assert.Equal(updateKey, board.Key);

            var afterKey = board.Key;

            board.UnMakeMove(promotion1);

            var hashKey2   = KeyGenerator.Hash(board, Colour.White);
            var updateKey2 = KeyGenerator.UpdateHash(updateKey, promotion1);

            Assert.Equal(hashKey2, board.Key);
            Assert.Equal(updateKey2, board.Key);

            Assert.NotEqual(beforeKey, afterKey);
            Assert.Equal(beforeKey, board.Key);
        }
Example #4
0
        public void Move_AreEqual()
        {
            var moveA = MoveBuilder.Create(Colour.White, PieceType.Rook, SquareFlag.G5.ToSquare(), new Models.Square(), 0, MoveType.Ordinary);
            var moveB = MoveBuilder.Create(Colour.White, PieceType.Rook, SquareFlag.G5.ToSquare(), new Models.Square(), 0, MoveType.Ordinary);

            Assert.Equal(moveA, moveB);
        }
Example #5
0
        public void Move_AreNotEqual()
        {
            var moveA = MoveBuilder.Create(Colour.White, 0, new Models.Square(), new Models.Square(), 0, MoveType.Ordinary);
            var moveB = MoveBuilder.Create(Colour.Black, 0, new Models.Square(), new Models.Square(), 0, MoveType.Ordinary);

            Assert.NotEqual(moveA, moveB);
        }
Example #6
0
        public void White_FourCaptures_OnePush_Correct()
        {
            var gameState = FenHelpers.Parse("K6k/8/8/8/8/p1p2p1p/1P4P1/8 w - -");

            var board = CreateBoard(gameState);

            var moves = new List <uint>(10);

            MoveGenerator.Generate(board, gameState.ToPlay, moves);

            var move1 = MoveBuilder.Create(Colour.White, PieceType.Pawn, SquareFlag.B2.ToSquare(), SquareFlag.B3.ToSquare(), PieceType.None, MoveType.Ordinary);
            var move2 = MoveBuilder.Create(Colour.White, PieceType.Pawn, SquareFlag.G2.ToSquare(), SquareFlag.G3.ToSquare(), PieceType.None, MoveType.Ordinary);

            var captures = moves.Where(x => x.GetCapturePieceType() != PieceType.None);

            var capture1 = MoveBuilder.Create(Colour.White, PieceType.Pawn, SquareFlag.B2.ToSquare(), SquareFlag.A3.ToSquare(), PieceType.Pawn, MoveType.Ordinary);
            var capture2 = MoveBuilder.Create(Colour.White, PieceType.Pawn, SquareFlag.B2.ToSquare(), SquareFlag.C3.ToSquare(), PieceType.Pawn, MoveType.Ordinary);
            var capture3 = MoveBuilder.Create(Colour.White, PieceType.Pawn, SquareFlag.G2.ToSquare(), SquareFlag.F3.ToSquare(), PieceType.Pawn, MoveType.Ordinary);
            var capture4 = MoveBuilder.Create(Colour.White, PieceType.Pawn, SquareFlag.G2.ToSquare(), SquareFlag.H3.ToSquare(), PieceType.Pawn, MoveType.Ordinary);

            Assert.Contains(move1, moves);
            Assert.Contains(move2, moves);

            Assert.Contains(capture1, moves);
            Assert.Contains(capture2, moves);
            Assert.Contains(capture3, moves);
            Assert.Contains(capture4, moves);
        }
Example #7
0
        public void Make_EnPassantOnlySetIfCapturePossible(string partialFen, SquareFlag enPassant)
        {
            var board = Create($"rnbqkbnr/pppp1ppp/8/{partialFen}/1P6/2PPPPPP/RNBQKBNR b KQkq -");

            var fromSquare = SquareFlag.D2;
            var toSquare   = SquareFlag.D4;

            var move = MoveBuilder.Create(Colour.White, PieceType.Pawn, fromSquare.ToSquare(), toSquare.ToSquare(), PieceType.None, MoveType.Ordinary);

            board.MakeMove(move);

            Assert.Equal(enPassant, board.EnPassant);
        }
Example #8
0
        public void DiscoverCheck(string fenString, SquareFlag fromSquare, SquareFlag toSquare)
        {
            var gameState = FenHelpers.Parse(fenString);

            var board = CreateBoard(gameState);

            var moves = new List <uint>(20);

            MoveGenerator.Generate(board, gameState.ToPlay, moves);

            var moveCount = moves.Count;

            var illegalMove = MoveBuilder.Create(Colour.White, PieceType.Pawn, fromSquare.ToSquare(), toSquare.ToSquare(), PieceType.None, MoveType.Ordinary);

            Assert.DoesNotContain(illegalMove, moves);
        }
Example #9
0
        public void White_DiscoveredCheck()
        {
            var gameState = FenHelpers.Parse("8/2b5/3P4/4K3/8/8/8/7k w - -");

            var board = CreateBoard(gameState);

            var moves = new List <uint>(10);

            MoveGenerator.Generate(board, gameState.ToPlay, moves);

            var illegalMove = MoveBuilder.Create(Colour.White, PieceType.Pawn, SquareFlag.D6.ToSquare(), SquareFlag.D7.ToSquare(), PieceType.None, MoveType.Ordinary);

            var movesView = moves.Select(x => new MoveViewer(x));

            Assert.DoesNotContain(illegalMove, moves);
        }
Example #10
0
        public void White_EnPassant_Capture_DiscoveredCheck()
        {
            var gameState = FenHelpers.Parse("8/8/8/q1rPp2K/8/7p/8/8 w - e6");

            var board = CreateBoard(gameState);

            var moves = new List <uint>(10);

            MoveGenerator.Generate(board, gameState.ToPlay, moves);

            var enPassantCapture = MoveBuilder.Create(Colour.White, PieceType.Pawn, SquareFlag.D6.ToSquare(), SquareFlag.E7.ToSquare(), PieceType.Pawn, MoveType.EnPassant);

            var movesView = moves.Select(x => new MoveViewer(x));

            Assert.DoesNotContain(enPassantCapture, moves);
        }
Example #11
0
        public void White_EnPassant_Capture()
        {
            var gameState = FenHelpers.Parse("K6k/8/8/3Pp3/8/8/8/8 w - e6");

            var board = CreateBoard(gameState);

            var moves = new List <uint>(10);

            MoveGenerator.Generate(board, gameState.ToPlay, moves);

            var enPassantCapture = MoveBuilder.Create(Colour.White, PieceType.Pawn, SquareFlag.D5.ToSquare(), SquareFlag.E6.ToSquare(), PieceType.Pawn, MoveType.EnPassant);

            var movesView = moves.Select(x => new MoveViewer(x));

            Assert.Contains(enPassantCapture, moves);
        }
Example #12
0
        public void White_Capture()
        {
            var gameState = FenHelpers.Parse("K6k/8/8/8/8/3p4/4P3/8 w - -");

            var board = CreateBoard(gameState);

            var moves = new List <uint>(10);

            MoveGenerator.Generate(board, gameState.ToPlay, moves);

            var capture = MoveBuilder.Create(Colour.White, PieceType.Pawn, SquareFlag.E2.ToSquare(), SquareFlag.D3.ToSquare(), PieceType.Pawn, MoveType.Ordinary);

            var movesView = moves.Select(x => new MoveViewer(x));

            Assert.Contains(capture, moves);
        }
Example #13
0
        public void Black_EightPawns_OneAndTwoPushes()
        {
            var gameState = FenHelpers.Parse("K6k/pppppppp/8/8/8/8/8/8 b - -");

            var board = CreateBoard(gameState);

            var moves = new List <uint>(10);

            MoveGenerator.Generate(board, gameState.ToPlay, moves);

            // Purely for debugging
            var pawnMoves = GetPawnMoveViews(moves);

            var moveA3 = MoveBuilder.Create(gameState.ToPlay, PieceType.Pawn, SquareFlag.A7.ToSquare(), SquareFlag.A6.ToSquare(), PieceType.None, MoveType.Ordinary);
            var moveA4 = MoveBuilder.Create(gameState.ToPlay, PieceType.Pawn, SquareFlag.A7.ToSquare(), SquareFlag.A5.ToSquare(), PieceType.None, MoveType.Ordinary);
            var moveB3 = MoveBuilder.Create(gameState.ToPlay, PieceType.Pawn, SquareFlag.B7.ToSquare(), SquareFlag.B6.ToSquare(), PieceType.None, MoveType.Ordinary);
            var moveB4 = MoveBuilder.Create(gameState.ToPlay, PieceType.Pawn, SquareFlag.B7.ToSquare(), SquareFlag.B5.ToSquare(), PieceType.None, MoveType.Ordinary);
            var moveC3 = MoveBuilder.Create(gameState.ToPlay, PieceType.Pawn, SquareFlag.C7.ToSquare(), SquareFlag.C6.ToSquare(), PieceType.None, MoveType.Ordinary);
            var moveC4 = MoveBuilder.Create(gameState.ToPlay, PieceType.Pawn, SquareFlag.C7.ToSquare(), SquareFlag.C5.ToSquare(), PieceType.None, MoveType.Ordinary);
            var moveD3 = MoveBuilder.Create(gameState.ToPlay, PieceType.Pawn, SquareFlag.D7.ToSquare(), SquareFlag.D6.ToSquare(), PieceType.None, MoveType.Ordinary);
            var moveD4 = MoveBuilder.Create(gameState.ToPlay, PieceType.Pawn, SquareFlag.D7.ToSquare(), SquareFlag.D5.ToSquare(), PieceType.None, MoveType.Ordinary);
            var moveE3 = MoveBuilder.Create(gameState.ToPlay, PieceType.Pawn, SquareFlag.E7.ToSquare(), SquareFlag.E6.ToSquare(), PieceType.None, MoveType.Ordinary);
            var moveE4 = MoveBuilder.Create(gameState.ToPlay, PieceType.Pawn, SquareFlag.E7.ToSquare(), SquareFlag.E5.ToSquare(), PieceType.None, MoveType.Ordinary);
            var moveF3 = MoveBuilder.Create(gameState.ToPlay, PieceType.Pawn, SquareFlag.F7.ToSquare(), SquareFlag.F6.ToSquare(), PieceType.None, MoveType.Ordinary);
            var moveF4 = MoveBuilder.Create(gameState.ToPlay, PieceType.Pawn, SquareFlag.F7.ToSquare(), SquareFlag.F5.ToSquare(), PieceType.None, MoveType.Ordinary);
            var moveG3 = MoveBuilder.Create(gameState.ToPlay, PieceType.Pawn, SquareFlag.G7.ToSquare(), SquareFlag.G6.ToSquare(), PieceType.None, MoveType.Ordinary);
            var moveG4 = MoveBuilder.Create(gameState.ToPlay, PieceType.Pawn, SquareFlag.G7.ToSquare(), SquareFlag.G5.ToSquare(), PieceType.None, MoveType.Ordinary);
            var moveH3 = MoveBuilder.Create(gameState.ToPlay, PieceType.Pawn, SquareFlag.H7.ToSquare(), SquareFlag.H6.ToSquare(), PieceType.None, MoveType.Ordinary);
            var moveH4 = MoveBuilder.Create(gameState.ToPlay, PieceType.Pawn, SquareFlag.H7.ToSquare(), SquareFlag.H5.ToSquare(), PieceType.None, MoveType.Ordinary);

            Assert.Contains(moveA3, moves);
            Assert.Contains(moveA4, moves);
            Assert.Contains(moveB3, moves);
            Assert.Contains(moveB4, moves);
            Assert.Contains(moveC3, moves);
            Assert.Contains(moveC4, moves);
            Assert.Contains(moveD3, moves);
            Assert.Contains(moveD4, moves);
            Assert.Contains(moveE3, moves);
            Assert.Contains(moveE4, moves);
            Assert.Contains(moveF3, moves);
            Assert.Contains(moveF4, moves);
            Assert.Contains(moveG3, moves);
            Assert.Contains(moveG4, moves);
            Assert.Contains(moveH3, moves);
            Assert.Contains(moveH4, moves);
        }
Example #14
0
        public void Make_UnMake_Correct1()
        {
            var board = Create("rnbqkbnr/pppp1ppp/8/8/P3p3/1P6/2PPPPPP/RNBQKBNR b KQkq -");

            var fromSquare = SquareFlag.D2;
            var toSquare   = SquareFlag.D4;

            var move = MoveBuilder.Create(Colour.White, PieceType.Pawn, fromSquare.ToSquare(), toSquare.ToSquare(), PieceType.None, MoveType.Ordinary);

            board.MakeMove(move);

            Assert.Equal(SquareFlag.D3, board.EnPassant);

            board.UnMakeMove(move);

            Assert.Equal((SquareFlag)0, board.EnPassant);
        }
Example #15
0
        public void White_EightPawns_OneAndTwoPushes()
        {
            var gameState = FenHelpers.Parse("K6k/8/8/8/8/8/PPPPPPPP/8 w - -");

            var board = CreateBoard(gameState);

            var moves = new List <uint>(10);

            MoveGenerator.Generate(board, gameState.ToPlay, moves);

            var pawnMoves = GetPawnMoveViews(moves);

            var moveA3 = MoveBuilder.Create(gameState.ToPlay, PieceType.Pawn, SquareFlag.A2.ToSquare(), SquareFlag.A3.ToSquare(), PieceType.None, MoveType.Ordinary);
            var moveA4 = MoveBuilder.Create(gameState.ToPlay, PieceType.Pawn, SquareFlag.A2.ToSquare(), SquareFlag.A4.ToSquare(), PieceType.None, MoveType.Ordinary);
            var moveB3 = MoveBuilder.Create(gameState.ToPlay, PieceType.Pawn, SquareFlag.B2.ToSquare(), SquareFlag.B3.ToSquare(), PieceType.None, MoveType.Ordinary);
            var moveB4 = MoveBuilder.Create(gameState.ToPlay, PieceType.Pawn, SquareFlag.B2.ToSquare(), SquareFlag.B4.ToSquare(), PieceType.None, MoveType.Ordinary);
            var moveC3 = MoveBuilder.Create(gameState.ToPlay, PieceType.Pawn, SquareFlag.C2.ToSquare(), SquareFlag.C3.ToSquare(), PieceType.None, MoveType.Ordinary);
            var moveC4 = MoveBuilder.Create(gameState.ToPlay, PieceType.Pawn, SquareFlag.C2.ToSquare(), SquareFlag.C4.ToSquare(), PieceType.None, MoveType.Ordinary);
            var moveD3 = MoveBuilder.Create(gameState.ToPlay, PieceType.Pawn, SquareFlag.D2.ToSquare(), SquareFlag.D3.ToSquare(), PieceType.None, MoveType.Ordinary);
            var moveD4 = MoveBuilder.Create(gameState.ToPlay, PieceType.Pawn, SquareFlag.D2.ToSquare(), SquareFlag.D4.ToSquare(), PieceType.None, MoveType.Ordinary);
            var moveE3 = MoveBuilder.Create(gameState.ToPlay, PieceType.Pawn, SquareFlag.E2.ToSquare(), SquareFlag.E3.ToSquare(), PieceType.None, MoveType.Ordinary);
            var moveE4 = MoveBuilder.Create(gameState.ToPlay, PieceType.Pawn, SquareFlag.E2.ToSquare(), SquareFlag.E4.ToSquare(), PieceType.None, MoveType.Ordinary);
            var moveF3 = MoveBuilder.Create(gameState.ToPlay, PieceType.Pawn, SquareFlag.F2.ToSquare(), SquareFlag.F3.ToSquare(), PieceType.None, MoveType.Ordinary);
            var moveF4 = MoveBuilder.Create(gameState.ToPlay, PieceType.Pawn, SquareFlag.F2.ToSquare(), SquareFlag.F4.ToSquare(), PieceType.None, MoveType.Ordinary);
            var moveG3 = MoveBuilder.Create(gameState.ToPlay, PieceType.Pawn, SquareFlag.G2.ToSquare(), SquareFlag.G3.ToSquare(), PieceType.None, MoveType.Ordinary);
            var moveG4 = MoveBuilder.Create(gameState.ToPlay, PieceType.Pawn, SquareFlag.G2.ToSquare(), SquareFlag.G4.ToSquare(), PieceType.None, MoveType.Ordinary);
            var moveH3 = MoveBuilder.Create(gameState.ToPlay, PieceType.Pawn, SquareFlag.H2.ToSquare(), SquareFlag.H3.ToSquare(), PieceType.None, MoveType.Ordinary);
            var moveH4 = MoveBuilder.Create(gameState.ToPlay, PieceType.Pawn, SquareFlag.H2.ToSquare(), SquareFlag.H4.ToSquare(), PieceType.None, MoveType.Ordinary);

            Assert.Contains(moveA3, moves);
            Assert.Contains(moveA4, moves);
            Assert.Contains(moveB3, moves);
            Assert.Contains(moveB4, moves);
            Assert.Contains(moveC3, moves);
            Assert.Contains(moveC4, moves);
            Assert.Contains(moveD3, moves);
            Assert.Contains(moveD4, moves);
            Assert.Contains(moveE3, moves);
            Assert.Contains(moveE4, moves);
            Assert.Contains(moveF3, moves);
            Assert.Contains(moveF4, moves);
            Assert.Contains(moveG3, moves);
            Assert.Contains(moveG4, moves);
            Assert.Contains(moveH3, moves);
            Assert.Contains(moveH4, moves);
        }
Example #16
0
 private void AddPromotions(MoveGenerationWorkspace workspace, Square fromSquare, Square toSquare, PieceType capturePieceType)
 {
     if (capturePieceType != PieceType.None)
     {
         workspace.CaptureMoveBuffer.Add(MoveBuilder.Create(workspace.Colour, PieceType.Pawn, fromSquare, toSquare, capturePieceType, MoveType.PromotionQueen, workspace.NumCheckers));
         workspace.CaptureMoveBuffer.Add(MoveBuilder.Create(workspace.Colour, PieceType.Pawn, fromSquare, toSquare, capturePieceType, MoveType.PromotionRook, workspace.NumCheckers));
         workspace.CaptureMoveBuffer.Add(MoveBuilder.Create(workspace.Colour, PieceType.Pawn, fromSquare, toSquare, capturePieceType, MoveType.PromotionKnight, workspace.NumCheckers));
         workspace.CaptureMoveBuffer.Add(MoveBuilder.Create(workspace.Colour, PieceType.Pawn, fromSquare, toSquare, capturePieceType, MoveType.PromotionBishop, workspace.NumCheckers));
     }
     else
     {
         workspace.NonCaptureMoveBuffer.Add(MoveBuilder.Create(workspace.Colour, PieceType.Pawn, fromSquare, toSquare, capturePieceType, MoveType.PromotionQueen, workspace.NumCheckers));
         workspace.NonCaptureMoveBuffer.Add(MoveBuilder.Create(workspace.Colour, PieceType.Pawn, fromSquare, toSquare, capturePieceType, MoveType.PromotionRook, workspace.NumCheckers));
         workspace.NonCaptureMoveBuffer.Add(MoveBuilder.Create(workspace.Colour, PieceType.Pawn, fromSquare, toSquare, capturePieceType, MoveType.PromotionKnight, workspace.NumCheckers));
         workspace.NonCaptureMoveBuffer.Add(MoveBuilder.Create(workspace.Colour, PieceType.Pawn, fromSquare, toSquare, capturePieceType, MoveType.PromotionBishop, workspace.NumCheckers));
     }
 }
Example #17
0
        public void Move_Constructor_AccessTwice_NoChange()
        {
            var move = MoveBuilder.Create(Colour.White, PieceType.Knight, SquareFlag.D5.ToSquare(), SquareFlag.E7.ToSquare(), PieceType.Pawn, MoveType.CastleKing, 2);

            Assert.Equal(Colour.White, move.GetColour());
            Assert.Equal(Colour.White, move.GetColour());
            Assert.Equal(PieceType.Knight, move.GetPieceType());
            Assert.Equal(PieceType.Knight, move.GetPieceType());
            Assert.Equal(SquareFlag.D5, move.GetFrom());
            Assert.Equal(SquareFlag.D5, move.GetFrom());
            Assert.Equal(SquareFlag.E7, move.GetTo());
            Assert.Equal(SquareFlag.E7, move.GetTo());
            Assert.Equal(PieceType.Pawn, move.GetCapturePieceType());
            Assert.Equal(PieceType.Pawn, move.GetCapturePieceType());
            Assert.Equal(MoveType.CastleKing, move.GetMoveType());
            Assert.Equal(MoveType.CastleKing, move.GetMoveType());
            Assert.Equal(2, move.GetNumCheckers());
        }
Example #18
0
        private void ToOrdinaryMoves(MoveGenerationWorkspace workspace, PieceType pieceType, Square fromSquare, SquareFlag attackableSquares)
        {
            var attackableSquaresAsList = attackableSquares.ToList();

            foreach (var toSquare in attackableSquaresAsList)
            {
                if (!workspace.RelativeBitBoard.OpponentSquares.HasFlag(toSquare))
                {
                    workspace.NonCaptureMoveBuffer.Add(MoveBuilder.Create(workspace.Colour, pieceType, fromSquare, toSquare.ToSquare(), PieceType.None, MoveType.Ordinary, workspace.NumCheckers));

                    continue;
                }

                var capturePieceType = workspace.RelativeBitBoard.GetPieceType(toSquare);

                workspace.CaptureMoveBuffer.Add(MoveBuilder.Create(workspace.Colour, pieceType, fromSquare, toSquare.ToSquare(), capturePieceType, MoveType.Ordinary, workspace.NumCheckers));
            }
        }
Example #19
0
        private void AddIndividualPawnPushes(MoveGenerationWorkspace workspace, Square fromSquare, SquareFlag pushMask)
        {
            var relativeBitBoard = workspace.RelativeBitBoard;

            var toSquare = fromSquare.Flag
                           .PawnForward(relativeBitBoard.Colour, 1)
                           .ToSquare();

            if (relativeBitBoard.OccupiedSquares.HasFlag(toSquare.Flag))
            {
                return;
            }

            if (pushMask.HasFlag(toSquare.Flag))
            {
                if (relativeBitBoard.PromotionRank.HasFlag(toSquare.Flag))
                {
                    AddPromotions(workspace, fromSquare, toSquare, PieceType.None);
                }
                else
                {
                    workspace.NonCaptureMoveBuffer.Add(MoveBuilder.Create(relativeBitBoard.Colour, PieceType.Pawn, fromSquare, toSquare, PieceType.None, MoveType.Ordinary, workspace.NumCheckers));
                }
            }

            // Possible that we can block check with double push
            if (relativeBitBoard.StartRank.HasFlag(fromSquare.Flag))
            {
                toSquare = fromSquare.Flag
                           .PawnForward(relativeBitBoard.Colour, 2)
                           .ToSquare();

                if (!pushMask.HasFlag(toSquare.Flag))
                {
                    return;
                }

                // Promotions not possible from start rank
                if (!relativeBitBoard.OccupiedSquares.HasFlag(toSquare.Flag))
                {
                    workspace.NonCaptureMoveBuffer.Add(MoveBuilder.Create(relativeBitBoard.Colour, PieceType.Pawn, fromSquare, toSquare, PieceType.None, MoveType.Ordinary, workspace.NumCheckers));
                }
            }
        }
Example #20
0
        public void Board_MakeUnMake_WhiteCaptureCorrectKeys()
        {
            var board = CreateBitBoard("K6k/8/8/8/8/3p4/4P3/8 w - -");

            var rootKey = KeyGenerator.Hash(board, Colour.White);

            var capture = MoveBuilder.Create(Colour.White, PieceType.Pawn, SquareFlag.E2.ToSquare(), SquareFlag.D3.ToSquare(), PieceType.Pawn, MoveType.Ordinary);

            var beforeKey = board.Key;

            board.MakeMove(capture);

            var afterKey = board.Key;

            board.UnMakeMove(capture);

            Assert.NotEqual(beforeKey, afterKey);
            Assert.Equal(beforeKey, board.Key);
        }
Example #21
0
        public void Make_UnMake_KnightCaptures_Correct()
        {
            var board          = Create("7k/8/3p4/8/4N3/8/8/K7 w - - 0 1");
            var boardReference = Create("7k/8/3p4/8/4N3/8/8/K7 w - - 0 1");
            var boardAfterMake = Create("7k/8/3N4/8/8/8/8/K7 w - - 0 1");

            var fromSquare = SquareFlag.E4;
            var toSquare   = SquareFlag.D6;

            var move = MoveBuilder.Create(Colour.White, PieceType.Knight, fromSquare.ToSquare(), toSquare.ToSquare(), PieceType.Pawn, MoveType.Ordinary);

            board.MakeMove(move);

            TestHelpers.AssertEqual(board, boardAfterMake);

            board.UnMakeMove(move);

            TestHelpers.AssertEqual(board, boardReference);
        }
Example #22
0
        public void E4_UnblockedCapture(string fenString, SquareFlag captureSquare, int expectedQueenMoveCount)
        {
            var gameState = FenHelpers.Parse(fenString);

            var board = CreateBoard(fenString);

            var moves = new List <uint>(10);

            MoveGenerator.Generate(board, gameState.ToPlay, moves);

            var queenMoves = GetQueenMoveViews(moves);

            var captures = GetCaptureMoveViews(moves);

            var capture1 = MoveBuilder.Create(gameState.ToPlay, PieceType.Queen, SquareFlag.E4.ToSquare(), captureSquare.ToSquare(), PieceType.Pawn, MoveType.Ordinary);

            Assert.Equal(expectedQueenMoveCount, queenMoves.Count);
            Assert.Contains(capture1, captures.Select(x => x.Value));
        }
Example #23
0
        public void EvadesCheckByRook(string fenString, int expectedMovesCount, SquareFlag toSquare)
        {
            var gameState = FenHelpers.Parse(fenString);

            var board = CreateBoard(gameState);

            var moves = new List <uint>(20);

            MoveGenerator.Generate(board, gameState.ToPlay, moves);

            var kingMoves = GetKingMoveViews(moves);

            var captureViews = GetCaptureMoveViews(moves);

            var capture1 = MoveBuilder.Create(gameState.ToPlay, PieceType.King, SquareFlag.E4.ToSquare(), toSquare.ToSquare(), PieceType.Rook, MoveType.Ordinary, 1);

            Assert.Equal(expectedMovesCount, kingMoves.Count());

            Assert.Contains(capture1, captureViews.Select(x => x.Value));
        }
Example #24
0
        public void White_Capture_OneCapture_Promotion_Correct()
        {
            var gameState = FenHelpers.Parse("3nn3/3P4/8/8/8/8/8/K6k w - -");

            var board = CreateBoard(gameState);

            var moves = new List <uint>(10);

            MoveGenerator.Generate(board, gameState.ToPlay, moves);

            var promotion1 = MoveBuilder.Create(Colour.White, PieceType.Pawn, SquareFlag.D7.ToSquare(), SquareFlag.E8.ToSquare(), PieceType.Knight, MoveType.PromotionQueen);
            var promotion2 = MoveBuilder.Create(Colour.White, PieceType.Pawn, SquareFlag.D7.ToSquare(), SquareFlag.E8.ToSquare(), PieceType.Knight, MoveType.PromotionRook);
            var promotion3 = MoveBuilder.Create(Colour.White, PieceType.Pawn, SquareFlag.D7.ToSquare(), SquareFlag.E8.ToSquare(), PieceType.Knight, MoveType.PromotionBishop);
            var promotion4 = MoveBuilder.Create(Colour.White, PieceType.Pawn, SquareFlag.D7.ToSquare(), SquareFlag.E8.ToSquare(), PieceType.Knight, MoveType.PromotionKnight);

            Assert.Contains(promotion1, moves);
            Assert.Contains(promotion2, moves);
            Assert.Contains(promotion3, moves);
            Assert.Contains(promotion4, moves);
        }
Example #25
0
        public void Make_Capture_BlackRookRemovesRights()
        {
            var board          = Create("r3k2r/8/8/8/8/8/8/R3K2R w KQkq - 0 1");
            var boardReference = Create("r3k2r/8/8/8/8/8/8/R3K2R w KQkq - 0 1");

            var fromSquare = SquareFlag.A1;
            var toSquare   = SquareFlag.A8;

            var move = MoveBuilder.Create(Colour.White, PieceType.Rook, fromSquare.ToSquare(), toSquare.ToSquare(), PieceType.Rook, MoveType.Ordinary);

            board.MakeMove(move);

            Assert.True(board.WhiteCanCastleKingSide);
            Assert.False(board.WhiteCanCastleQueenSide);
            Assert.True(board.BlackCanCastleKingSide);
            Assert.False(board.BlackCanCastleQueenSide);

            board.UnMakeMove(move);

            TestHelpers.AssertEqual(board, boardReference);
        }
Example #26
0
        public void Make_BlackStandardKingMoveRemovesRights()
        {
            var board          = Create("r3k2r/8/8/8/8/8/8/R3K2R w KQkq -");
            var boardReference = Create("r3k2r/8/8/8/8/8/8/R3K2R w KQkq -");

            var fromSquare = SquareFlag.E8;
            var toSquare   = SquareFlag.E7;

            var move = MoveBuilder.Create(Colour.Black, PieceType.King, fromSquare.ToSquare(), toSquare.ToSquare(), PieceType.None, MoveType.Ordinary);

            board.MakeMove(move);

            Assert.True(board.WhiteCanCastleKingSide);
            Assert.True(board.WhiteCanCastleQueenSide);
            Assert.False(board.BlackCanCastleKingSide);
            Assert.False(board.BlackCanCastleQueenSide);

            board.UnMakeMove(move);

            TestHelpers.AssertEqual(board, boardReference);
        }
Example #27
0
        public void Make_UnMake_EnPassant_Correct()
        {
            var board = Create("4k3/8/8/8/5Pp1/8/8/4K3 w - f3 0 1");

            var boardReference = Create("4k3/8/8/8/5Pp1/8/8/4K3 w - f3 0 1");

            var fromSquare = SquareFlag.G4;
            var toSquare   = SquareFlag.F3;

            var move = MoveBuilder.Create(Colour.Black, PieceType.Pawn, fromSquare.ToSquare(), toSquare.ToSquare(), PieceType.Pawn, MoveType.EnPassant);

            board.MakeMove(move);

            Assert.NotEqual(board.White, boardReference.White);
            Assert.NotEqual(board.Black, boardReference.Black);
            Assert.NotEqual(board.EnPassant, boardReference.EnPassant);

            board.UnMakeMove(move);

            TestHelpers.AssertEqual(board, boardReference);
        }
Example #28
0
        public void Black_OneCapture_Promotion_Correct()
        {
            var gameState = FenHelpers.Parse("4k3/8/8/8/8/8/1p6/R2QK3 b - -");

            var board = CreateBoard(gameState);

            var moves = new List <uint>(10);

            MoveGenerator.Generate(board, gameState.ToPlay, moves);

            var promotion1 = MoveBuilder.Create(Colour.Black, PieceType.Pawn, SquareFlag.B2.ToSquare(), SquareFlag.A1.ToSquare(), PieceType.Rook, MoveType.PromotionQueen);
            var promotion2 = MoveBuilder.Create(Colour.Black, PieceType.Pawn, SquareFlag.B2.ToSquare(), SquareFlag.A1.ToSquare(), PieceType.Rook, MoveType.PromotionRook);
            var promotion3 = MoveBuilder.Create(Colour.Black, PieceType.Pawn, SquareFlag.B2.ToSquare(), SquareFlag.A1.ToSquare(), PieceType.Rook, MoveType.PromotionBishop);
            var promotion4 = MoveBuilder.Create(Colour.Black, PieceType.Pawn, SquareFlag.B2.ToSquare(), SquareFlag.A1.ToSquare(), PieceType.Rook, MoveType.PromotionKnight);

            var pawnMoves = GetPawnMoveViews(moves);

            Assert.Contains(promotion1, moves);
            Assert.Contains(promotion2, moves);
            Assert.Contains(promotion3, moves);
            Assert.Contains(promotion4, moves);
        }
Example #29
0
        public void Board_MakeUnMake_CastleKeysCorrect()
        {
            var board = CreateBitBoard("r3k2r/8/8/8/8/8/8/R3K2R w KQkq - 0 1");

            var rootKey = KeyGenerator.Hash(board, Colour.White);

            var castle = MoveBuilder.Create(
                Colour.White,
                PieceType.King,
                SquareFlagConstants.WhiteKingStartSquare.ToSquare(),
                SquareFlagConstants.WhiteKingSideRookStartSquare.ToSquare(),
                PieceType.None,
                MoveType.CastleKing);

            var beforeKey = board.Key;

            board.MakeMove(castle);

            var hashKey   = KeyGenerator.Hash(board, Colour.Black);
            var updateKey = KeyGenerator.UpdateHash(rootKey, castle);

            Assert.Equal(hashKey, board.Key);
            Assert.Equal(updateKey, board.Key);

            var afterKey = board.Key;

            board.UnMakeMove(castle);

            var hashKey2   = KeyGenerator.Hash(board, Colour.White);
            var updateKey2 = KeyGenerator.UpdateHash(updateKey, castle);

            Assert.Equal(hashKey2, board.Key);
            Assert.Equal(updateKey2, board.Key);

            Assert.NotEqual(beforeKey, afterKey);
            Assert.Equal(beforeKey, board.Key);
        }
Example #30
0
        private void AddIndividualPawnCaptures(MoveGenerationWorkspace workspace, Square fromSquare, SquareFlag pushMask, SquareFlag captureMask)
        {
            var relativeBitBoard = workspace.RelativeBitBoard;

            var captureSquares = relativeBitBoard.Colour == Colour.White
                ? AttackBitmaps.PawnCapturesWhite[fromSquare.Index].ToList()
                : AttackBitmaps.PawnCapturesBlack[fromSquare.Index].ToList();

            foreach (var toSquare in captureSquares)
            {
                var moveType = relativeBitBoard.EnPassant.HasFlag(toSquare) ? MoveType.EnPassant : MoveType.Ordinary;

                if (relativeBitBoard.OpponentSquares.HasFlag(toSquare) || moveType == MoveType.EnPassant)
                {
                    var capturePieceType = relativeBitBoard.GetPieceType(toSquare);

                    var discoveredCheck = false;

                    if (moveType != MoveType.EnPassant)
                    {
                        if (!captureMask.HasFlag(toSquare))
                        {
                            continue;
                        }
                    }
                    else
                    {
                        // Abuse the push system - push an imaginary pawn from the en passant square as opponent to find piece
                        var enPassantCaptureSquare = relativeBitBoard.EnPassant.PawnForward(relativeBitBoard.OpponentColour, 1);

                        var blockWithPush = pushMask.HasFlag(relativeBitBoard.EnPassant);

                        var evadeWithCapture = captureMask.HasFlag(enPassantCaptureSquare);

                        if (!blockWithPush && !evadeWithCapture)
                        {
                            continue;
                        }

                        capturePieceType = PieceType.Pawn;

                        // Looking for DISCOVERED CHECK (not spotted by pinned pieces as there are 2 pawns in the way)
                        // Slight duplication here but probably cleaner than passing in
                        var kingSquare = relativeBitBoard.MyKing.ToSquare();

                        var enPassantDiscoveredCheckRank = relativeBitBoard.EnPassantDiscoveredCheckRank;

                        // This should be super rare. Performing an en passant capture with our King on same rank.
                        if (enPassantDiscoveredCheckRank.HasFlag(kingSquare.Flag))
                        {
                            if ((enPassantDiscoveredCheckRank & relativeBitBoard.OpponentRooks) > 0 ||
                                (enPassantDiscoveredCheckRank & relativeBitBoard.OpponentQueens) > 0)
                            {
                                var occupancyMask = MagicNumbers.RookOccupancyMasks[kingSquare.Index];

                                var occupancyBeforeCapture = relativeBitBoard.OccupiedSquares & occupancyMask;

                                var occupancyAfterCapture = occupancyBeforeCapture
                                                            & ~enPassantCaptureSquare
                                                            & ~fromSquare.Flag;

                                // Search for magic moves using just the occupancy of rank (the rest is not relevant)
                                var magicIndex = MagicIndexHelpers.GetMagicIndex(PieceType.Rook, kingSquare.Index, occupancyAfterCapture);

                                var kingRayAttacks = AttackBitmaps.RookAttacks[kingSquare.Index][magicIndex];

                                var kingRayAttacksOnRank = kingRayAttacks & enPassantDiscoveredCheckRank;

                                discoveredCheck = (kingRayAttacksOnRank & relativeBitBoard.OpponentRooks) > 0 ||
                                                  (kingRayAttacksOnRank & relativeBitBoard.OpponentQueens) > 0;
                            }
                        }
                    }

                    if (relativeBitBoard.PromotionRank.HasFlag(toSquare))
                    {
                        AddPromotions(workspace, fromSquare, toSquare.ToSquare(), capturePieceType);
                    }
                    else if (!discoveredCheck)
                    {
                        if (capturePieceType != PieceType.None)
                        {
                            workspace.CaptureMoveBuffer.Add(MoveBuilder.Create(workspace.Colour, PieceType.Pawn, fromSquare, toSquare.ToSquare(), capturePieceType, moveType, workspace.NumCheckers));
                        }
                        else
                        {
                            workspace.NonCaptureMoveBuffer.Add(MoveBuilder.Create(workspace.Colour, PieceType.Pawn, fromSquare, toSquare.ToSquare(), capturePieceType, moveType, workspace.NumCheckers));
                        }
                    }
                }
            }
        }