move_do2: save/restore state inside func; perft: add silent option

This commit is contained in:
2024-04-18 09:54:58 +02:00
parent 36e1d987f3
commit c710da4bf9
6 changed files with 206 additions and 34 deletions

View File

@@ -131,6 +131,95 @@ pos_t *move_do(pos_t *pos, const move_t move) //, state_t *state)
return pos;
}
pos_t *move_do2(pos_t *pos, const move_t move, state_t *state)
{
//# ifdef DEBUG_MOVE_DO
// move_print(move, M_PR_NL | M_PR_LONG);
//# endif
color_t us = pos->turn, them = OPPONENT(us);
square_t from = move_from(move), to = move_to(move);
piece_t piece = pos->board[from];
piece_t captured = pos->board[to];
piece_type_t ptype = PIECE(piece);
piece_t new_piece = piece;
int up = sq_up(us);
*state = pos->state; /* save irreversible changes */
++pos->clock_50;
++pos->plycount;
pos->en_passant = SQUARE_NONE;
pos->turn = them;
pos->captured = captured;
bug_on(COLOR(piece) != us);
if (is_promotion(move)) {
bug_on(sq_rank(to) != sq_rel_rank(RANK_8, us));
new_piece = MAKE_PIECE(move_promoted(move), us);
}
if (captured != EMPTY) {
pos->clock_50 = 0;
//pos->captured = pos->board[to]; /* save capture info */
bug_on(pos->board[to] == EMPTY || COLOR(pos->captured) != them);
pos_clr_sq(pos, to); /* clear square */
} else if (is_castle(move)) { /* handle rook move */
square_t rookfrom, rookto;
if (is_castle_K(move)) {
rookfrom = sq_rel(H1, us);
rookto = sq_rel(F1, us);
} else {
rookfrom = sq_rel(A1, us);
rookto = sq_rel(D1, us);
}
pos_set_sq(pos, rookto, pos->board[rookfrom]);
pos_clr_sq(pos, rookfrom);
pos->castle = clr_castle(pos->castle, us);
} else if (ptype == PAWN) { /* pawn non capture or e.p. */
pos->clock_50 = 0;
if (is_dpush(move)) /* if pawn double push, set e.p. */
pos->en_passant = from + up;
else if (is_enpassant(move)) { /* clear grabbed pawn */
square_t grabbed = to - up;
pos_clr_sq(pos, grabbed);
}
}
pos_clr_sq(pos, from); /* always clear "from" and set "to" */
pos_set_sq(pos, to, new_piece);
if (ptype == KING)
pos->king[us] = to;
/* update castling flags
* As we always consider flags are valid, we :
* - adjust our flags if relative from is "E1", "A1", H1"
* - adjust opp flags if relative to if "A8", H8"
*/
if (can_castle(pos->castle, us)) { /* do we save time with this test ? */
square_t rel_e1 = sq_rel(E1, us);
square_t rel_a1 = sq_rel(A1, us);
square_t rel_h1 = sq_rel(H1, us);
if (from == rel_e1)
pos->castle = clr_castle(pos->castle, us);
else if (from == rel_a1)
pos->castle = clr_ooo(pos->castle, us);
else if (from == rel_h1)
pos->castle = clr_oo(pos->castle, us);
}
if (can_castle(pos->castle, them)) { /* do we save time with this test ? */
square_t rel_a8 = sq_rel(A8, us);
square_t rel_h8 = sq_rel(H8, us);
if (to == rel_a8)
pos->castle = clr_ooo(pos->castle, them);
else if (to == rel_h8)
pos->castle = clr_oo(pos->castle, them);
}
return pos;
}
/**
* move_undo() - undo move.
* @pos: &pos_t position
@@ -186,3 +275,42 @@ pos_t *move_undo(pos_t *pos, const move_t move)
pos->turn = us;
return pos;
}
pos_t *move_undo2(pos_t *pos, const move_t move, const state_t *state)
{
color_t them = pos->turn, us = OPPONENT(them);
square_t from = move_from(move), to = move_to(move);
piece_t piece = pos->board[to];
int up = sq_up(them);
if (is_promotion(move))
piece = MAKE_PIECE(PAWN, us);
pos_clr_sq(pos, to); /* always clear "to" ... */
pos_set_sq(pos, from, piece); /* ... and set "from" */
if (PIECE(piece) == KING)
pos->king[us] = from;
if (pos->captured != EMPTY) {
pos_set_sq(pos, to, pos->captured); /* restore captured piece */
} else if (is_castle(move)) { /* make reverse rook move */
square_t rookfrom, rookto;
if (is_castle_K(move)) {
rookfrom = sq_rel(F1, us);
rookto = sq_rel(H1, us);
} else {
rookfrom = sq_rel(D1, us);
rookto = sq_rel(A1, us);
}
pos_set_sq(pos, rookto, pos->board[rookfrom]);
pos_clr_sq(pos, rookfrom);
} else if (is_enpassant(move)) { /* restore grabbed pawn */
square_t grabbed = to + up;
pos_set_sq(pos, grabbed, MAKE_PIECE(PAWN, them));
}
pos->state = *state; /* restore irreversible changes */
pos->turn = us;
return pos;
}

