Ejemplo n.º 1
0
 public void PlacePiece(Piece piece)
 {
     Debug.Log(board);
     board.PlacePiece(piece);
     StrategyGame.Instance.Pieces.Add(piece);
     MoveGeneration.GenerateMoves(StrategyGame.Instance.Pieces);
 }
Ejemplo n.º 2
0
 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);
 }
Ejemplo n.º 3
0
        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);
            }
        }
Ejemplo n.º 4
0
        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);
            }
        }
Ejemplo n.º 5
0
 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++;
             }
         }
     }
 }
Ejemplo n.º 6
0
 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);
         }
     }
 }
Ejemplo n.º 7
0
        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++;
                    }
                }
            }
        }
Ejemplo n.º 8
0
        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);
            }
        }
Ejemplo n.º 9
0
    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++;
                    }
                }
            }
        }
    }
Ejemplo n.º 10
0
    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++;
                        }
                    }
                }
            }
        }
    }
Ejemplo n.º 11
0
 public void GenerateMoves(MoveGeneration moveGeneration, ulong fromSquareMask, ulong toSquareMask)
 {
     GeneratePawnMoves(moveGeneration, fromSquareMask, toSquareMask);
     GeneratePieceMoves(moveGeneration, fromSquareMask, toSquareMask);
     GenerateKingMoves(moveGeneration, fromSquareMask, toSquareMask);
 }