Exemplo n.º 1
0
    // returns true if last GameState results in a draw by insufficient material, false otherwise
    public static bool IsDrawByInsufficientMaterial()
    {
        // initialize piece counts
        int w_knight_count = ChessBoard.BitCount(AI.board.white_knight);
        int w_bishop_count = ChessBoard.BitCount(AI.board.white_bishop);
        int b_knight_count = ChessBoard.BitCount(AI.board.black_knight);
        int b_bishop_count = ChessBoard.BitCount(AI.board.black_bishop);
        int w_piece_count  = ChessBoard.BitCount(AI.board.white_pieces);
        int b_piece_count  = ChessBoard.BitCount(AI.board.black_pieces);

        // white king v. black king
        if (w_piece_count == 1 && b_piece_count == 1)
        {
            return(true);
        }

        // white king v. black king and knight or bishop
        if (w_piece_count == 1 && b_piece_count == 2 && (b_knight_count == 1 || b_bishop_count == 1))
        {
            return(true);
        }

        // white king and knight or bishop v. black king
        if (b_piece_count == 1 && w_piece_count == 2 && (w_knight_count == 1 || w_bishop_count == 1))
        {
            return(true);
        }

        // white king and bishop(s) v. black king and bishop(s), bishops all on same color squares
        if ((w_piece_count - w_bishop_count) == 1 && (b_piece_count - b_bishop_count) == 1)
        {
            // initialize light/dark squares Biboards
            UInt64 light_squares = 0x55AA55AA55AA55AA;
            UInt64 dark_squares  = 0xAA55AA55AA55AA55;

            // bishops are all on light squares
            if ((AI.board.white_bishop & dark_squares) == 0 && (AI.board.black_bishop & dark_squares) == 0)
            {
                return(true);
            }

            // bishops are all on dark squares
            if ((AI.board.white_bishop & light_squares) == 0 && (AI.board.black_bishop & light_squares) == 0)
            {
                return(true);
            }
        }

        // there is still sufficient material to checkmate
        return(false);
    }
Exemplo n.º 2
0
    // returns the king safety score for the specified color
    public static int GetKingSafetyScore(int player)
    {
        // initialize variables
        int white_king_safety = 0, black_king_safety = 0, net_king_safety = 0;

        // calculate white king safety score
        uint white_king_sq = MoveGen.GetNextSquare(AI.board.white_king);

        white_king_safety += BONUS_KINGSAFETY_STRONG * (ChessBoard.BitCount(W_KINGSAFETY_STRONG[white_king_sq] & AI.board.white_pawn));
        white_king_safety += BONUS_KINGSAFETY_WEAK * (ChessBoard.BitCount(W_KINGSAFETY_WEAK[white_king_sq] & AI.board.white_pawn));

        // calculate black king safety score
        uint black_king_sq = MoveGen.GetNextSquare(AI.board.black_king);

        black_king_safety += BONUS_KINGSAFETY_STRONG * (ChessBoard.BitCount(B_KINGSAFETY_STRONG[black_king_sq] & AI.board.black_pawn));
        black_king_safety += BONUS_KINGSAFETY_WEAK * (ChessBoard.BitCount(B_KINGSAFETY_WEAK[black_king_sq] & AI.board.black_pawn));

        // give penalty for being in check in end game
        if (IsEndGame(GetMaterialScore(ChessBoard.WHITE), GetMaterialScore(ChessBoard.BLACK)))
        {
            if (MoveGen.IsKingAttacked(ChessBoard.WHITE))
            {
                white_king_safety += PENALTY_KING_CHECKED;
            }
            if (MoveGen.IsKingAttacked(ChessBoard.BLACK))
            {
                black_king_safety += PENALTY_KING_CHECKED;
            }
        }

        // calculate net king safety score
        if (player == ChessBoard.WHITE)
        {
            net_king_safety += white_king_safety - black_king_safety;
        }
        else if (player == ChessBoard.BLACK)
        {
            net_king_safety += black_king_safety - white_king_safety;
        }

        // return king safety score
        return(net_king_safety);
    }
Exemplo n.º 3
0
    // returns the material score for the specified player
    public static int GetMaterialScore(int player)
    {
        // initialize variables
        int    white_material = 0, black_material = 0, net_material = 0;
        int    wPawns        = ChessBoard.BitCount(AI.board.white_pawn);
        int    wRooks        = ChessBoard.BitCount(AI.board.white_rook);
        int    wKnights      = ChessBoard.BitCount(AI.board.white_knight);
        int    wBishops      = ChessBoard.BitCount(AI.board.white_bishop);
        int    wQueens       = ChessBoard.BitCount(AI.board.white_queen);
        int    wTotal        = wPawns + wRooks + wKnights + wBishops + wQueens;
        int    bPawns        = ChessBoard.BitCount(AI.board.black_pawn);
        int    bRooks        = ChessBoard.BitCount(AI.board.black_rook);
        int    bKnights      = ChessBoard.BitCount(AI.board.black_knight);
        int    bBishops      = ChessBoard.BitCount(AI.board.black_bishop);
        int    bQueens       = ChessBoard.BitCount(AI.board.black_queen);
        int    bTotal        = bPawns + bRooks + bKnights + bBishops + bQueens;
        UInt64 light_squares = 0x55AA55AA55AA55AA;
        UInt64 dark_squares  = 0xAA55AA55AA55AA55;

        // calculate material score for both players
        white_material += PAWN_SCORE * wPawns;
        white_material += ROOK_SCORE * wRooks;
        white_material += KNIGHT_SCORE * wKnights;
        white_material += BISHOP_SCORE * wBishops;
        white_material += QUEEN_SCORE * wQueens;
        black_material += PAWN_SCORE * bPawns;
        black_material += ROOK_SCORE * bRooks;
        black_material += KNIGHT_SCORE * bKnights;
        black_material += BISHOP_SCORE * bBishops;
        black_material += QUEEN_SCORE * bQueens;

        // add bonus for bishop pair
        if ((AI.board.white_bishop & light_squares) != ChessBoard.EMPTY && (AI.board.white_bishop & dark_squares) != ChessBoard.EMPTY)
        {
            white_material += BONUS_BISHOP_PAIR;
        }
        if ((AI.board.black_bishop & light_squares) != ChessBoard.EMPTY && (AI.board.black_bishop & dark_squares) != ChessBoard.EMPTY)
        {
            black_material += BONUS_BISHOP_PAIR;
        }

        // if one side is ahead on material, give bonus for pieces remaining on board
        if (player == ChessBoard.WHITE && (white_material + wTotal) > (black_material + bTotal))
        {
            white_material += (45 + (3 * wTotal));
            black_material += (6 * bTotal);
        }
        else if (player == ChessBoard.BLACK && (black_material + bTotal) > (white_material + wTotal))
        {
            black_material += (45 + (3 * bTotal));
            white_material += (6 * wTotal);
        }

        // calculate net material score
        if (player == ChessBoard.WHITE)
        {
            net_material = white_material - black_material;
        }
        else if (player == ChessBoard.BLACK)
        {
            net_material = black_material - white_material;
        }

        // return material score
        return(net_material);
    }