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