Exemple #1
0
        public void OrderMoves(Board board, List <Move> moves, bool useTT)
        {
            Move hashMove = invalidMove;

            if (useTT)
            {
                hashMove = transpositionTable.GetStoredMove();
            }

            for (int i = 0; i < moves.Count; i++)
            {
                int score            = 0;
                int movePieceType    = Piece.PieceType(board.Square[moves[i].StartSquare]);
                int capturePieceType = Piece.PieceType(board.Square[moves[i].TargetSquare]);
                int flag             = moves[i].MoveFlag;

                if (capturePieceType != Piece.None)
                {
                    // Order moves to try capturing the most valuable opponent piece with least valuable of own pieces first
                    // The capturedPieceValueMultiplier is used to make even 'bad' captures like QxP rank above non-captures
                    score = capturedPieceValueMultiplier * GetPieceValue(capturePieceType) - GetPieceValue(movePieceType);
                }

                if (movePieceType == Piece.Pawn)
                {
                    if (flag == Move.Flag.PromoteToQueen)
                    {
                        score += Evaluation.queenValue;
                    }
                    else if (flag == Move.Flag.PromoteToKnight)
                    {
                        score += Evaluation.knightValue;
                    }
                    else if (flag == Move.Flag.PromoteToRook)
                    {
                        score += Evaluation.rookValue;
                    }
                    else if (flag == Move.Flag.PromoteToBishop)
                    {
                        score += Evaluation.bishopValue;
                    }
                }
                else
                {
                    // Penalize moving piece to a square attacked by opponent pawn
                    if (BitBoardUtility.ContainsSquare(moveGenerator.opponentPawnAttackMap, moves[i].TargetSquare))
                    {
                        score -= squareControlledByOpponentPawnPenalty;
                    }
                }
                if (Move.SameMove(moves[i], hashMove))
                {
                    score += 10000;
                }

                moveScores[i] = score;
            }

            Sort(moves);
        }