View File

@@ -19,4 +19,7 @@
pos_t *move_do(pos_t *pos, const move_t move);//, state_t *state);
pos_t *move_undo(pos_t *pos, const move_t move);//, const state_t *state);
pos_t *move_do2(pos_t *pos, const move_t move, state_t *state);
pos_t *move_undo2(pos_t *pos, const move_t move, const state_t *state);
#endif /* MOVE_DO_H */

View File

@@ -41,7 +41,7 @@
*
* @return: total moves found at @depth level.
*/
u64 perft(pos_t *pos, int depth, int ply)
u64 perft(pos_t *pos, int depth, int ply, bool output)
{
int subnodes;
u64 nodes = 0;
@@ -60,8 +60,8 @@ u64 perft(pos_t *pos, int depth, int ply)
nodes++;
} else {
move_do(pos, *move);
subnodes = perft(pos, depth - 1, ply + 1);
if (ply == 1) {
subnodes = perft(pos, depth - 1, ply + 1, output);
if (output && ply == 1) {
char movestr[8];
printf("%s: %d\n", move_str(movestr, *move, 0), subnodes);
}
@@ -71,7 +71,7 @@ u64 perft(pos_t *pos, int depth, int ply)
}
}
if (ply == 1)
if (output && ply == 1)
printf("Total: %lu\n", nodes);
return nodes;
}
@@ -87,7 +87,7 @@ u64 perft(pos_t *pos, int depth, int ply)
*
* @return: total moves found at @depth level.
*/
u64 perft_test(pos_t *pos, int depth, int ply)
u64 perft_test(pos_t *pos, int depth, int ply, bool output)
{
int subnodes;
u64 nodes = 0;
@@ -97,7 +97,6 @@ u64 perft_test(pos_t *pos, int depth, int ply)
movelist.nmoves = 0;
pos_set_checkers_pinners_blockers(pos);
state = pos->state;
pos_legal(pos, pos_gen_pseudo(pos, &movelist));
last = movelist.move + movelist.nmoves;
@@ -105,19 +104,18 @@ u64 perft_test(pos_t *pos, int depth, int ply)
if (depth == 1) {
nodes++;
} else {
move_do(pos, *move);
subnodes = perft(pos, depth - 1, ply + 1);
if (ply == 1) {
move_do2(pos, *move, &state);
subnodes = perft(pos, depth - 1, ply + 1, output);
if (output && ply == 1) {
char movestr[8];
printf("%s: %d\n", move_str(movestr, *move, 0), subnodes);
}
nodes += subnodes;
move_undo(pos, *move);
pos->state = state;
move_undo2(pos, *move, &state);
}
}
if (ply == 1)
if (output && ply == 1)
printf("Total: %lu\n", nodes);
return nodes;
}

View File

@@ -19,7 +19,7 @@
//eval_t negamax(pos_t *pos, int depth, int color);
//eval_t pvs(pos_t *pos, int depth, int alpha, int beta, int color);
u64 perft(pos_t *pos, int depth, int ply);
u64 perft_test(pos_t *pos, int depth, int ply);
u64 perft(pos_t *pos, int depth, int ply, bool output);
u64 perft_test(pos_t *pos, int depth, int ply, bool output);
#endif /* SEARCH_H */