⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 evaluate.cpp

📁 超强国际象棋引擎
💻 CPP
📖 第 1 页 / 共 4 页
字号:
        dist = 4;

        if(wk == (0xA5) || wk == (0xB5))
            { // best case
            if(COLOUR_IS_WHITE(turn))
                dist--;
            }
        else if(wk == (0xB4) || ((wk == (0xA6) || wk == (0xB6)) && bq != (0xB4)))
            { // white loses a tempo
            if(COLOUR_IS_BLACK(turn) && SQUARE_FILE(bq) != (0x5))
                return false;
            }
        else
            {
            return false;
            }

        if(DISTANCE(bk, prom) > dist)
            return true;
        }
    else if(wp == (0xA6))
        {

        prom = (0xB6);
        dist = 4;

        if(false) { }
        else if(wk == (0xB6))
            {           // dist = 0

            dist++;     // self-blocking penalty

            if(COLOUR_IS_WHITE(turn))
                dist--; // right-to-move bonus
            }
        else if(wk == (0xA5) || wk == (0xB5))
            {           // dist = 1, right side

            dist--;     // right-side bonus

            if(DELTA_INC_LINE(wp - bq) == wk - wp)
                dist++; // pinned-pawn penalty

            if(COLOUR_IS_WHITE(turn))
                dist--; // right-to-move bonus
            }
        else if(wk == (0xA7) || wk == (0xB7))
            {           // dist = 1, wrong side
            if(DELTA_INC_LINE(wp - bq) == wk - wp)
                dist++; // pinned-pawn penalty

            if(COLOUR_IS_WHITE(turn))
                dist--; // right-to-move bonus
            }
        else if((wk == (0xA4) || wk == (0xB4)) && bq != (0xB6))
            { // dist = 2, right side
            if(COLOUR_IS_BLACK(turn) && SQUARE_FILE(bq) != (0x5))
                return false;

            dist--; // right-side bonus
            }
        else if((wk == (0xA8) || wk == (0xB8)) && bq != (0xB6))
            { // dist = 2, wrong side
            if(COLOUR_IS_BLACK(turn) && SQUARE_FILE(bq) != (0x7))
                return false;
            }
        else
            {

            return false;
            }

        if(DISTANCE(bk, prom) > dist)
            return true;
        }

    return false;
    }

// draw_kpkr()

static bool draw_kpkr(const int list [], int turn)
    {

    int wk, wp, bk, br;
    int wk_file, wk_rank;
    int wp_file, wp_rank;
    int br_file, br_rank;
    int inc;
    int prom;
    int dist;

    // load

    wk = *list++;
    wp = *list++;
    bk = *list++;
    br = *list++;

    // init

    wk_file = SQUARE_FILE(wk);
    wk_rank = SQUARE_RANK(wk);

    wp_file = SQUARE_FILE(wp);
    wp_rank = SQUARE_RANK(wp);

    br_file = SQUARE_FILE(br);
    br_rank = SQUARE_RANK(br);

    inc = PAWN_MOVE_INC(0);
    prom = PAWN_PROMOTE(wp, 0);

    // conditions

    if(false) { }
    else if(DISTANCE(wk, wp) == 1) {

    // no-op

    }
    else if(DISTANCE(wk, wp) == 2 && abs(wk_rank - wp_rank) <= 1)
        {
        if(COLOUR_IS_BLACK(turn) && br_file != (wk_file + wp_file) / 2)
            return false;
        }
    else
        {

        return false;
        }

    // white features

    dist = DISTANCE(wk, prom) + DISTANCE(wp, prom);

    if(wk == prom)
        dist++;

    if(wk == wp + inc)
        { // king on pawn's "front square"
        if(wp_file == (0x4))
            return false;
        dist++; // self-blocking penalty
        }

    // black features

    if(br_file != wp_file && br_rank != (0xB))
        {
        dist--; // misplaced-rook bonus
        }

    // test

    if(COLOUR_IS_WHITE(turn))
        dist--; // right-to-move bonus

    if(DISTANCE(bk, prom) > dist)
        return true;

    return false;
    }

// draw_kpkb()

static bool draw_kpkb(const int list [], int turn)
    {

    int wk, wp, bk, bb;
    int inc;
    int end, to;
    int delta, inc_2;
    int sq;

    // load

    wk = *list++;
    wp = *list++;
    bk = *list++;
    bb = *list++;

    // blocked pawn?

    inc = PAWN_MOVE_INC(0);
    end = PAWN_PROMOTE(wp, 0) + inc;

    for ( to = wp + inc; to != end; to += inc )
        {
        if(to == bb)
            return true; // direct blockade

        delta = to - bb;

        if(PSEUDO_ATTACK(((1 << 5) | (1 << 1)), delta))
            {

            inc_2 = DELTA_INC_ALL(delta);

            sq = bb;

            do
                {
                sq += inc_2;

                if(sq == to)
                    return true; // indirect blockade
                } while (sq != bk);
            }
        }

    return false;
    }

// draw_kpkn()