Exemple #2
0
        bool SquareAttackedAfterEPCapture(int epCaptureSquare, int capturingPawnStartSquare)
        {
            if (BitBoardUtility.ContainsSquare(opponentAttackMapNoPawns, friendlyKingSquare))
            {
                return(true);
            }

            // Loop through the horizontal direction towards ep capture to see if any enemy piece now attacks king
            int dirIndex = (epCaptureSquare < friendlyKingSquare) ? 2 : 3;

            for (int i = 0; i < numSquaresToEdge[friendlyKingSquare][dirIndex]; i++)
            {
                int squareIndex = friendlyKingSquare + directionOffsets[dirIndex] * (i + 1);
                int piece       = board.Square[squareIndex];
                if (piece != Piece.None)
                {
                    // Friendly piece is blocking view of this square from the enemy.
                    if (Piece.IsColour(piece, friendlyColour))
                    {
                        break;
                    }
                    // This square contains an enemy piece
                    else
                    {
                        if (Piece.IsRookOrQueen(piece))
                        {
                            return(true);
                        }
                        else
                        {
                            // This piece is not able to move in the current direction, and is therefore blocking any checks along this line
                            break;
                        }
                    }
                }
            }

            // check if enemy pawn is controlling this square (can't use pawn attack bitboard, because pawn has been captured)
            for (int i = 0; i < 2; i++)
            {
                // Check if square exists diagonal to friendly king from which enemy pawn could be attacking it
                if (numSquaresToEdge[friendlyKingSquare][pawnAttackDirections[friendlyColourIndex][i]] > 0)
                {
                    // move in direction friendly pawns attack to get square from which enemy pawn would attack
                    int piece = board.Square[friendlyKingSquare + directionOffsets[pawnAttackDirections[friendlyColourIndex][i]]];
                    if (piece == (Piece.Pawn | opponentColour))                     // is enemy pawn
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
Exemple #3
0
 bool SquareIsAttacked(int square)
 {
     return(BitBoardUtility.ContainsSquare(opponentAttackMap, square));
 }
Exemple #4
0
        void CalculateAttackData()
        {
            GenSlidingAttackMap();
            // Search squares in all directions around friendly king for checks/pins by enemy sliding pieces (queen, rook, bishop)
            int startDirIndex = 0;
            int endDirIndex   = 8;

            if (board.queens[opponentColourIndex].Count == 0)
            {
                startDirIndex = (board.rooks[opponentColourIndex].Count > 0) ? 0 : 4;
                endDirIndex   = (board.bishops[opponentColourIndex].Count > 0) ? 8 : 4;
            }

            for (int dir = startDirIndex; dir < endDirIndex; dir++)
            {
                bool isDiagonal = dir > 3;

                int   n = numSquaresToEdge[friendlyKingSquare][dir];
                int   directionOffset         = directionOffsets[dir];
                bool  isFriendlyPieceAlongRay = false;
                ulong rayMask = 0;

                for (int i = 0; i < n; i++)
                {
                    int squareIndex = friendlyKingSquare + directionOffset * (i + 1);
                    rayMask |= 1ul << squareIndex;
                    int piece = board.Square[squareIndex];

                    // This square contains a piece
                    if (piece != Piece.None)
                    {
                        if (Piece.IsColour(piece, friendlyColour))
                        {
                            // First friendly piece we have come across in this direction, so it might be pinned
                            if (!isFriendlyPieceAlongRay)
                            {
                                isFriendlyPieceAlongRay = true;
                            }
                            // This is the second friendly piece we've found in this direction, therefore pin is not possible
                            else
                            {
                                break;
                            }
                        }
                        // This square contains an enemy piece
                        else
                        {
                            int pieceType = Piece.PieceType(piece);

                            // Check if piece is in bitmask of pieces able to move in current direction
                            if (isDiagonal && Piece.IsBishopOrQueen(pieceType) || !isDiagonal && Piece.IsRookOrQueen(pieceType))
                            {
                                // Friendly piece blocks the check, so this is a pin
                                if (isFriendlyPieceAlongRay)
                                {
                                    pinsExistInPosition = true;
                                    pinRayBitmask      |= rayMask;
                                }
                                // No friendly piece blocking the attack, so this is a check
                                else
                                {
                                    checkRayBitmask |= rayMask;
                                    inDoubleCheck    = inCheck;                                  // if already in check, then this is double check
                                    inCheck          = true;
                                }
                                break;
                            }
                            else
                            {
                                // This enemy piece is not able to move in the current direction, and so is blocking any checks/pins
                                break;
                            }
                        }
                    }
                }
                // Stop searching for pins if in double check, as the king is the only piece able to move in that case anyway
                if (inDoubleCheck)
                {
                    break;
                }
            }

            // Knight attacks
            PieceList opponentKnights = board.knights[opponentColourIndex];

            opponentKnightAttacks = 0;
            bool isKnightCheck = false;

            for (int knightIndex = 0; knightIndex < opponentKnights.Count; knightIndex++)
            {
                int startSquare = opponentKnights[knightIndex];
                opponentKnightAttacks |= knightAttackBitboards[startSquare];

                if (!isKnightCheck && BitBoardUtility.ContainsSquare(opponentKnightAttacks, friendlyKingSquare))
                {
                    isKnightCheck    = true;
                    inDoubleCheck    = inCheck;                  // if already in check, then this is double check
                    inCheck          = true;
                    checkRayBitmask |= 1ul << startSquare;
                }
            }

            // Pawn attacks
            PieceList opponentPawns = board.pawns[opponentColourIndex];

            opponentPawnAttackMap = 0;
            bool isPawnCheck = false;

            for (int pawnIndex = 0; pawnIndex < opponentPawns.Count; pawnIndex++)
            {
                int   pawnSquare  = opponentPawns[pawnIndex];
                ulong pawnAttacks = pawnAttackBitboards[pawnSquare][opponentColourIndex];
                opponentPawnAttackMap |= pawnAttacks;

                if (!isPawnCheck && BitBoardUtility.ContainsSquare(pawnAttacks, friendlyKingSquare))
                {
                    isPawnCheck      = true;
                    inDoubleCheck    = inCheck;                  // if already in check, then this is double check
                    inCheck          = true;
                    checkRayBitmask |= 1ul << pawnSquare;
                }
            }

            int enemyKingSquare = board.KingSquare[opponentColourIndex];

            opponentAttackMapNoPawns = opponentSlidingAttackMap | opponentKnightAttacks | kingAttackBitboards[enemyKingSquare];
            opponentAttackMap        = opponentAttackMapNoPawns | opponentPawnAttackMap;
        }