Compare commits
2 Commits
9c2e76442d
...
dc916f5c56
Author | SHA1 | Date | |
---|---|---|---|
dc916f5c56 | |||
748953a767 |
@@ -79,7 +79,7 @@ bool pseudo_is_legal(const pos_t *pos, const move_t move)
|
|||||||
* 5th relative rank. To do so, we create an occupation bb without
|
* 5th relative rank. To do so, we create an occupation bb without
|
||||||
* the 2 pawns.
|
* the 2 pawns.
|
||||||
*/
|
*/
|
||||||
if (is_capture(move) && PIECE(pos->board[to]) == EMPTY) {
|
if (is_enpassant(move)) {
|
||||||
/* from rank bitboard */
|
/* from rank bitboard */
|
||||||
bitboard_t rank5 = bb_sqrank[from];
|
bitboard_t rank5 = bb_sqrank[from];
|
||||||
/* enemy rooks/queens on from rank */
|
/* enemy rooks/queens on from rank */
|
||||||
@@ -158,6 +158,7 @@ movelist_t *pos_all_legal(const pos_t *pos, movelist_t *dest)
|
|||||||
* When immediately known, a few move flags are also applied in these cases:
|
* When immediately known, a few move flags are also applied in these cases:
|
||||||
* - castling: M_CASTLE_{K,Q}
|
* - castling: M_CASTLE_{K,Q}
|
||||||
* - pawn capture (incl. en-passant): M_CAPTURE
|
* - pawn capture (incl. en-passant): M_CAPTURE
|
||||||
|
* en-passant: M_EN_PASSANT
|
||||||
* - promotion: M_PROMOTION
|
* - promotion: M_PROMOTION
|
||||||
* - promotion and capture
|
* - promotion and capture
|
||||||
*
|
*
|
||||||
@@ -188,7 +189,7 @@ int pos_gen_pseudomoves(pos_t *pos)
|
|||||||
/* king - MUST BE FIRST ! */
|
/* king - MUST BE FIRST ! */
|
||||||
from = pos->king[us];
|
from = pos->king[us];
|
||||||
movebits = bb_king_moves(not_my_pieces, from);
|
movebits = bb_king_moves(not_my_pieces, from);
|
||||||
bit_for_each64(to, tmp2, movebits) {
|
bit_for_each64(to, tmp1, movebits) {
|
||||||
moves[nmoves++] = move_make(from, to);
|
moves[nmoves++] = move_make(from, to);
|
||||||
}
|
}
|
||||||
if (popcount64(pos->checkers) > 1) /* double check, we stop here */
|
if (popcount64(pos->checkers) > 1) /* double check, we stop here */
|
||||||
@@ -235,8 +236,6 @@ int pos_gen_pseudomoves(pos_t *pos)
|
|||||||
// sizeof(RANK_3bb));
|
// sizeof(RANK_3bb));
|
||||||
//bitboard_t rel_filea = (me == WHITE ? FILE_Abb : FILE_Hbb);
|
//bitboard_t rel_filea = (me == WHITE ? FILE_Abb : FILE_Hbb);
|
||||||
//bitboard_t rel_fileh = (me == WHITE ? FILE_Hbb : FILE_Abb);
|
//bitboard_t rel_fileh = (me == WHITE ? FILE_Hbb : FILE_Abb);
|
||||||
int en_passant = pos->en_passant == SQUARE_NONE? 0: pos->en_passant;
|
|
||||||
bitboard_t enemy_avail = bb_sq[en_passant] | enemy_pieces;
|
|
||||||
|
|
||||||
/* pawn: ranks 2-6 push 1 and 2 squares */
|
/* pawn: ranks 2-6 push 1 and 2 squares */
|
||||||
movebits = pawn_shift_up(pos->bb[us][PAWN] & ~rel_rank7, us) & empty;
|
movebits = pawn_shift_up(pos->bb[us][PAWN] & ~rel_rank7, us) & empty;
|
||||||
@@ -252,21 +251,31 @@ int pos_gen_pseudomoves(pos_t *pos)
|
|||||||
moves[nmoves++] = move_make(from, to);
|
moves[nmoves++] = move_make(from, to);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pawn: ranks 2-6 captures left, including en-passant */
|
/* pawn: ranks 2-6 captures left */
|
||||||
from_pawns = pos->bb[us][PAWN] & ~rel_rank7; // & ~rel_filea;
|
from_pawns = pos->bb[us][PAWN] & ~rel_rank7; // & ~rel_filea;
|
||||||
movebits = pawn_shift_upleft(from_pawns, us) & enemy_avail;
|
movebits = pawn_shift_upleft(from_pawns, us) & enemy_pieces;
|
||||||
bit_for_each64(to, tmp1, movebits) {
|
bit_for_each64(to, tmp1, movebits) {
|
||||||
from = pawn_push_upleft(to, them); /* reverse capture */
|
from = pawn_push_upleft(to, them); /* reverse capture */
|
||||||
moves[nmoves++] = move_make_capture(from, to);
|
moves[nmoves++] = move_make_capture(from, to);
|
||||||
}
|
}
|
||||||
/* pawn: ranks 2-6 captures right, including en-passant */
|
/* pawn: ranks 2-6 captures right */
|
||||||
from_pawns = pos->bb[us][PAWN] & ~rel_rank7; // & ~rel_fileh;
|
from_pawns = pos->bb[us][PAWN] & ~rel_rank7; // & ~rel_fileh;
|
||||||
movebits = pawn_shift_upright(from_pawns, us) & enemy_avail;
|
movebits = pawn_shift_upright(from_pawns, us) & enemy_pieces;
|
||||||
bit_for_each64(to, tmp1, movebits) {
|
bit_for_each64(to, tmp1, movebits) {
|
||||||
from = pawn_push_upright(to, them);
|
from = pawn_push_upright(to, them);
|
||||||
moves[nmoves++] = move_make_capture(from, to);
|
moves[nmoves++] = move_make_capture(from, to);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* pawn: en-passant */
|
||||||
|
if ((to = pos->en_passant) != SQUARE_NONE) {
|
||||||
|
movebits = mask(to);
|
||||||
|
from_pawns = pos->bb[us][PAWN]
|
||||||
|
& (pawn_shift_upleft(movebits, them) | pawn_shift_upright(movebits, them));
|
||||||
|
bit_for_each64(from, tmp1, from_pawns) {
|
||||||
|
moves[nmoves++] = move_make_enpassant(from, to);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* pawn: rank 7 push */
|
/* pawn: rank 7 push */
|
||||||
movebits = pawn_shift_up(pos->bb[us][PAWN] & rel_rank7, us) & empty;
|
movebits = pawn_shift_up(pos->bb[us][PAWN] & rel_rank7, us) & empty;
|
||||||
bit_for_each64(to, tmp1, movebits) {
|
bit_for_each64(to, tmp1, movebits) {
|
||||||
@@ -278,7 +287,7 @@ int pos_gen_pseudomoves(pos_t *pos)
|
|||||||
}
|
}
|
||||||
/* pawn promotion: rank 7 captures left */
|
/* pawn promotion: rank 7 captures left */
|
||||||
from_pawns = pos->bb[us][PAWN] & rel_rank7; // & ~rel_filea;
|
from_pawns = pos->bb[us][PAWN] & rel_rank7; // & ~rel_filea;
|
||||||
movebits = pawn_shift_upleft(from_pawns, us) & enemy_avail;
|
movebits = pawn_shift_upleft(from_pawns, us) & enemy_pieces;
|
||||||
bit_for_each64(to, tmp1, movebits) {
|
bit_for_each64(to, tmp1, movebits) {
|
||||||
from = pawn_push_upleft(to, them); /* reverse capture */
|
from = pawn_push_upleft(to, them); /* reverse capture */
|
||||||
moves[nmoves++] = move_make_promote_capture(from, to, QUEEN);
|
moves[nmoves++] = move_make_promote_capture(from, to, QUEEN);
|
||||||
|
61
src/move.h
61
src/move.h
@@ -39,28 +39,38 @@ typedef s32 move_t;
|
|||||||
#define MOVE_NULL (0) /* hack: from = to = A1 */
|
#define MOVE_NULL (0) /* hack: from = to = A1 */
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
M_OFF_FROM = 0,
|
M_OFF_FROM = 0,
|
||||||
M_OFF_TO = 6,
|
M_OFF_TO = 6,
|
||||||
M_OFF_PROM = 12,
|
M_OFF_PROMOTED = 12,
|
||||||
M_OFF_CAPT = 15,
|
M_OFF_CAPTURED = 15,
|
||||||
M_OFF_FLAGS = 18
|
M_OFF_FLAGS = 18
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
M_CAPTURE = mask(0),
|
M_CAPTURE = mask(M_OFF_FLAGS + 0),
|
||||||
M_ENPASSANT = mask(1),
|
M_ENPASSANT = mask(M_OFF_FLAGS + 1),
|
||||||
M_PROMOTION = mask(2),
|
M_PROMOTION = mask(M_OFF_FLAGS + 2),
|
||||||
M_CASTLE_K = mask(3), /* maybe only one ? */
|
M_CASTLE_K = mask(M_OFF_FLAGS + 3), /* maybe only one ? */
|
||||||
M_CASTLE_Q = mask(5), /* maybe only one ? */
|
M_CASTLE_Q = mask(M_OFF_FLAGS + 5), /* maybe only one ? */
|
||||||
M_CHECK = mask(6) /* maybe unknown/useless ? */
|
M_CHECK = mask(M_OFF_FLAGS + 6) /* maybe unknown/useless ? */
|
||||||
} move_flags_t;
|
} move_flags_t;
|
||||||
|
|
||||||
|
#define move_set_flags(move, flags) ((move) | (flags))
|
||||||
|
|
||||||
|
#define is_capture(m) ((m) & M_CAPTURE)
|
||||||
|
#define is_enpassant(m) ((m) & M_ENPASSANT)
|
||||||
|
#define is_promotion(m) ((m) & M_PROMOTION)
|
||||||
|
#define is_castle(m) ((m) & (M_CASTLE_K | M_CASTLE_Q))
|
||||||
|
#define is_castle_K(m) ((m) & M_CASTLE_K)
|
||||||
|
#define is_castle_Q(m) ((m) & M_CASTLE_Q)
|
||||||
|
#define is_check(m) ((m) & M_CHECK)
|
||||||
|
|
||||||
|
|
||||||
#define MOVES_MAX 256
|
#define MOVES_MAX 256
|
||||||
|
|
||||||
typedef struct __movelist_s {
|
typedef struct __movelist_s {
|
||||||
move_t move[MOVES_MAX];
|
move_t move[MOVES_MAX];
|
||||||
int nmoves; /* total moves (fill) */
|
int nmoves; /* total moves (fill) */
|
||||||
//int curmove; /* current move (use) */
|
|
||||||
} movelist_t;
|
} movelist_t;
|
||||||
|
|
||||||
static inline square_t move_from(move_t move)
|
static inline square_t move_from(move_t move)
|
||||||
@@ -75,26 +85,14 @@ static inline square_t move_to(move_t move)
|
|||||||
|
|
||||||
static inline piece_t move_promoted(move_t move)
|
static inline piece_t move_promoted(move_t move)
|
||||||
{
|
{
|
||||||
return (move >> M_OFF_PROM) & 07;
|
return (move >> M_OFF_PROMOTED) & 07;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline piece_type_t move_captured(move_t move)
|
static inline piece_type_t move_captured(move_t move)
|
||||||
{
|
{
|
||||||
return (move >> M_OFF_CAPT) & 07;
|
return (move >> M_OFF_CAPTURED) & 07;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline move_flags_t move_flags(move_t move)
|
|
||||||
{
|
|
||||||
return (move >> M_OFF_FLAGS) & 077;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define is_capture(m) (move_flags(m) & M_CAPTURE)
|
|
||||||
#define is_enpassant(m) (move_flags(m) & M_ENPASSANT)
|
|
||||||
#define is_promotion(m) (move_flags(m) & M_PROMOTION)
|
|
||||||
#define is_castle(m) (move_flags(m) & (M_CASTLE_K | M_CASTLE_Q))
|
|
||||||
#define is_castle_K(m) (move_flags(m) & M_CASTLE_K)
|
|
||||||
#define is_castle_Q(m) (move_flags(m) & M_CASTLE_Q)
|
|
||||||
#define is_check(m) (move_flags(m) & M_CHECK)
|
|
||||||
|
|
||||||
static inline move_t move_make(square_t from, square_t to)
|
static inline move_t move_make(square_t from, square_t to)
|
||||||
{
|
{
|
||||||
@@ -103,7 +101,7 @@ static inline move_t move_make(square_t from, square_t to)
|
|||||||
|
|
||||||
static inline move_t move_make_flags(square_t from, square_t to, move_flags_t flags)
|
static inline move_t move_make_flags(square_t from, square_t to, move_flags_t flags)
|
||||||
{
|
{
|
||||||
return move_make(from, to) | (flags << M_OFF_FLAGS);
|
return move_set_flags(move_make(from, to), flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline move_t move_make_capture(square_t from, square_t to)
|
static inline move_t move_make_capture(square_t from, square_t to)
|
||||||
@@ -111,16 +109,21 @@ static inline move_t move_make_capture(square_t from, square_t to)
|
|||||||
return move_make_flags(from, to, M_CAPTURE);
|
return move_make_flags(from, to, M_CAPTURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline move_t move_make_enpassant(square_t from, square_t to)
|
||||||
|
{
|
||||||
|
return move_make_flags(from, to, M_CAPTURE | M_ENPASSANT);
|
||||||
|
}
|
||||||
|
|
||||||
static inline move_t move_make_promote(square_t from, square_t to,
|
static inline move_t move_make_promote(square_t from, square_t to,
|
||||||
piece_type_t promoted)
|
piece_type_t promoted)
|
||||||
{
|
{
|
||||||
return move_make_flags(from, to, M_PROMOTION) | (promoted << M_OFF_PROM);
|
return move_make_flags(from, to, M_PROMOTION) | (promoted << M_OFF_PROMOTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline move_t move_make_promote_capture(square_t from, square_t to,
|
static inline move_t move_make_promote_capture(square_t from, square_t to,
|
||||||
piece_type_t promoted)
|
piece_type_t promoted)
|
||||||
{
|
{
|
||||||
return move_make_flags(from, to, M_CAPTURE | M_PROMOTION) | (promoted << M_OFF_PROM);
|
return move_make_promote(from, to, promoted) | M_CAPTURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* moves_print flags
|
/* moves_print flags
|
||||||
|
@@ -33,14 +33,14 @@ typedef struct __pos_s {
|
|||||||
/* data which cannot be recovered by move_undo
|
/* data which cannot be recovered by move_undo
|
||||||
* following data can be accessed either directly, either via "movesave"
|
* following data can be accessed either directly, either via "movesave"
|
||||||
* structure name.
|
* structure name.
|
||||||
* For example, pos->en_passant and pos->movesave.en_passant are the same.
|
* For example, pos->en_passant and pos->state.en_passant are the same.
|
||||||
* This allows a memcpy on this data (to save/restore position state).
|
* This allows a memcpy on this data (to save/restore position state).
|
||||||
*/
|
*/
|
||||||
struct_group_tagged(movesave, movesave,
|
struct_group_tagged(state_s, state,
|
||||||
square_t en_passant;
|
square_t en_passant;
|
||||||
castle_rights_t castle;
|
castle_rights_t castle;
|
||||||
u16 clock_50;
|
u16 clock_50;
|
||||||
u16 plycount; /* plies so far, start is 0 */
|
u16 plycount; /* plies so far, start from 1 */
|
||||||
);
|
);
|
||||||
|
|
||||||
piece_t board[BOARDSIZE];
|
piece_t board[BOARDSIZE];
|
||||||
@@ -54,6 +54,8 @@ typedef struct __pos_s {
|
|||||||
movelist_t moves;
|
movelist_t moves;
|
||||||
} pos_t;
|
} pos_t;
|
||||||
|
|
||||||
|
typedef struct state_s state_t;
|
||||||
|
|
||||||
#define pos_pinned(p) (p->blockers & p->bb[p->turn][ALL_PIECES])
|
#define pos_pinned(p) (p->blockers & p->bb[p->turn][ALL_PIECES])
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user