static bool draw_kpkn(const int list [], int turn)
    {

    int wk, wp, bk, bn;
    int inc;
    int end;
    int file;
    int sq;

    // load

    wk = *list++;
    wp = *list++;
    bk = *list++;
    bn = *list++;

    // blocked pawn?

    inc = PAWN_MOVE_INC(0);
    end = PAWN_PROMOTE(wp, 0) + inc;

    file = SQUARE_FILE(wp);

    if(file == (0x4) || file == (0xB))
        end -= inc;

    for ( sq = wp + inc; sq != end; sq += inc )
        {
        if(sq == bn || PSEUDO_ATTACK(((1 << 4) | (1 << 1)), sq - bn))
            return true; // blockade
        }

    return false;
    }

// draw_knpk()

static bool draw_knpk(const int list [], int turn)
    {

    int wk, wn, wp, bk;

    // load

    wk = *list++;
    wn = *list++;
    wp = *list++;
    bk = *list++;

    // test

    if(wp == (0xA4) && DISTANCE(bk, (0xB4)) <= 1)
        return true;

    return false;
    }

// draw_krpkr()

static bool draw_krpkr(const int list [], int turn)
    {

    int wk, wr, wp, bk, br;
    int wp_file, wp_rank;
    int bk_file, bk_rank;
    int br_file, br_rank;
    int prom;

    // load

    wk = *list++;
    wr = *list++;
    wp = *list++;
    bk = *list++;
    br = *list++;

    // test

    wp_file = SQUARE_FILE(wp);
    wp_rank = SQUARE_RANK(wp);

    bk_file = SQUARE_FILE(bk);
    bk_rank = SQUARE_RANK(bk);

    br_file = SQUARE_FILE(br);
    br_rank = SQUARE_RANK(br);

    prom = PAWN_PROMOTE(wp, 0);

    if(false) { }
    else if(bk == prom)
        {

        // TODO: rook near (0x4) if wp_rank == (0x9)?

        if(br_file > wp_file)
            return true;
        }
    else if(bk_file == wp_file && bk_rank > wp_rank)
        {

        return true;
        }
    else if(wr == prom && wp_rank == (0xA) && (bk == (0xAA) || bk == (0xAB)) && br_file == wp_file)
        {
        if(br_rank <= (0x6))
            {
            if(DISTANCE(wk, wp) > 1)
                return true;
            }
        else
            { // br_rank >= (0x7)
            if(DISTANCE(wk, wp) > 2)
                return true;
            }
        }

    return false;
    }

// draw_kbpkb()

static bool draw_kbpkb(const int list [], int turn)
    {

    int wk, wb, wp, bk, bb;
    int inc;
    int end, to;
    int delta, inc_2;
    int sq;

    // load

    wk = *list++;
    wb = *list++;
    wp = *list++;
    bk = *list++;
    bb = *list++;

    // opposit color?

    if(SQUARE_COLOUR(wb) == SQUARE_COLOUR(bb))
        return false; // TODO

    // blocked pawn?

    inc = PAWN_MOVE_INC(0);
    end = PAWN_PROMOTE(wp, 0) + inc;

    for ( to = wp + inc; to != end; to += inc )
        {
        if(to == bb)
            return true; // direct blockade

        delta = to - bb;

        if(PSEUDO_ATTACK(((1 << 5) | (1 << 1)), delta))
            {

            inc_2 = DELTA_INC_ALL(delta);

            sq = bb;

            do
                {
                sq += inc_2;

                if(sq == to)
                    return true; // indirect blockade
                } while (sq != bk);
            }
        }

    return false;
    }

// shelter_square()

static int shelter_square(const board_t *board, int square, int color)
    {

    int penalty;
    int file, rank;

    penalty = 0;

    file = SQUARE_FILE(square);
    rank = PAWN_RANK(square, color);

    penalty += shelter_file(board, file, rank, color) * 2;

    if(file != (0x4))
        penalty += shelter_file(board, file - 1, rank, color);

    if(file != (0xB))
        penalty += shelter_file(board, file + 1, rank, color);

    if(penalty == 0)
        penalty = 11; // weak back rank

    penalty += storm_file(board, file, color);

    if(file != (0x4))
        penalty += storm_file(board, file - 1, color);

    if(file != (0xB))
        penalty += storm_file(board, file + 1, color);

    return penalty;
    }

// shelter_file()

static int shelter_file(const board_t *board, int file, int rank, int color)
    {

    int dist;
    int penalty;

    dist = BIT_FIRST(board->pawn_file[color][file] & bit_ge[rank]);
    dist = (0xB) - dist;
    penalty = 36 - dist * dist;

    return penalty;
    }

// storm_file()

static int storm_file(const board_t *board, int file, int color)
    {

    int dist;
    int penalty;

    dist = BIT_LAST(board->pawn_file[COLOUR_OPP(color)][file]);
    penalty = 0;

    switch(dist)
        {
        case (0x7):
            penalty = 10 * 1;
            break;

        case (0x8):
            penalty = 10 * 2;
            break;

        case (0x9):
            penalty = 10 * 3;
            break;
        }

    return penalty;
    }

// bishop_can_attack()

static bool bishop_can_attack(const board_t *board, int to, int color)
    {

    const sq_t *ptr;
    int from;
    int piece;

    for ( ptr = &board->piece[color][1]; (from = *ptr) != 0; ptr++ )
        {

        piece = board->square[from];

        if(PIECE_IS_BISHOP(piece) && SQUARE_COLOUR(from) == SQUARE_COLOUR(to))
            {
            return true;
            }
        }

    return false;
    }

// end of eval.cpp

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -