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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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)); } }
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()); }
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)); } }
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)); } } }
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); }
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); }
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)); }
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)); }
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); }
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); }
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); }
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); }
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); }
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); }
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)); } } } } }