move.h: simplify flags. movegen.c: add pos_next_legal()
This commit is contained in:
@@ -34,7 +34,7 @@
|
||||
*
|
||||
* @return: true if move is valid, false otherwise.
|
||||
*/
|
||||
bool pseudo_is_legal(pos_t *pos, move_t move)
|
||||
bool pseudo_is_legal(const pos_t *pos, const move_t move)
|
||||
{
|
||||
color_t us = pos->turn, them = OPPONENT(us);
|
||||
square_t from = move_from(move), to = move_to(move), king = pos->king[us], sq;
|
||||
@@ -79,7 +79,7 @@ bool pseudo_is_legal(pos_t *pos, move_t move)
|
||||
* 5th relative rank. To do so, we create an occupation bb without
|
||||
* the 2 pawns.
|
||||
*/
|
||||
if (move & M_CAPTURE && PIECE(pos->board[to]) == EMPTY) {
|
||||
if (IS_CAPTURE(move) && PIECE(pos->board[to]) == EMPTY) {
|
||||
/* from rank bitboard */
|
||||
bitboard_t rank5 = bb_sqrank[from];
|
||||
/* enemy rooks/queens on from rank */
|
||||
@@ -100,6 +100,51 @@ bool pseudo_is_legal(pos_t *pos, move_t move)
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* pos_next_legal() - get next legal move in position.
|
||||
* @pos: position
|
||||
* @start: &int, starting position in move list
|
||||
*
|
||||
* Get next valid move in @pos move list, from move @start, or MOVE_NONE.
|
||||
* @start is set to next non-checked move in pseudo-legal list.
|
||||
* Position pseudo-legal moves must be already calculated before calling this function.
|
||||
*
|
||||
* @return: move, or -1 if no move.
|
||||
*/
|
||||
move_t pos_next_legal(const pos_t *pos, int *start)
|
||||
{
|
||||
int nmoves = pos->moves.nmoves;
|
||||
const move_t *moves = pos->moves.move;
|
||||
|
||||
while (*start < nmoves) {
|
||||
move_t move = moves[*start];
|
||||
++*start;
|
||||
if (pseudo_is_legal(pos, move))
|
||||
return move;
|
||||
}
|
||||
return MOVE_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* pos_all_legal() - get the list of legal moves from pseudo-legal.
|
||||
* @pos: position
|
||||
* @dest: destination &movelist_t
|
||||
*
|
||||
* The pseudo-legal moves must be already calculated before calling this function.
|
||||
*
|
||||
* @Return: @dest
|
||||
*/
|
||||
movelist_t *pos_all_legal(const pos_t *pos, movelist_t *dest)
|
||||
{
|
||||
dest->nmoves = 0;
|
||||
move_t move;
|
||||
int tmp = 0;
|
||||
|
||||
while ((move = pos_next_legal(pos, &tmp)) != MOVE_NONE)
|
||||
dest->move[dest->nmoves++] = move;
|
||||
return dest;
|
||||
}
|
||||
|
||||
/**
|
||||
* pos_gen_pseudomoves() - generate position pseudo-legal moves
|
||||
* @pos: position
|
||||
@@ -290,24 +335,3 @@ int pos_gen_pseudomoves(pos_t *pos)
|
||||
*/
|
||||
return (pos->moves.nmoves = nmoves);
|
||||
}
|
||||
|
||||
/**
|
||||
* pos_legalmoves() - generate position legal moves from pseudo-legal ones.
|
||||
* @pos: position
|
||||
* @dest: address where to store legal moves
|
||||
*
|
||||
* The pseudo-legal moves must be already calculated before calling this function.
|
||||
*
|
||||
* @Return: @dest
|
||||
*/
|
||||
movelist_t *pos_legalmoves(pos_t *pos, movelist_t *dest)
|
||||
{
|
||||
int pseudo;
|
||||
movelist_t *src = &pos->moves;
|
||||
dest->nmoves = 0;
|
||||
for (pseudo = 0; pseudo < src->nmoves; ++pseudo) {
|
||||
if (pseudo_is_legal(pos, src->move[pseudo]))
|
||||
dest->move[dest->nmoves++] = src->move[pseudo];
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
@@ -21,8 +21,9 @@
|
||||
#include "piece.h"
|
||||
#include "move.h"
|
||||
|
||||
extern bool pseudo_is_legal(pos_t *pos, move_t move);
|
||||
extern int pos_gen_pseudomoves(pos_t *pos);
|
||||
extern movelist_t *pos_legalmoves(pos_t *pos, movelist_t *dest);
|
||||
bool pseudo_is_legal(const pos_t *pos, const move_t move);
|
||||
move_t pos_next_legal(const pos_t *pos, int *start);
|
||||
movelist_t *pos_all_legal(const pos_t *pos, movelist_t *dest);
|
||||
int pos_gen_pseudomoves(pos_t *pos);
|
||||
|
||||
#endif /* MOVEGEN_H */
|
||||
|
@@ -107,11 +107,11 @@ char *move_str(char *dst, const move_t move, __unused const int flags)
|
||||
square_t from = move_from(move);
|
||||
square_t to = move_to(move);
|
||||
int len;
|
||||
sprintf(dst, "%s-%s%n", sq_to_string(from), sq_to_string(to), &len);
|
||||
sprintf(dst, "%s%s%n", sq_to_string(from), sq_to_string(to), &len);
|
||||
|
||||
if (move & M_PROMOTION) {
|
||||
if (IS_PROMOTION(move)) {
|
||||
piece_t promoted = move_promoted(move);
|
||||
sprintf(dst + len, "=%s", piece_to_low(promoted));
|
||||
sprintf(dst + len, "%s", piece_to_low(promoted));
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
@@ -127,7 +127,7 @@ char *move_str(char *dst, const move_t move, __unused const int flags)
|
||||
* M_PR_NCAPT: print move if non capture
|
||||
* M_PR_NUM: print also move number
|
||||
* M_PR_LONG: print long notation
|
||||
* M_PR_NL: print a newline after move
|
||||
* M_PR_NL: print a newline after each move
|
||||
* M_PR_EVAL: print move eval
|
||||
*/
|
||||
void moves_print(movelist_t *moves, __unused int flags)
|
||||
|
80
src/move.h
80
src/move.h
@@ -19,29 +19,52 @@
|
||||
#include "board.h"
|
||||
|
||||
/* move structure:
|
||||
* 3 2 2 1 1 1 1 1 1
|
||||
* 1 5 3 8 7 5 4 2 1 6 5 0
|
||||
* UUUUUUUU FFFFFF ccc ppp tttttt ffffff
|
||||
* 3 3 2 2 1 1 1 1 1 1
|
||||
* 1 0 5 3 8 7 5 4 2 1 6 5 0
|
||||
* S UUUUUUU FFFFFF ccc ppp tttttt ffffff
|
||||
*
|
||||
* bits len range type mask get desc
|
||||
* ffffff 6 0-5 square_t 3f &63 from
|
||||
* tttttt 6 6-11 square_t fc0 (>>6)&63 to
|
||||
* ppp 3 15-17 piece_type_t 38000 (>>15)&7 promoted
|
||||
* ccc 3 12-14 piece_type_t 7000 (>>12)&7 captured
|
||||
* FFFFFF 6 18-23 move_flags_t fc0000 N/A flags
|
||||
* UUUUUUUU 8 24-31 unused fe000000 N/A future usage ?
|
||||
* bits len off range type mask get desc
|
||||
* ffffff 6 0 0-5 square_t 077 &63 from
|
||||
* tttttt 6 6 6-11 square_t 07700 (>>6)&63 to
|
||||
* ppp 3 12 12-14 piece_type_t 070000 (>>12)&7 promoted
|
||||
* ccc 3 15 15-17 piece_type_t 0700000 (>>15)&7 captured
|
||||
* FFFFFF 6 18 18-23 move_flags_t 077000000 (>>18)&63 N/A flags
|
||||
* UUUUUUU 7 24 24-30 unused 017700000000 future usage
|
||||
* S 1 31 31-31 - 020000000000 sign
|
||||
*/
|
||||
typedef u32 move_t;
|
||||
typedef s32 move_t;
|
||||
|
||||
/* special move_t values */
|
||||
#define MOVE_NONE (-1)
|
||||
#define MOVE_NULL (0) /* hack: from = to = A1 */
|
||||
|
||||
enum {
|
||||
M_OFF_FROM = 0,
|
||||
M_OFF_TO = 6,
|
||||
M_OFF_PROM = 12,
|
||||
M_OFF_CAPT = 15,
|
||||
M_OFF_FLAGS = 18
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
M_START = 18,
|
||||
M_CAPTURE = (1 << (M_START + 0)),
|
||||
M_ENPASSANT = (1 << (M_START + 1)),
|
||||
M_PROMOTION = (1 << (M_START + 2)),
|
||||
M_CASTLE_K = (1 << (M_START + 3)), /* maybe only one ? */
|
||||
M_CASTLE_Q = (1 << (M_START + 4)), /* maybe only one ? */
|
||||
M_CHECK = (1 << (M_START + 5)) /* maybe unknown/useless ? */
|
||||
} move_type_t;
|
||||
//M_INVALID = -1,
|
||||
//M_START = 18,
|
||||
M_CAPTURE = mask(0),
|
||||
M_ENPASSANT = mask(1),
|
||||
M_PROMOTION = mask(2),
|
||||
M_CASTLE_K = mask(3), /* maybe only one ? */
|
||||
M_CASTLE_Q = mask(5), /* maybe only one ? */
|
||||
M_CHECK = mask(6) /* maybe unknown/useless ? */
|
||||
} move_flags_t;
|
||||
|
||||
#define MOVE_FLAGS(m) ((m) >> M_OFF_FLAGS)
|
||||
#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)
|
||||
|
||||
#define MOVES_MAX 256
|
||||
|
||||
@@ -58,27 +81,27 @@ static inline square_t move_from(move_t move)
|
||||
|
||||
static inline square_t move_to(move_t move)
|
||||
{
|
||||
return (move >> 6) & 077;
|
||||
return (move >> M_OFF_TO) & 077;
|
||||
}
|
||||
|
||||
static inline piece_t move_promoted(move_t move)
|
||||
{
|
||||
return (move >> 12) & 07;
|
||||
return (move >> M_OFF_PROM) & 07;
|
||||
}
|
||||
|
||||
static inline piece_type_t move_captured(move_t move)
|
||||
{
|
||||
return (move >> 15) & 07;
|
||||
return (move >> M_OFF_CAPT) & 07;
|
||||
}
|
||||
|
||||
static inline move_t move_make(square_t from, square_t to)
|
||||
{
|
||||
return (to << 6) | from;
|
||||
return (to << M_OFF_TO) | from;
|
||||
}
|
||||
|
||||
static inline move_t move_make_flags(square_t from, square_t to, move_type_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;
|
||||
return move_make(from, to) | (flags << M_OFF_FLAGS);
|
||||
}
|
||||
|
||||
static inline move_t move_make_capture(square_t from, square_t to)
|
||||
@@ -89,13 +112,13 @@ static inline move_t move_make_capture(square_t from, square_t to)
|
||||
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 << 12);
|
||||
return move_make_flags(from, to, M_PROMOTION) | (promoted << M_OFF_PROM);
|
||||
}
|
||||
|
||||
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 << 12);
|
||||
return move_make_flags(from, to, M_CAPTURE | M_PROMOTION) | (promoted << M_OFF_PROM);
|
||||
}
|
||||
|
||||
/* moves_print flags
|
||||
@@ -109,9 +132,6 @@ static inline move_t move_make_promote_capture(square_t from, square_t to,
|
||||
#define M_PR_SEPARATE 0x40 /* separate captures */
|
||||
#define M_PR_LONG 0x80
|
||||
|
||||
//pool_t *moves_pool_init();
|
||||
//void moves_pool_stats();
|
||||
|
||||
//int move_print(int movenum, move_t *move, move_flags_t flags);
|
||||
char *move_str(char *dst, const move_t move, __unused const int flags);
|
||||
void moves_print(movelist_t *moves, int flags);
|
||||
|
@@ -237,7 +237,7 @@ int main(int __unused ac, __unused char**av)
|
||||
/* print movelists */
|
||||
send_stockfish_fen(outfd, fishpos, fen);
|
||||
pos_gen_pseudomoves(pos);
|
||||
pos_legalmoves(pos, &legal);
|
||||
pos_all_legal(pos, &legal);
|
||||
//printf("Fu ");
|
||||
//moves_print(fishpos, 0);
|
||||
//fflush(stdout);
|
||||
|
Reference in New Issue
Block a user