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

📄 check.cpp

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

// includes

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

// prototypes

static void add_quiet_checks(list_t *list, const board_t *board);
static void add_castle_checks(list_t *list, board_t *board);
static void add_check(list_t *list, int move, board_t *board);
static void find_pins(int list [], const board_t *board);

// functions

// gen_quiet_checks()

void gen_quiet_checks(list_t *list, board_t *board)
    {

    LIST_CLEAR(list);

    add_quiet_checks(list, board);
    add_castle_checks(list, board);
    }

// add_quiet_checks()

static void add_quiet_checks(list_t *list, const board_t *board)
    {

    int me, opp;
    int king;
    const sq_t *ptr, *ptr_2;
    int from, to, sq;
    int piece;
    const inc_t *inc_ptr;
    int inc;
    int pawn;
    int rank;
    int pin[8 + 1];

    // init

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

    king = KING_POS(board, opp);

    find_pins(pin, board);

    // indirect checks

    for ( ptr = pin; (from = *ptr) != 0; ptr++ )
        {

        piece = board->square[from];

        if(PIECE_IS_PAWN(piece))
            {
            inc = PAWN_MOVE_INC(me);
            rank = PAWN_RANK(from, me);

            if(rank != (0xA))
                { // promotes are generated with captures
                to = from + inc;

                if(board->square[to] == 0)
                    {
                    if(DELTA_INC_LINE(to - king) != DELTA_INC_LINE(from - king))
                        {
                        LIST_ADD(list, MOVE_MAKE(from, to));

                        if(rank == (0x5))
                            {
                            to = from + (2 * inc);

                            if(board->square[to] == 0)
                                {
                                LIST_ADD(list, MOVE_MAKE(from, to));
                                }
                            }
                        }
                    }
                }
            }
        else if(PIECE_IS_SLIDER(piece))
            {
            for ( inc_ptr = PIECE_INC(piece); (inc = *inc_ptr) != 0; inc_ptr++ )
                {
                for ( to = from + inc; board->square[to] == 0; to += inc )
                    {
                    LIST_ADD(list, MOVE_MAKE(from, to));
                    }
                }
            }
        else
            {
            for ( inc_ptr = PIECE_INC(piece); (inc = *inc_ptr) != 0; inc_ptr++ )
                {
                to = from + inc;

                if(board->square[to] == 0)
                    {
                    if(DELTA_INC_LINE(to - king) != DELTA_INC_LINE(from - king))
                        {
                        LIST_ADD(list, MOVE_MAKE(from, to));
                        }
                    }
                }
            }
        }

    // piece direct checks

    for ( ptr = &board->piece[me][1]; (from = *ptr) != 0; ptr++ )
        {
        for ( ptr_2 = pin; (sq = *ptr_2) != 0; ptr_2++ )
            {
            if(sq == from)
                goto next_piece;
            }

        piece = board->square[from];
        inc_ptr = PIECE_INC(piece);

        if(PIECE_IS_SLIDER(piece))
            {
            for (; (inc = *inc_ptr) != 0; inc_ptr++ )
                {
                for ( to = from + inc; board->square[to] == 0; to += inc )
                    {
                    if(PIECE_ATTACK(board, piece, to, king))
                        {
                        LIST_ADD(list, MOVE_MAKE(from, to));
                        }
                    }
                }
            }
        else
            {
            for (; (inc = *inc_ptr) != 0; inc_ptr++ )
                {
                to = from + inc;

                if(board->square[to] == 0)
                    {
                    if(PSEUDO_ATTACK(piece, king - to))
                        {
                        LIST_ADD(list, MOVE_MAKE(from, to));
                        }
                    }
                }
            }

        next_piece:
        ;
        }

    // pawn direct checks

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

    to = king - (inc - 1);
    from = to - inc;

    if(board->square[from] == pawn)
        {
        if(board->square[to] == 0)
            {
            LIST_ADD(list, MOVE_MAKE(from, to));
            }
        }
    else
        {
        from = to - (2 * inc);

        if(board->square[from] == pawn)
            {
            if(PAWN_RANK(from, me) == (0x5) && board->square[to] == 0 && board->square[from + inc] == 0)
                {
                LIST_ADD(list, MOVE_MAKE(from, to));
                }
            }
        }

    to = king - (inc + 1);
    from = to - inc;

    if(board->square[from] == pawn)
        {
        if(board->square[to] == 0)
            {
            LIST_ADD(list, MOVE_MAKE(from, to));
            }
        }
    else
        {
        from = to - (2 * inc);

        if(board->square[from] == pawn)
            {
            if(PAWN_RANK(from, me) == (0x5) && board->square[to] == 0 && board->square[from + inc] == 0)
                {
                LIST_ADD(list, MOVE_MAKE(from, to));
                }
            }
        }
    }

