add move_make_promote_capture and move_make_capture

This commit is contained in:
2024-03-11 16:10:16 +01:00
parent 301ca24783
commit 890cb05296
2 changed files with 121 additions and 87 deletions

View File

@@ -27,18 +27,6 @@
#include "move-gen.h" #include "move-gen.h"
/**
* gen_castle() - generate c
* @pos: position
*
* Generate all pseudo pawn pushes.
*/
//int gen_pawn_push(pos_t *pos, bitboard_t occ)
//{
//}
/** /**
* pseudo_is_legal() - check if a move is legal. * pseudo_is_legal() - check if a move is legal.
* @pos: position * @pos: position
@@ -47,10 +35,11 @@
* We check all possible invalid moves: * We check all possible invalid moves:
* (1) King: * (1) King:
* - K moves to a controlled square * - K moves to a controlled square
* - Castling: * (1) Castling:
* - K passes a controlled square - already done in pseudomove gen * - K passes a controlled square - already done in pseudomove gen
* *
* (2) En-passant: *
* (3) En-passant:
* - pinned taking pawn, done in (3) * - pinned taking pawn, done in (3)
* - taking and taken pawn on same rank than king, discovered check on rank * - taking and taken pawn on same rank than king, discovered check on rank
* *
@@ -103,10 +92,21 @@ bool pseudo_is_legal(pos_t *pos, move_t move)
* gen_all_pseudomoves() - generate all pseudo moves * gen_all_pseudomoves() - generate all pseudo moves
* @pos: position * @pos: position
* *
* Generate all moves, no check is done on validity due to castle rules, * Generate all @pos pseudo moves for player-to-move.
* or check (pinned pieces, etc...). * The @pos->moves table is filled with the moves.
* *
* @return: The number of moves. * Only a few validity checks are done here (i.e. moves are not generated):
* - castling, if king is in check
* - castling, if king passes an enemy-controlled square (not final square).
* When immediately known, a few move flags are also applied in these cases:
* - castling: M_CASTLE_{K,Q}
* - pawn capture (incl. en-passant): M_CAPTURE
* - promotion: M_PROMOTION
* - promotion and capture
*
* TODO: move code to specific functions (especially castling, pawn push/capture)
*
* @Return: The total number of moves.
*/ */
int gen_all_pseudomoves(pos_t *pos) int gen_all_pseudomoves(pos_t *pos)
{ {
@@ -127,7 +127,7 @@ int gen_all_pseudomoves(pos_t *pos)
int from, to; int from, to;
/* king */ /* 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, tmp2, movebits) {
@@ -187,11 +187,28 @@ int gen_all_pseudomoves(pos_t *pos)
//printf("push %d->%d %s->%s", from, to, sq_to_string(from), sq_to_string(to)); //printf("push %d->%d %s->%s", from, to, sq_to_string(from), sq_to_string(to));
moves[nmoves++] = move_make(from, to); moves[nmoves++] = move_make(from, to);
} }
/* possible second push */
movebits = pawn_shift_up(movebits & rel_rank3, us) & empty; movebits = pawn_shift_up(movebits & rel_rank3, us) & empty;
bit_for_each64(to, tmp1, movebits) { bit_for_each64(to, tmp1, movebits) {
from = pawn_push_up(pawn_push_up(to, them), them); from = pawn_push_up(pawn_push_up(to, them), them);
moves[nmoves++] = move_make(from, to); moves[nmoves++] = move_make(from, to);
} }
/* pawn: ranks 2-6 captures left, including en-passant */
from_pawns = pos->bb[us][PAWN] & ~rel_rank7; // & ~rel_filea;
movebits = pawn_shift_upleft(from_pawns, us) & enemy_avail;
bit_for_each64(to, tmp1, movebits) {
from = pawn_push_upleft(to, them); /* reverse capture */
moves[nmoves++] = move_make_capture(from, to);
}
/* pawn: ranks 2-6 captures right, including en-passant */
from_pawns = pos->bb[us][PAWN] & ~rel_rank7; // & ~rel_fileh;
movebits = pawn_shift_upright(from_pawns, us) & enemy_avail;
bit_for_each64(to, tmp1, movebits) {
from = pawn_push_upright(to, them);
moves[nmoves++] = move_make_capture(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) {
@@ -201,44 +218,28 @@ int gen_all_pseudomoves(pos_t *pos)
moves[nmoves++] = move_make_promote(from, to, BISHOP); moves[nmoves++] = move_make_promote(from, to, BISHOP);
moves[nmoves++] = move_make_promote(from, to, KNIGHT); moves[nmoves++] = move_make_promote(from, to, KNIGHT);
} }
/* pawn promotion: rank 7 captures left */
/* pawn: ranks 2-6 captures left, including en-passant */
from_pawns = pos->bb[us][PAWN] & ~rel_rank7; // & ~rel_filea;
movebits = pawn_shift_upleft(from_pawns, us) & enemy_avail;
bit_for_each64(to, tmp1, movebits) {
from = pawn_push_upleft(to, them); /* reverse capture */
moves[nmoves++] = move_make(from, to);
}
/* pawn: 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_avail;
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(from, to, QUEEN); moves[nmoves++] = move_make_promote_capture(from, to, QUEEN);
moves[nmoves++] = move_make_promote(from, to, ROOK); moves[nmoves++] = move_make_promote_capture(from, to, ROOK);
moves[nmoves++] = move_make_promote(from, to, BISHOP); moves[nmoves++] = move_make_promote_capture(from, to, BISHOP);
moves[nmoves++] = move_make_promote(from, to, KNIGHT); moves[nmoves++] = move_make_promote_capture(from, to, KNIGHT);
}
/* pawn: ranks 2-6 captures right, including en-passant */
from_pawns = pos->bb[us][PAWN] & ~rel_rank7; // & ~rel_fileh;
movebits = pawn_shift_upright(from_pawns, us) & enemy_avail;
bit_for_each64(to, tmp1, movebits) {
from = pawn_push_upright(to, them);
moves[nmoves++] = move_make(from, to);
} }
/* pawn: rank 7 captures right */ /* pawn: rank 7 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_pieces; 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); /* reverse capture */ from = pawn_push_upright(to, them); /* reverse capture */
moves[nmoves++] = move_make_promote(from, to, QUEEN); moves[nmoves++] = move_make_promote_capture(from, to, QUEEN);
moves[nmoves++] = move_make_promote(from, to, ROOK); moves[nmoves++] = move_make_promote_capture(from, to, ROOK);
moves[nmoves++] = move_make_promote(from, to, BISHOP); moves[nmoves++] = move_make_promote_capture(from, to, BISHOP);
moves[nmoves++] = move_make_promote(from, to, KNIGHT); moves[nmoves++] = move_make_promote_capture(from, to, KNIGHT);
} }
/* castle - Attention ! We consider that castle flags are correct, /* castle - Attention ! Castling flags are assumed correct
*/ */
if (!pos->checkers) { if (!pos->checkers) {
bitboard_t rel_rank1 = BB_REL_RANK(RANK_1, us); bitboard_t rel_rank1 = BB_REL_RANK(RANK_1, us);

View File

@@ -19,50 +19,52 @@
#include "board.h" #include "board.h"
/* move structure: /* move structure:
* 3 2 2 1 1 1 1 1 1 * 3 2 2 1 1 1 1 1 1
* 1 5 4 8 7 5 4 2 1 6 5 0 * 1 5 3 8 7 5 4 2 1 6 5 0
* UUUUUUU FFFFFFF ppp ccc tttttt ffffff * UUUUUUUU FFFFFF ppp ccc tttttt ffffff
* *
* bits range type mask get desc * bits len range type mask get desc
* ffffff 0-5 square_t 3f &63 from * ffffff 6 0-5 square_t 3f &63 from
* tttttt 6-11 square_t fc0 (>>6)&63 to * tttttt 6 6-11 square_t fc0 (>>6)&63 to
* ccc 12-14 piece_type_t 7000 (>>12)&7 captured * ccc 3 12-14 piece_type_t 7000 (>>12)&7 captured
* ppp 15-17 piece_type_t 38000 (>>15)&7 promoted * ppp 3 15-17 piece_type_t 38000 (>>15)&7 promoted
* FFFFFFF 18-24 N/A 1fc0000 N/A flags * FFFFFF 6 18-23 move_flags_t fc0000 N/A flags
* UUUUUUU 25-31 unused fe000000 N/A future usage ? * UUUUUUUU 8 24-31 unused fe000000 N/A future usage ?
*/ */
#define move_t u32 typedef u32 move_t;
/* move flags */ typedef enum {
#define M_FLAGS_BEG 18 M_START = 18,
#define M_HAS_FLAGS mask(M_FLAGS_BEG + 0) /* probably unused */ M_CAPTURE = (1 << (M_START + 0)),
#define M_CAPTURE mask(M_FLAGS_BEG + 1) M_ENPASSANT = (1 << (M_START + 1)),
#define M_EPASSANT mask(M_FLAGS_BEG + 2) M_PROMOTION = (1 << (M_START + 2)),
#define M_PROMOTE mask(M_FLAGS_BEG + 3) M_CASTLE_K = (1 << (M_START + 3)), /* maybe only one ? */
#define M_CASTLE_K mask(M_FLAGS_BEG + 4) M_CASTLE_Q = (1 << (M_START + 4)), /* maybe only one ? */
#define M_CASTLE_Q mask(M_FLAGS_BEG + 5) M_CHECK = (1 << (M_START + 5)) /* maybe unknown/useless ? */
#define M_CHECK mask(M_FLAGS_BEG + 6) /* probably unknown/useless */ } move_type_t;
#define M_FLAGS (M_CAPTURE | M_ENPASSANT | M_PROMOTION | \
M_CASTLE_K | M_CASTLE_Q | M_CHECK)
#define M_NORMAL (~M_FLAGS)
#define MOVES_MAX 256 #define MOVES_MAX 256
static inline move_t move_make(square_t from, square_t to) typedef struct __movelist_s {
{ move_t move[MOVES_MAX];
return (to << 6) | from; int nmoves; /* total moves (fill) */
} int curmove; /* current move (use) */
} movelist_t;
static inline move_t move_make_flags(square_t from, square_t to, int flags)
{
return move_make(from, to) | flags;
}
static inline move_t move_make_promote(square_t from, square_t to, piece_type_t piece) /* move flags */
{ //#define M_FLAGS_BEG 18
return move_make(from, to) | M_PROMOTE | (piece << 15); //#define M_HAS_FLAGS mask(M_FLAGS_BEG + 0) /* probably useless */
} //#define M_CAPTURE mask(M_FLAGS_BEG + 0)
//#define M_EN_PASSANT mask(M_FLAGS_BEG + 1)
//#define M_PROMOTION mask(M_FLAGS_BEG + 2)
//#define M_CASTLE_K mask(M_FLAGS_BEG + 3) /* maybe only one ? */
//#define M_CASTLE_Q mask(M_FLAGS_BEG + 4) /* maybe only one ? */
//#define M_CHECK mask(M_FLAGS_BEG + 5) /* probably unknown/useless */
//#define M_FLAGS (M_CAPTURE | M_ENPASSANT | M_PROMOTION |
// M_CASTLE_K | M_CASTLE_Q | M_CHECK)
//#define M_NORMAL (~M_FLAGS)
static inline square_t move_from(move_t move) static inline square_t move_from(move_t move)
{ {
@@ -73,6 +75,43 @@ static inline square_t move_to(move_t move)
return (move >> 6) & 077; return (move >> 6) & 077;
} }
static inline piece_t move_promoted(move_t move)
{
return (move >> 15) & 07;
}
static inline piece_t move_captured(move_t move)
{
return (move >> 12) & 07;
}
static inline move_t move_make(square_t from, square_t to)
{
return (to << 6) | from;
}
static inline move_t move_make_flags(square_t from, square_t to, move_type_t flags)
{
return move_make(from, to) | flags;
}
static inline move_t move_make_capture(square_t from, square_t to)
{
return move_make_flags(from, to, M_CAPTURE);
}
static inline move_t move_make_promote(square_t from, square_t to,
piece_type_t promoted)
{
return move_make_flags(from, to, M_PROMOTION) | (promoted << 15);
}
static inline move_t move_make_promote_capture(square_t from, square_t to,
piece_type_t promoted)
{
return move_make_flags(from, to, M_CAPTURE | M_PROMOTION) | (promoted << 15);
}
/* moves_print flags /* moves_print flags
*/ */
#define M_PR_CAPT 0x01 #define M_PR_CAPT 0x01
@@ -83,12 +122,6 @@ static inline square_t move_to(move_t move)
#define M_PR_SEPARATE 0x40 /* separate captures */ #define M_PR_SEPARATE 0x40 /* separate captures */
#define M_PR_LONG 0x80 #define M_PR_LONG 0x80
typedef struct __movelist_s {
move_t move[MOVES_MAX];
int nmoves; /* total moves (fill) */
int curmove; /* current move (use) */
} movelist_t;
//pool_t *moves_pool_init(); //pool_t *moves_pool_init();
//void moves_pool_stats(); //void moves_pool_stats();