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

📄 evasion.cpp

📁 超强国际象棋引擎
💻 CPP
字号:
// move_evasion.cpp

// includes

#include "move.h"
#include "move_gen.h"

#pragma warning( disable : 4244 )
// Level 2 conversion from 'int' to 'short', possible loss of data ->

// prototypes

static bool gen_evasions(list_t *list, const board_t *board, const attack_t *attack, bool legal, bool stop);
static bool add_pawn_moves(list_t *list, const board_t *board, int to, bool legal, bool stop);
static bool add_pawn_captures(list_t *list, const board_t *board, int to, bool legal, bool stop);
static bool add_piece_moves(list_t *list, const board_t *board, int to, bool legal, bool stop);

// functions

// gen_legal_evasions()

void gen_legal_evasions(list_t *list, const board_t *board, const attack_t *attack)
    {

    gen_evasions(list, board, attack, true, false);
    }

// gen_pseudo_evasions()

void gen_pseudo_evasions(list_t *list, const board_t *board, const attack_t *attack)
    {

    gen_evasions(list, board, attack, false, false);
    }

// legal_evasion_exist()

bool legal_evasion_exist(const board_t *board, const attack_t *attack)
    {

    list_t list[1]; // dummy
    return gen_evasions(list, board, attack, true, true);
    }

// gen_evasions()

static bool gen_evasions(list_t *list, const board_t *board, const attack_t *attack, bool legal, bool stop)
    {

    int me, opp;
    int opp_flag;
    int king;
    const inc_t *inc_ptr;
    int inc;
    int to;
    int piece;

    // init

    LIST_CLEAR(list);

    me = board->turn;
    opp = COLOUR_OPP(me);

    opp_flag = COLOUR_FLAG(opp);

    king = KING_POS(board, me);

    for ( inc_ptr = king_inc; (inc = *inc_ptr) != 0; inc_ptr++ )
        {
        if(inc != -attack->di[0] && inc != -attack->di[1])
            { // avoid escaping along a check line
            to = king + inc;
            piece = board->square[to];

            if(piece == 0 || FLAG_IS(piece, opp_flag))
                {
                if(!legal || !is_attacked(board, to, opp))
                    {
                    if(stop)
                        return true;
                    LIST_ADD(list, MOVE_MAKE(king, to));
                    }
                }
            }
        }

    if(attack->dn >= 2)
        return false; // double check, we are done

    // single check
    // capture the checking piece

    if(add_pawn_captures(list, board, attack->ds[0], legal, stop) && stop)
        return true;

    if(add_piece_moves(list, board, attack->ds[0], legal, stop) && stop)
        return true;

    // interpose a piece

    inc = attack->di[0];

    if(inc != 0)
        { // line
        for ( to = king + inc; to != attack->ds[0]; to += inc )
            {
            if(add_pawn_moves(list, board, to, legal, stop) && stop)
                return true;

            if(add_piece_moves(list, board, to, legal, stop) && stop)
                return true;
            }
        }

    return false;
    }

// add_pawn_moves()

static bool add_pawn_moves(list_t *list, const board_t *board, int to, bool legal, bool stop)
    {

    int me;
    int inc;
    int pawn;
    int from;
    int piece;

    me = board->turn;

    inc = PAWN_MOVE_INC(me);
    pawn = PAWN_MAKE(me);

    from = to - inc;
    piece = board->square[from];

    if(piece == pawn)
        { // single push
        if(!legal || !is_pinned(board, from, me))
            {
            if(stop)
                return true;
            add_pawn_move(list, from, to);
            }
        }
    else if(piece == 0 && PAWN_RANK(to, me) == (0x7))
        { // double push

        from = to - (2 * inc);

        if(board->square[from] == pawn)
            {
            if(!legal || !is_pinned(board, from, me))
                {
                if(stop)
                    return true;

                LIST_ADD(list, MOVE_MAKE(from, to));
                }
            }
        }

    return false;
    }

// add_pawn_captures()

static bool add_pawn_captures(list_t *list, const board_t *board, int to, bool legal, bool stop)
    {

    int me;
    int inc;
    int pawn;
    int from;

    me = board->turn;

    inc = PAWN_MOVE_INC(me);
    pawn = PAWN_MAKE(me);

    from = to - (inc - 1);

    if(board->square[from] == pawn)
        {
        if(!legal || !is_pinned(board, from, me))
            {
            if(stop)
                return true;
            add_pawn_move(list, from, to);
            }
        }

    from = to - (inc + 1);

    if(board->square[from] == pawn)
        {
        if(!legal || !is_pinned(board, from, me))
            {
            if(stop)
                return true;
            add_pawn_move(list, from, to);
            }
        }

    if(board->ep_square != 0 && to == SQUARE_EP_DUAL(board->ep_square))
        {

        to = board->ep_square;
        from = to - (inc - 1);

        if(board->square[from] == pawn)
            {
            if(!legal || !is_pinned(board, from, me))
                {
                if(stop)
                    return true;

                LIST_ADD(list, MOVE_MAKE_FLAGS(from, to, (3 << 14)));
                }
            }

        from = to - (inc + 1);

        if(board->square[from] == pawn)
            {
            if(!legal || !is_pinned(board, from, me))
                {
                if(stop)
                    return true;

                LIST_ADD(list, MOVE_MAKE_FLAGS(from, to, (3 << 14)));
                }
            }
        }

    return false;
    }

// add_piece_moves()

static bool add_piece_moves(list_t *list, const board_t *board, int to, bool legal, bool stop)
    {

    int me;
    const sq_t *ptr;
    int from, piece;

    me = board->turn;

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

        piece = board->square[from];

        if(PIECE_ATTACK(board, piece, from, to))
            {
            if(!legal || !is_pinned(board, from, me))
                {
                if(stop)
                    return true;

                LIST_ADD(list, MOVE_MAKE(from, to));
                }
            }
        }

    return false;
    }

// end of move_evasion.cpp

⌨️ 快捷键说明

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