// add_castle_checks()

static void add_castle_checks(list_t *list, board_t *board)
    {
    if(COLOUR_IS_WHITE(board->turn))
        {
        if((board->flags &(1 << 0)) != 0 && board->square[(0x49)] == 0 && board->square[(0x4A)] == 0
            && !is_attacked(board, (0x49), 1))
            {
            add_check(list, MOVE_MAKE_FLAGS((0x48), (0x4A), (1 << 14)), board);
            }

        if((board->flags &(1 << 1)) != 0 && board->square[(0x47)] == 0 && board->square[(0x46)] == 0
            && board->square[(0x45)] == 0 && !is_attacked(board, (0x47), 1))
            {
            add_check(list, MOVE_MAKE_FLAGS((0x48), (0x46), (1 << 14)), board);
            }
        }
    else
        { // black
        if((board->flags &(1 << 2)) != 0 && board->square[(0xB9)] == 0 && board->square[(0xBA)] == 0
            && !is_attacked(board, (0xB9), 0))
            {
            add_check(list, MOVE_MAKE_FLAGS((0xB8), (0xBA), (1 << 14)), board);
            }

        if((board->flags &(1 << 3)) != 0 && board->square[(0xB7)] == 0 && board->square[(0xB6)] == 0
            && board->square[(0xB5)] == 0 && !is_attacked(board, (0xB7), 0))
            {
            add_check(list, MOVE_MAKE_FLAGS((0xB8), (0xB6), (1 << 14)), board);
            }
        }
    }

// add_check()

static void add_check(list_t *list, int move, board_t *board)
    {

    undo_t undo[1];
    move_do(board, move, undo);

    if(IS_IN_CHECK(board, board->turn))
        LIST_ADD(list, move);
    move_undo(board, move, undo);
    }

// move_is_check()

bool move_is_check(int move, board_t *board)
    {

    undo_t undo[1];
    bool check;
    int me, opp, king;
    int from, to, piece;

    // slow test for complex moves

    if(MOVE_IS_SPECIAL(move))
        {

        move_do(board, move, undo);
        check = IS_IN_CHECK(board, board->turn);
        move_undo(board, move, undo);

        return check;
        }

    // init

    me = board->turn;
    opp = COLOUR_OPP(me);
    king = KING_POS(board, opp);

    from = MOVE_FROM(move);
    to = MOVE_TO(move);
    piece = board->square[from];

    // direct check

    if(PIECE_ATTACK(board, piece, to, king))
        return true;

    // indirect check

    if(is_pinned(board, from, opp) && DELTA_INC_LINE(king - to) != DELTA_INC_LINE(king - from))
        {
        return true;
        }

    return false;
    }

// find_pins()

static void find_pins(int list [], const board_t *board)
    {

    int me, opp;
    int king;
    const sq_t *ptr;
    int from;
    int piece;
    int delta;
    int inc;
    int sq;
    int capture;
    int pin;

    // init

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

    king = KING_POS(board, opp);

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

        piece = board->square[from];

        delta = king - from;

        if(PSEUDO_ATTACK(piece, delta))
            {

            inc = DELTA_INC_LINE(delta);
            sq = from;
            do sq += inc;

            while((capture = board->square[sq]) == 0);

            if(COLOUR_IS(capture, me))
                {
                pin = sq;
                do sq += inc;

                while(board->square[sq] == 0);

                if(sq == king)
                    * list++ = pin;
                }
            }
        }

    *list = 0;
    }

// end of move_check.cpp

⌨️ 快捷键说明

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