示例#1
0
        public static ulong PseudomoveBitboard(int piece, int[] board)
        {
            PieceType pt = Util.GetPieceType(piece);

            switch (pt)
            {
            case PieceType.Pawn:
                return(PawnMoveGenerator.PseudomoveBitboard(piece, board));

            case PieceType.Night:
                return(KnightMoveGenerator.PseudomoveBitboard(piece));

            case PieceType.Bishop:
                return(BishopMoveGenerator.PseudomoveBitboard(piece));

            case PieceType.Rook:
                return(RookMoveGenerator.PseudomoveBitboard(piece));

            case PieceType.Queen:
                return(QueenMoveGenerator.PseudomoveBitboard(piece));

            case PieceType.King:
                return(KingMoveGenerator.PseudomoveBitboard(piece));

            default:
                break;
            }

            return(0);
        }
示例#2
0
文件: Game.cs 项目: wgwine/ChessGen
        public MoveGenerationResult GetMoves()
        {
            MoveGenerationResult result                       = new MoveGenerationResult();
            List <Move>          myGeneratedMoves             = new List <Move>();
            List <Move>          nonCheckingMoves             = new List <Move>();
            List <ulong>         enemyPseudoMoves             = new List <ulong>();
            List <int>           threateningPieces            = new List <int>();
            List <int>           threateningPiecesNonKingMove = new List <int>();
            IEnumerable <int>    positions                    = _theBoard.Where(e => e > 0);
            List <int>           myPieces                     = positions.Where(e => _whiteToMove == Util.IsWhite(e)).ToList();
            List <int>           enemyPieces                  = positions.Where(e => _whiteToMove == !Util.IsWhite(e)).ToList();
            bool   kingChecked = false;
            int    currentKingPosition;
            int    opponentKingPiece;
            double materialScore = Material();

            if (_whiteToMove)
            {
                currentKingPiece = whiteKing;
            }
            else
            {
                currentKingPiece = blackKing;
            }
            if (!_whiteToMove)
            {
                opponentKingPiece = whiteKing;
            }
            else
            {
                opponentKingPiece = blackKing;
            }
            currentKingPosition = Util.GetPieceOffset(currentKingPiece);

            Dictionary <int, List <Move> > enemyMovements = new Dictionary <int, List <Models.Move> >();

            List <Move> pieceMoves;
            //see if king is currently in check. If yes and no moves are generated it is checkmate. If no and no moves generated it is stalemate
            bool allowOOOCastle = true, allowOOCastle = true;

            foreach (int piece in enemyPieces)
            {
                pieceMoves = MoveGenerator.GenerateMovesForPiece(piece, _theBoard);
                if (Util.IsSquareAttacked(currentKingPosition, pieceMoves))
                {
                    kingChecked = true;
                }
                else
                {
                    if (_whiteToMove)
                    {
                        if (Util.AreSquaresAttacked(whiteOOCastleAttackedSquares, pieceMoves))
                        {
                            allowOOCastle = false;
                        }
                        if (Util.AreSquaresAttacked(whiteOOOCastleAttackedSquares, pieceMoves))
                        {
                            allowOOOCastle = false;
                        }
                    }
                    else
                    {
                        if (Util.AreSquaresAttacked(blackOOCastleAttackedSquares, pieceMoves))
                        {
                            allowOOCastle = false;
                        }
                        if (Util.AreSquaresAttacked(blackOOOCastleAttackedSquares, pieceMoves))
                        {
                            allowOOOCastle = false;
                        }
                    }
                }
                //get all targeted enemy squares without regard for blocking squares. Used to trim check verification step
                enemyPseudoMoves.Add(MoveGenerator.PseudomoveBitboard(piece, _theBoard));
            }
            if (!kingChecked)
            {
                if (_whiteToMove)
                {
                    if (_whiteOOCastle && allowOOCastle && Util.AreSquaresEmpty(whiteOOCastleAttackedSquares, _theBoard))
                    {
                        nonCheckingMoves.Add(new Move()
                        {
                            From = whiteKing, To = whiteKing + 2, CastleRookFrom = _theBoard[7], CastleRookTo = _theBoard[7] - 2, removesOO = true
                        });
                    }
                    if (_whiteOOOCastle && allowOOOCastle && Util.AreSquaresEmpty(whiteOOOCastleOccupiedSquares, _theBoard))
                    {
                        nonCheckingMoves.Add(new Move()
                        {
                            From = whiteKing, To = whiteKing - 2, CastleRookFrom = _theBoard[0], CastleRookTo = _theBoard[0] + 3, removesOOO = true
                        });
                    }
                }
                else
                {
                    if (_blackOOCastle && allowOOOCastle && Util.AreSquaresEmpty(blackOOCastleAttackedSquares, _theBoard))
                    {
                        nonCheckingMoves.Add(new Move()
                        {
                            From = blackKing, To = blackKing + 2, CastleRookFrom = _theBoard[63], CastleRookTo = _theBoard[63] - 2, removesOO = true
                        });
                    }
                    if (_blackOOOCastle && allowOOOCastle && Util.AreSquaresEmpty(blackOOOCastleOccupiedSquares, _theBoard))
                    {
                        nonCheckingMoves.Add(new Move()
                        {
                            From = blackKing, To = blackKing - 2, CastleRookFrom = _theBoard[56], CastleRookTo = _theBoard[56] + 3, removesOOO = true
                        });
                    }
                }
            }

            //generate legal moves for each of my pieces
            foreach (int piece in myPieces)
            {
                myGeneratedMoves.AddRange(MoveGenerator.GenerateMovesForPiece(piece, _theBoard));
            }


            ulong movedKingPositions  = KingMoveGenerator.PseudomoveBitboard(currentKingPiece);
            ulong unmovedKingPosition = (one << (currentKingPosition));

            foreach (int piece in _theBoard.Where(e => e > 0 && _whiteToMove != Util.IsWhite(e)))
            {
                //find out if the move caused the king to be in check
                if ((movedKingPositions & MoveGenerator.PseudomoveBitboard(piece, _theBoard)) > 0)
                {
                    threateningPieces.Add(piece);
                }
                if ((unmovedKingPosition & MoveGenerator.PseudomoveBitboard(piece, _theBoard)) > 0)
                {
                    threateningPiecesNonKingMove.Add(piece);
                }
            }

            foreach (Move m in myGeneratedMoves)
            {
                bool kingFutureChecked = false;

                Move maybeCapturedEnemy = Move(m, true);

                m.MaterialScore = materialScore + (maybeCapturedEnemy.Captured.HasValue ? Util.GetPieceValue(maybeCapturedEnemy.Captured.Value) : 0);

                if (!_whiteToMove)
                {
                    currentKingPiece = whiteKing;
                }
                else
                {
                    currentKingPiece = blackKing;
                }
                currentKingPosition = Util.GetPieceOffset(currentKingPiece);
                if (Util.IsKing(m.From))
                {
                    foreach (int piece in threateningPieces.Where(e => _theBoard.Contains(e)))
                    {
                        //find out if the move caused the king to be in check
                        if (((one << (currentKingPosition)) & MoveGenerator.GenerateMovesForPieceBitboard(piece, _theBoard)) > 0)
                        {
                            kingFutureChecked = true;
                        }
                    }
                }
                else
                {
                    foreach (int piece in threateningPiecesNonKingMove.Where(e => _theBoard.Contains(e)))
                    {
                        //find out if the move caused the king to be in check
                        if (((one << (currentKingPosition)) & MoveGenerator.GenerateMovesForPieceBitboard(piece, _theBoard)) > 0)
                        {
                            kingFutureChecked = true;
                        }
                    }
                }

                Undo();
                if (!kingFutureChecked)
                {
                    nonCheckingMoves.Add(m);
                }
            }

            result.Moves = nonCheckingMoves;
            if (nonCheckingMoves.Count == 0)
            {
                if (kingChecked)
                {
                    result.Endgame = EndgameType.Checkmate;
                }
                else
                {
                    result.Endgame = EndgameType.Stalemate;
                }
            }
            return(result);
        }