📄 check.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 + -