public void PlacePiece(Piece piece) { Debug.Log(board); board.PlacePiece(piece); StrategyGame.Instance.Pieces.Add(piece); MoveGeneration.GenerateMoves(StrategyGame.Instance.Pieces); }
public void GenerateMoves(MoveGeneration MoveGeneration, ulong FromSquareMask, ulong ToSquareMask) { GeneratePawnMoves(MoveGeneration, FromSquareMask, ToSquareMask); GenerateKnightMoves(MoveGeneration, FromSquareMask, ToSquareMask); GenerateBishopMoves(MoveGeneration, FromSquareMask, ToSquareMask); GenerateRookMoves(MoveGeneration, FromSquareMask, ToSquareMask); GenerateQueenMoves(MoveGeneration, FromSquareMask, ToSquareMask); GenerateKingMoves(MoveGeneration, FromSquareMask, ToSquareMask); }
private void GenerateQueenMoves(MoveGeneration MoveGeneration, ulong FromSquareMask, ulong ToSquareMask) { ulong queens; ulong unOrEnemyOccupiedSquares; ulong enemyOccupiedSquares; int attacker; if (WhiteMove) { // White Move queens = WhiteQueens & FromSquareMask; unOrEnemyOccupiedSquares = ~OccupancyWhite; enemyOccupiedSquares = OccupancyBlack; attacker = Piece.WhiteQueen; } else { // Black Move queens = BlackQueens & FromSquareMask; unOrEnemyOccupiedSquares = ~OccupancyBlack; enemyOccupiedSquares = OccupancyWhite; attacker = Piece.BlackQueen; } int fromSquare; while ((fromSquare = Bitwise.FindFirstSetBit(queens)) != Square.Illegal) { var bishopOccupancy = Board.BishopMoveMasks[fromSquare] & Occupancy; var rookOccupancy = Board.RookMoveMasks[fromSquare] & Occupancy; var queenDestinations = MoveGeneration switch { MoveGeneration.AllMoves => (Board.PrecalculatedMoves.GetBishopMovesMask(fromSquare, bishopOccupancy) | Board.PrecalculatedMoves.GetRookMovesMask(fromSquare, rookOccupancy)) & unOrEnemyOccupiedSquares & ToSquareMask, MoveGeneration.OnlyCaptures => (Board.PrecalculatedMoves.GetBishopMovesMask(fromSquare, bishopOccupancy) | Board.PrecalculatedMoves.GetRookMovesMask(fromSquare, rookOccupancy)) & enemyOccupiedSquares & ToSquareMask, MoveGeneration.OnlyNonCaptures => (Board.PrecalculatedMoves.GetBishopMovesMask(fromSquare, bishopOccupancy) | Board.PrecalculatedMoves.GetRookMovesMask(fromSquare, rookOccupancy)) & ~Occupancy & ToSquareMask, _ => throw new Exception($"{MoveGeneration} move generation not supported.") }; int toSquare; while ((toSquare = Bitwise.FindFirstSetBit(queenDestinations)) != Square.Illegal) { var victim = GetPiece(toSquare); var move = Move.Null; Move.SetFrom(ref move, fromSquare); Move.SetTo(ref move, toSquare); if (victim != Piece.None) { Move.SetCaptureAttacker(ref move, attacker); } Move.SetCaptureVictim(ref move, victim); Move.SetIsQuiet(ref move, victim == Piece.None); Moves[MoveIndex] = move; MoveIndex++; Bitwise.ClearBit(ref queenDestinations, toSquare); } Bitwise.ClearBit(ref queens, fromSquare); } }
private void GenerateKnightMoves(MoveGeneration MoveGeneration, ulong FromSquareMask, ulong ToSquareMask) { ulong knights; ulong unOrEnemyOccupiedSquares; ulong enemyOccupiedSquares; int attacker; if (WhiteMove) { // White Move knights = WhiteKnights & FromSquareMask; unOrEnemyOccupiedSquares = ~OccupancyWhite; enemyOccupiedSquares = OccupancyBlack; attacker = Piece.WhiteKnight; } else { // Black Move knights = BlackKnights & FromSquareMask; unOrEnemyOccupiedSquares = ~OccupancyBlack; enemyOccupiedSquares = OccupancyWhite; attacker = Piece.BlackKnight; } int fromSquare; while ((fromSquare = Bitwise.FindFirstSetBit(knights)) != Square.Illegal) { var knightDestinations = MoveGeneration switch { MoveGeneration.AllMoves => Board.KnightMoveMasks[fromSquare] & unOrEnemyOccupiedSquares & ToSquareMask, MoveGeneration.OnlyCaptures => Board.KnightMoveMasks[fromSquare] & enemyOccupiedSquares & ToSquareMask, MoveGeneration.OnlyNonCaptures => Board.KnightMoveMasks[fromSquare] & ~Occupancy & ToSquareMask, _ => throw new Exception($"{MoveGeneration} move generation not supported.") }; int toSquare; while ((toSquare = Bitwise.FindFirstSetBit(knightDestinations)) != Square.Illegal) { var victim = GetPiece(toSquare); var move = Move.Null; Move.SetFrom(ref move, fromSquare); Move.SetTo(ref move, toSquare); if (victim != Piece.None) { Move.SetCaptureAttacker(ref move, attacker); } Move.SetCaptureVictim(ref move, victim); Move.SetIsQuiet(ref move, victim == Piece.None); Moves[MoveIndex] = move; MoveIndex++; Bitwise.ClearBit(ref knightDestinations, toSquare); } Bitwise.ClearBit(ref knights, fromSquare); } }
private void GeneratePieceMoves(MoveGeneration moveGeneration, ulong fromSquareMask, ulong toSquareMask) { for (var colorlessPiece = ColorlessPiece.Knight; colorlessPiece <= ColorlessPiece.Queen; colorlessPiece++) { var attacker = PieceHelper.GetPieceOfColor(colorlessPiece, ColorToMove); var pieces = PieceBitboards[(int)attacker] & fromSquareMask; if (pieces == 0) { continue; } var getPieceMovesMask = Board.PieceMoveMaskDelegates[(int)colorlessPiece]; var unOrEnemyOccupiedSquares = ~ColorOccupancy[(int)ColorToMove]; var enemyOccupiedSquares = ColorOccupancy[(int)ColorLastMoved]; Square fromSquare; while ((fromSquare = Bitwise.PopFirstSetSquare(ref pieces)) != Square.Illegal) { var pieceDestinations = moveGeneration switch { MoveGeneration.AllMoves => getPieceMovesMask(fromSquare, Occupancy) & unOrEnemyOccupiedSquares & toSquareMask, MoveGeneration.OnlyCaptures => getPieceMovesMask(fromSquare, Occupancy) & enemyOccupiedSquares & toSquareMask, MoveGeneration.OnlyNonCaptures => getPieceMovesMask(fromSquare, Occupancy) & ~Occupancy & toSquareMask, _ => throw new Exception($"{moveGeneration} move generation not supported.") }; Square toSquare; while ((toSquare = Bitwise.PopFirstSetSquare(ref pieceDestinations)) != Square.Illegal) { var victim = GetPiece(toSquare); var move = Move.Null; Move.SetPiece(ref move, attacker); Move.SetFrom(ref move, fromSquare); Move.SetTo(ref move, toSquare); if (victim != Piece.None) { Move.SetCaptureAttacker(ref move, attacker); } Move.SetCaptureVictim(ref move, victim); Moves[MoveIndex] = move; MoveIndex++; } } } }
public void MovePiece(Move move) { // Check if this is going to trigger a capture if (move.Capture) { // A capture event occurs and we switch over to the Action phase MasterGame.Instance.CaptureAttempted.Invoke(move); } else { board.MovePiece(move); MoveGeneration.GenerateMoves(StrategyGame.Instance.Pieces); Debug.Log("================== Moves Generated =================="); Debug.Log("Moves:"); foreach (var m in StrategyGame.Instance.Pieces[2].Moves) { Debug.Log("Move: " + m.From + " - " + m.To); } } }
private void GenerateKingMoves(MoveGeneration MoveGeneration, ulong FromSquareMask, ulong ToSquareMask) { ulong king; ulong unOrEnemyOccupiedSquares; ulong enemyOccupiedSquares; int attacker; bool castleQueenside; ulong castleQueensideMask; bool castleKingside; ulong castleKingsideMask; if (WhiteMove) { // White Move king = WhiteKing & FromSquareMask; unOrEnemyOccupiedSquares = ~OccupancyWhite; enemyOccupiedSquares = OccupancyBlack; attacker = Piece.WhiteKing; castleQueenside = Engine.Castling.WhiteQueenside(Castling); castleQueensideMask = Board.WhiteCastleQEmptySquaresMask; castleKingside = Engine.Castling.WhiteKingside(Castling); castleKingsideMask = Board.WhiteCastleKEmptySquaresMask; } else { // Black Move king = BlackKing & FromSquareMask; unOrEnemyOccupiedSquares = ~OccupancyBlack; enemyOccupiedSquares = OccupancyWhite; attacker = Piece.BlackKing; castleQueenside = Engine.Castling.BlackQueenside(Castling); castleQueensideMask = Board.BlackCastleQEmptySquaresMask; castleKingside = Engine.Castling.BlackKingside(Castling); castleKingsideMask = Board.BlackCastleKEmptySquaresMask; } ulong move; var fromSquare = Bitwise.FindFirstSetBit(king); if (fromSquare == Square.Illegal) { return; } var kingDestinations = MoveGeneration switch { MoveGeneration.AllMoves => Board.KingMoveMasks[fromSquare] & unOrEnemyOccupiedSquares & ToSquareMask, MoveGeneration.OnlyCaptures => Board.KingMoveMasks[fromSquare] & enemyOccupiedSquares & ToSquareMask, MoveGeneration.OnlyNonCaptures => Board.KingMoveMasks[fromSquare] & ~Occupancy & ToSquareMask, _ => throw new Exception($"{MoveGeneration} move generation not supported.") }; int toSquare; while ((toSquare = Bitwise.FindFirstSetBit(kingDestinations)) != Square.Illegal) { var victim = GetPiece(toSquare); move = Move.Null; Move.SetFrom(ref move, fromSquare); Move.SetTo(ref move, toSquare); if (victim != Piece.None) { Move.SetCaptureAttacker(ref move, attacker); } Move.SetCaptureVictim(ref move, victim); Move.SetIsKingMove(ref move, true); Move.SetIsQuiet(ref move, victim == Piece.None); Moves[MoveIndex] = move; MoveIndex++; Bitwise.ClearBit(ref kingDestinations, toSquare); } if (MoveGeneration != MoveGeneration.OnlyCaptures) { if (castleQueenside && ((Occupancy & castleQueensideMask) == 0)) { // Castle Queenside if (WhiteMove) { // White Move fromSquare = Square.e1; toSquare = Square.c1; } else { // Black Move fromSquare = Square.e8; toSquare = Square.c8; } if ((Board.SquareMasks[toSquare] & ToSquareMask) > 0) { move = Move.Null; Move.SetFrom(ref move, fromSquare); Move.SetTo(ref move, toSquare); Move.SetIsCastling(ref move, true); Move.SetIsKingMove(ref move, true); Move.SetIsQuiet(ref move, false); Moves[MoveIndex] = move; MoveIndex++; } } if (castleKingside && ((Occupancy & castleKingsideMask) == 0)) { // Castle Kingside if (WhiteMove) { // White Move fromSquare = Square.e1; toSquare = Square.g1; } else { // Black Move fromSquare = Square.e8; toSquare = Square.g8; } if ((Board.SquareMasks[toSquare] & ToSquareMask) > 0) { move = Move.Null; Move.SetFrom(ref move, fromSquare); Move.SetTo(ref move, toSquare); Move.SetIsCastling(ref move, true); Move.SetIsKingMove(ref move, true); Move.SetIsQuiet(ref move, false); Moves[MoveIndex] = move; MoveIndex++; } } } }
private void GeneratePawnMoves(MoveGeneration MoveGeneration, ulong FromSquareMask, ulong ToSquareMask) { ulong pawns; ulong[] pawnMoveMasks; ulong[] pawnDoubleMoveMasks; ulong[] pawnAttackMasks; ulong enemyOccupiedSquares; var unoccupiedSquares = ~Occupancy; int[] ranks; int attacker; int queen; int rook; int bishop; int knight; int enPassantVictim; if (WhiteMove) { // White Move pawns = WhitePawns & FromSquareMask; pawnMoveMasks = Board.WhitePawnMoveMasks; pawnDoubleMoveMasks = Board.WhitePawnDoubleMoveMasks; pawnAttackMasks = Board.WhitePawnAttackMasks; enemyOccupiedSquares = OccupancyBlack; ranks = Board.WhiteRanks; attacker = Piece.WhitePawn; queen = Piece.WhiteQueen; rook = Piece.WhiteRook; bishop = Piece.WhiteBishop; knight = Piece.WhiteKnight; enPassantVictim = Piece.BlackPawn; } else { // Black Move pawns = BlackPawns & FromSquareMask; pawnMoveMasks = Board.BlackPawnMoveMasks; pawnDoubleMoveMasks = Board.BlackPawnDoubleMoveMasks; pawnAttackMasks = Board.BlackPawnAttackMasks; enemyOccupiedSquares = OccupancyWhite; ranks = Board.BlackRanks; attacker = Piece.BlackPawn; queen = Piece.BlackQueen; rook = Piece.BlackRook; bishop = Piece.BlackBishop; knight = Piece.BlackKnight; enPassantVictim = Piece.WhitePawn; } int fromSquare; ulong move; if ((EnPassantSquare != Square.Illegal) && ((Board.SquareMasks[EnPassantSquare] & ToSquareMask) > 0) && (MoveGeneration != MoveGeneration.OnlyNonCaptures)) { var enPassantAttackers = Board.EnPassantAttackerMasks[EnPassantSquare] & pawns; while ((fromSquare = Bitwise.FindFirstSetBit(enPassantAttackers)) != Square.Illegal) { // Capture pawn en passant. move = Move.Null; Move.SetFrom(ref move, fromSquare); Move.SetTo(ref move, EnPassantSquare); Move.SetCaptureAttacker(ref move, attacker); Move.SetCaptureVictim(ref move, enPassantVictim); Move.SetIsEnPassantCapture(ref move, true); Move.SetIsPawnMove(ref move, true); Move.SetIsQuiet(ref move, false); Moves[MoveIndex] = move; MoveIndex++; Bitwise.ClearBit(ref enPassantAttackers, fromSquare); } } while ((fromSquare = Bitwise.FindFirstSetBit(pawns)) != Square.Illegal) { ulong pawnDestinations; int toSquare; int toSquareRank; if (MoveGeneration != MoveGeneration.OnlyCaptures) { // Pawns may move forward one square (or two if on initial square) if forward squares are unoccupied. pawnDestinations = pawnMoveMasks[fromSquare] & unoccupiedSquares & ToSquareMask; while ((toSquare = Bitwise.FindFirstSetBit(pawnDestinations)) != Square.Illegal) { var doubleMove = Board.SquareDistances[fromSquare][toSquare] == 2; if (doubleMove && ((Occupancy & pawnDoubleMoveMasks[fromSquare]) > 0)) { // Double move is blocked. Bitwise.ClearBit(ref pawnDestinations, toSquare); continue; } toSquareRank = ranks[toSquare]; if (toSquareRank < 7) { move = Move.Null; Move.SetFrom(ref move, fromSquare); Move.SetTo(ref move, toSquare); Move.SetIsDoublePawnMove(ref move, doubleMove); Move.SetIsPawnMove(ref move, true); Move.SetIsQuiet(ref move, true); Moves[MoveIndex] = move; MoveIndex++; } else { // Promote pawn to queen. move = Move.Null; Move.SetFrom(ref move, fromSquare); Move.SetTo(ref move, toSquare); Move.SetPromotedPiece(ref move, queen); Move.SetIsPawnMove(ref move, true); Move.SetIsQuiet(ref move, false); Moves[MoveIndex] = move; MoveIndex++; // Promote pawn to rook. move = Move.Null; Move.SetFrom(ref move, fromSquare); Move.SetTo(ref move, toSquare); Move.SetPromotedPiece(ref move, rook); Move.SetIsPawnMove(ref move, true); Move.SetIsQuiet(ref move, false); Moves[MoveIndex] = move; MoveIndex++; // Promote pawn to bishop. move = Move.Null; Move.SetFrom(ref move, fromSquare); Move.SetTo(ref move, toSquare); Move.SetPromotedPiece(ref move, bishop); Move.SetIsPawnMove(ref move, true); Move.SetIsQuiet(ref move, false); Moves[MoveIndex] = move; MoveIndex++; // Promote pawn to knight. move = Move.Null; Move.SetFrom(ref move, fromSquare); Move.SetTo(ref move, toSquare); Move.SetPromotedPiece(ref move, knight); Move.SetIsPawnMove(ref move, true); Move.SetIsQuiet(ref move, false); Moves[MoveIndex] = move; MoveIndex++; } Bitwise.ClearBit(ref pawnDestinations, toSquare); } } if (MoveGeneration != MoveGeneration.OnlyNonCaptures) { // Pawns may attack diagonally forward one square if occupied by enemy. pawnDestinations = pawnAttackMasks[fromSquare] & enemyOccupiedSquares & ToSquareMask; while ((toSquare = Bitwise.FindFirstSetBit(pawnDestinations)) != Square.Illegal) { toSquareRank = ranks[toSquare]; var victim = GetPiece(toSquare); if (toSquareRank < 7) { move = Move.Null; Move.SetFrom(ref move, fromSquare); Move.SetTo(ref move, toSquare); Move.SetCaptureAttacker(ref move, attacker); Move.SetCaptureVictim(ref move, victim); Move.SetIsPawnMove(ref move, true); Move.SetIsQuiet(ref move, false); Moves[MoveIndex] = move; MoveIndex++; } else { // Promote pawn to queen. move = Move.Null; Move.SetFrom(ref move, fromSquare); Move.SetTo(ref move, toSquare); Move.SetPromotedPiece(ref move, queen); Move.SetCaptureAttacker(ref move, attacker); Move.SetCaptureVictim(ref move, victim); Move.SetIsPawnMove(ref move, true); Move.SetIsQuiet(ref move, false); Moves[MoveIndex] = move; MoveIndex++; // Promote pawn to rook. move = Move.Null; Move.SetFrom(ref move, fromSquare); Move.SetTo(ref move, toSquare); Move.SetPromotedPiece(ref move, rook); Move.SetCaptureAttacker(ref move, attacker); Move.SetCaptureVictim(ref move, victim); Move.SetIsPawnMove(ref move, true); Move.SetIsQuiet(ref move, false); Moves[MoveIndex] = move; MoveIndex++; // Promote pawn to bishop. move = Move.Null; Move.SetFrom(ref move, fromSquare); Move.SetTo(ref move, toSquare); Move.SetPromotedPiece(ref move, bishop); Move.SetCaptureAttacker(ref move, attacker); Move.SetCaptureVictim(ref move, victim); Move.SetIsPawnMove(ref move, true); Move.SetIsQuiet(ref move, false); Moves[MoveIndex] = move; MoveIndex++; // Promote pawn to knight. move = Move.Null; Move.SetFrom(ref move, fromSquare); Move.SetTo(ref move, toSquare); Move.SetPromotedPiece(ref move, knight); Move.SetCaptureAttacker(ref move, attacker); Move.SetCaptureVictim(ref move, victim); Move.SetIsPawnMove(ref move, true); Move.SetIsQuiet(ref move, false); Moves[MoveIndex] = move; MoveIndex++; } Bitwise.ClearBit(ref pawnDestinations, toSquare); } } Bitwise.ClearBit(ref pawns, fromSquare); } }
private void GenerateKingMoves(MoveGeneration moveGeneration, ulong fromSquareMask, ulong toSquareMask) { var king = GetKing(ColorToMove) & fromSquareMask; if (king == 0) { return; } var unOrEnemyOccupiedSquares = ~ColorOccupancy[(int)ColorToMove]; var enemyOccupiedSquares = ColorOccupancy[(int)ColorLastMoved]; var attacker = PieceHelper.GetPieceOfColor(ColorlessPiece.King, ColorToMove); ulong move; var fromSquare = Bitwise.FirstSetSquare(king); if (fromSquare == Square.Illegal) { return; } var kingDestinations = moveGeneration switch { MoveGeneration.AllMoves => Board.KingMoveMasks[(int)fromSquare] & unOrEnemyOccupiedSquares & toSquareMask, MoveGeneration.OnlyCaptures => Board.KingMoveMasks[(int)fromSquare] & enemyOccupiedSquares & toSquareMask, MoveGeneration.OnlyNonCaptures => Board.KingMoveMasks[(int)fromSquare] & ~Occupancy & toSquareMask, _ => throw new Exception($"{moveGeneration} move generation not supported.") }; Square toSquare; while ((toSquare = Bitwise.PopFirstSetSquare(ref kingDestinations)) != Square.Illegal) { var victim = GetPiece(toSquare); move = Move.Null; Move.SetPiece(ref move, attacker); Move.SetFrom(ref move, fromSquare); Move.SetTo(ref move, toSquare); if (victim != Piece.None) { Move.SetCaptureAttacker(ref move, attacker); } Move.SetCaptureVictim(ref move, victim); Move.SetIsKingMove(ref move, true); Moves[MoveIndex] = move; MoveIndex++; } if (moveGeneration != MoveGeneration.OnlyCaptures) { for (var boardSide = BoardSide.Queen; boardSide <= BoardSide.King; boardSide++) { var castleEmptySquaresMask = Board.CastleEmptySquaresMask[(int)ColorToMove][(int)boardSide]; if (!KingInCheck && Game.Castling.Permitted(Castling, ColorToMove, boardSide) && ((Occupancy & castleEmptySquaresMask) == 0)) { // Castle toSquare = Board.CastleToSquares[(int)ColorToMove][(int)boardSide]; if ((Board.SquareMasks[(int)toSquare] & toSquareMask) > 0) { move = Move.Null; Move.SetPiece(ref move, attacker); Move.SetFrom(ref move, fromSquare); Move.SetTo(ref move, toSquare); Move.SetIsCastling(ref move, true); Move.SetIsKingMove(ref move, true); Moves[MoveIndex] = move; MoveIndex++; } } } } }
private void GeneratePawnMoves(MoveGeneration moveGeneration, ulong fromSquareMask, ulong toSquareMask) { var pawns = GetPawns(ColorToMove) & fromSquareMask; if (pawns == 0) { return; } var pawnMoveMasks = Board.PawnMoveMasks[(int)ColorToMove]; var pawnDoubleMoveMasks = Board.PawnDoubleMoveMasks[(int)ColorToMove]; var pawnAttackMasks = Board.PawnAttackMasks[(int)ColorToMove]; var enemyOccupiedSquares = ColorOccupancy[(int)ColorLastMoved]; var unoccupiedSquares = ~Occupancy; var ranks = Board.Ranks[(int)ColorToMove]; var attacker = PieceHelper.GetPieceOfColor(ColorlessPiece.Pawn, ColorToMove); var queen = PieceHelper.GetPieceOfColor(ColorlessPiece.Queen, ColorToMove); var knight = PieceHelper.GetPieceOfColor(ColorlessPiece.Knight, ColorToMove); var enPassantVictim = PieceHelper.GetPieceOfColor(ColorlessPiece.Pawn, ColorLastMoved); Square fromSquare; ulong move; if ((EnPassantSquare != Square.Illegal) && ((Board.SquareMasks[(int)EnPassantSquare] & toSquareMask) > 0) && (moveGeneration != MoveGeneration.OnlyNonCaptures)) { var enPassantAttackers = Board.EnPassantAttackerMasks[(int)EnPassantSquare] & pawns; while ((fromSquare = Bitwise.PopFirstSetSquare(ref enPassantAttackers)) != Square.Illegal) { // Capture pawn en passant. move = Move.Null; Move.SetPiece(ref move, attacker); Move.SetFrom(ref move, fromSquare); Move.SetTo(ref move, EnPassantSquare); Move.SetCaptureAttacker(ref move, attacker); Move.SetCaptureVictim(ref move, enPassantVictim); Move.SetIsEnPassantCapture(ref move, true); Move.SetIsPawnMove(ref move, true); Moves[MoveIndex] = move; MoveIndex++; } } while ((fromSquare = Bitwise.PopFirstSetSquare(ref pawns)) != Square.Illegal) { ulong pawnDestinations; Square toSquare; int toSquareRank; if (moveGeneration != MoveGeneration.OnlyCaptures) { // Pawns may move forward one square (or two if on initial square) if forward squares are unoccupied. pawnDestinations = pawnMoveMasks[(int)fromSquare] & unoccupiedSquares & toSquareMask; while ((toSquare = Bitwise.PopFirstSetSquare(ref pawnDestinations)) != Square.Illegal) { var doubleMove = Board.SquareDistances[(int)fromSquare][(int)toSquare] == 2; if (doubleMove && ((Occupancy & pawnDoubleMoveMasks[(int)fromSquare]) > 0)) { continue; // Double move is blocked. } toSquareRank = ranks[(int)toSquare]; if (toSquareRank < 7) { move = Move.Null; Move.SetPiece(ref move, attacker); Move.SetFrom(ref move, fromSquare); Move.SetTo(ref move, toSquare); Move.SetIsDoublePawnMove(ref move, doubleMove); Move.SetIsPawnMove(ref move, true); Moves[MoveIndex] = move; MoveIndex++; } else { for (var promotedPiece = queen; promotedPiece >= knight; promotedPiece--) { // Promote pawn. move = Move.Null; Move.SetPiece(ref move, attacker); Move.SetFrom(ref move, fromSquare); Move.SetTo(ref move, toSquare); Move.SetPromotedPiece(ref move, promotedPiece); Move.SetIsPawnMove(ref move, true); Moves[MoveIndex] = move; MoveIndex++; } } } } if (moveGeneration != MoveGeneration.OnlyNonCaptures) { // Pawns may attack diagonally forward one square if occupied by enemy. pawnDestinations = pawnAttackMasks[(int)fromSquare] & enemyOccupiedSquares & toSquareMask; while ((toSquare = Bitwise.PopFirstSetSquare(ref pawnDestinations)) != Square.Illegal) { toSquareRank = ranks[(int)toSquare]; var victim = GetPiece(toSquare); if (toSquareRank < 7) { move = Move.Null; Move.SetPiece(ref move, attacker); Move.SetFrom(ref move, fromSquare); Move.SetTo(ref move, toSquare); Move.SetCaptureAttacker(ref move, attacker); Move.SetCaptureVictim(ref move, victim); Move.SetIsPawnMove(ref move, true); Moves[MoveIndex] = move; MoveIndex++; } else { for (var promotedPiece = queen; promotedPiece >= knight; promotedPiece--) { // Promote pawn. move = Move.Null; Move.SetPiece(ref move, attacker); Move.SetFrom(ref move, fromSquare); Move.SetTo(ref move, toSquare); Move.SetCaptureAttacker(ref move, attacker); Move.SetPromotedPiece(ref move, promotedPiece); Move.SetCaptureVictim(ref move, victim); Move.SetIsPawnMove(ref move, true); Moves[MoveIndex] = move; MoveIndex++; } } } } } }
public void GenerateMoves(MoveGeneration moveGeneration, ulong fromSquareMask, ulong toSquareMask) { GeneratePawnMoves(moveGeneration, fromSquareMask, toSquareMask); GeneratePieceMoves(moveGeneration, fromSquareMask, toSquareMask); GenerateKingMoves(moveGeneration, fromSquareMask, toSquareMask); }