From 65fe74c9c5ed6da8207613b60b44aa458914afce Mon Sep 17 00:00:00 2001 From: Bruno Raoult Date: Wed, 27 Mar 2024 12:52:39 +0100 Subject: [PATCH] movegen: don't separate promotions, perft: loop uses next_legal() --- src/move-gen.c | 89 +++++++++++++++++++------------------------------- src/search.c | 39 ++++++++++------------ 2 files changed, 52 insertions(+), 76 deletions(-) diff --git a/src/move-gen.c b/src/move-gen.c index 1c62ffc..2d156af 100644 --- a/src/move-gen.c +++ b/src/move-gen.c @@ -192,7 +192,6 @@ int pos_gen_pseudomoves(pos_t *pos, movelist_t *movelist) bitboard_t movebits, from_pawns; bitboard_t tmp1, tmp2; - move_t *moves = movelist->move; int *nmoves = &movelist->nmoves; int from, to; @@ -223,7 +222,6 @@ int pos_gen_pseudomoves(pos_t *pos, movelist_t *movelist) } } bit_for_each64(from, tmp1, pos->bb[us][ROOK] | pos->bb[us][QUEEN]) { - // printf("rook=%d/%s\n", from, sq_to_string(from)); movebits = hyperbola_rook_moves(occ, from) & not_my_pieces; bit_for_each64(to, tmp2, movebits & empty) { moves[(*nmoves)++] = move_make(from, to); @@ -245,16 +243,23 @@ int pos_gen_pseudomoves(pos_t *pos, movelist_t *movelist) } /* pawn: relative rank and files */ - bitboard_t rel_rank7 = bb_rel_rank(RANK_7, us); + bitboard_t rel_rank8 = bb_rel_rank(RANK_8, us); bitboard_t rel_rank3 = bb_rel_rank(RANK_3, us); /* pawn: ranks 2-6 push 1 and 2 squares */ - movebits = pawn_shift_up(pos->bb[us][PAWN] & ~rel_rank7, us) & empty; - bit_for_each64(to, tmp1, movebits) { + movebits = pawn_shift_up(pos->bb[us][PAWN], us) & empty; + bit_for_each64(to, tmp1, movebits & ~rel_rank8) { from = pawn_push_up(to, them); /* reverse push */ - //printf("push %d->%d %s->%s", from, to, sq_to_string(from), sq_to_string(to)); moves[(*nmoves)++] = move_make(from, to); } + bit_for_each64(to, tmp1, movebits & rel_rank8) { /* promotions */ + from = pawn_push_up(to, them); /* reverse push */ + moves[(*nmoves)++] = move_make_promote(from, to, QUEEN); + moves[(*nmoves)++] = move_make_promote(from, to, ROOK); + moves[(*nmoves)++] = move_make_promote(from, to, BISHOP); + moves[(*nmoves)++] = move_make_promote(from, to, KNIGHT); + } + /* possible second push */ movebits = pawn_shift_up(movebits & rel_rank3, us) & empty; bit_for_each64(to, tmp1, movebits) { @@ -262,20 +267,33 @@ int pos_gen_pseudomoves(pos_t *pos, movelist_t *movelist) moves[(*nmoves)++] = move_make_flags(from, to, M_DPUSH); } - /* pawn: ranks 2-6 captures left */ - from_pawns = pos->bb[us][PAWN] & ~rel_rank7; // & ~rel_filea; - movebits = pawn_shift_upleft(from_pawns, us) & enemy_pieces; - bit_for_each64(to, tmp1, movebits) { + /* pawn: captures left */ + movebits = pawn_shift_upleft(pos->bb[us][PAWN], us) & enemy_pieces; + bit_for_each64(to, tmp1, movebits & ~rel_rank8) { from = pawn_push_upleft(to, them); /* reverse capture */ moves[(*nmoves)++] = move_make_capture(from, to); } - /* pawn: ranks 2-6 captures right */ - from_pawns = pos->bb[us][PAWN] & ~rel_rank7; // & ~rel_fileh; - movebits = pawn_shift_upright(from_pawns, us) & enemy_pieces; - bit_for_each64(to, tmp1, movebits) { - from = pawn_push_upright(to, them); + bit_for_each64(to, tmp1, movebits & rel_rank8) { + 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, ROOK); + moves[(*nmoves)++] = move_make_promote_capture(from, to, BISHOP); + moves[(*nmoves)++] = move_make_promote_capture(from, to, KNIGHT); + } + + /* pawn: captures right */ + movebits = pawn_shift_upright(pos->bb[us][PAWN], us) & enemy_pieces; + bit_for_each64(to, tmp1, movebits & ~rel_rank8) { + from = pawn_push_upright(to, them); /* reverse capture */ moves[(*nmoves)++] = move_make_capture(from, to); } + bit_for_each64(to, tmp1, movebits & rel_rank8) { + from = pawn_push_upright(to, them); /* reverse capture */ + moves[(*nmoves)++] = move_make_promote_capture(from, to, QUEEN); + moves[(*nmoves)++] = move_make_promote_capture(from, to, ROOK); + moves[(*nmoves)++] = move_make_promote_capture(from, to, BISHOP); + moves[(*nmoves)++] = move_make_promote_capture(from, to, KNIGHT); + } /* pawn: en-passant */ if ((to = pos->en_passant) != SQUARE_NONE) { @@ -287,36 +305,6 @@ int pos_gen_pseudomoves(pos_t *pos, movelist_t *movelist) } } - /* pawn: rank 7 push */ - movebits = pawn_shift_up(pos->bb[us][PAWN] & rel_rank7, us) & empty; - bit_for_each64(to, tmp1, movebits) { - from = pawn_push_up(to, them); /* reverse push */ - moves[(*nmoves)++] = move_make_promote(from, to, QUEEN); - moves[(*nmoves)++] = move_make_promote(from, to, ROOK); - moves[(*nmoves)++] = move_make_promote(from, to, BISHOP); - moves[(*nmoves)++] = move_make_promote(from, to, KNIGHT); - } - /* pawn promotion: rank 7 captures left */ - from_pawns = pos->bb[us][PAWN] & rel_rank7; // & ~rel_filea; - movebits = pawn_shift_upleft(from_pawns, us) & enemy_pieces; - bit_for_each64(to, tmp1, movebits) { - 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, ROOK); - moves[(*nmoves)++] = move_make_promote_capture(from, to, BISHOP); - moves[(*nmoves)++] = move_make_promote_capture(from, to, KNIGHT); - } - /* pawn: rank 7 captures right */ - from_pawns = pos->bb[us][PAWN] & rel_rank7; // & ~rel_fileh; - movebits = pawn_shift_upright(from_pawns, us) & enemy_pieces; - bit_for_each64(to, tmp1, movebits) { - from = pawn_push_upright(to, them); /* reverse capture */ - moves[(*nmoves)++] = move_make_promote_capture(from, to, QUEEN); - moves[(*nmoves)++] = move_make_promote_capture(from, to, ROOK); - moves[(*nmoves)++] = move_make_promote_capture(from, to, BISHOP); - moves[(*nmoves)++] = move_make_promote_capture(from, to, KNIGHT); - } - /* castle - Attention ! Castling flags are assumed correct */ if (!pos->checkers) { @@ -342,16 +330,7 @@ int pos_gen_pseudomoves(pos_t *pos, movelist_t *movelist) } } } - /* TODO - * DONE. pawn ranks 2-6 advance (1 push, + 2 squares for rank 2) - * DONE. pawns rank 7 advance + promotions - * DONE. pawns ranks 2-6 captures, left and right - * DONE. pawns en-passant (with capture) - * DONE. pawns rank 7 capture + promotion - * DONE. castle - * - * add function per piece, and type, for easier debug - * + /* TODO: add function per piece, and type, for easier debug */ return *nmoves; } diff --git a/src/search.c b/src/search.c index 418fd12..30d8cd8 100644 --- a/src/search.c +++ b/src/search.c @@ -37,33 +37,31 @@ */ u64 perft(pos_t *pos, int depth, int ply) { - int subnodes, nmove = 0; + int subnodes, movetmp = 0; u64 nodes = 0; - movelist_t pseudo = { .nmoves = 0 }, legal = { .nmoves = 0 }; + movelist_t pseudo = { .nmoves = 0 }; move_t move; + state_t state; if (depth == 0) return 1; pos->checkers = pos_checkers(pos, pos->turn); pos_set_pinners_blockers(pos); + state = pos->state; pos_gen_pseudomoves(pos, &pseudo); - pos_all_legal(pos, &pseudo, &legal); - - for (nmove = 0; nmove < legal.nmoves; ++nmove ) { - //while ((move = pos_next_legal(pos, &pseudo, &movetmp)) != MOVE_NONE) { - //printf("depth=%d movetmp=%d\n", depth, movetmp); - state_t state; - move = legal.move[nmove]; - move_do(pos, move, &state); + while ((move = pos_next_legal(pos, &pseudo, &movetmp)) != MOVE_NONE) { + move_do(pos, move); subnodes = perft(pos, depth - 1, ply + 1); if (ply == 1) { char movestr[8]; printf("%s: %d\n", move_str(movestr, move, 0), subnodes); } nodes += subnodes; - move_undo(pos, move, &state); + move_undo(pos, move); + pos->state = state; } + if (ply == 1) printf("\nTotal: %lu\n", nodes); return nodes; @@ -75,32 +73,31 @@ u64 perft2(pos_t *pos, int depth, int ply) u64 nodes = 0; movelist_t pseudo = { .nmoves = 0 }; move_t move; + state_t state; if (is_in_check(pos, OPPONENT(pos->turn))) return 0; if (depth == 0) return 1; pos->checkers = pos_checkers(pos, pos->turn); - pos->pinners = pos_king_pinners(pos, pos->turn); - pos->blockers = pos_king_blockers(pos, pos->turn, pos->pinners); + pos_set_pinners_blockers(pos); + state = pos->state; pos_gen_pseudomoves(pos, &pseudo); - //pos_all_legal(pos, &pseudo, &legal); for (nmove = 0; nmove < pseudo.nmoves; ++nmove ) { - //while ((move = pos_next_legal(pos, &pseudo, &movetmp)) != MOVE_NONE) { - //printf("depth=%d movetmp=%d\n", depth, movetmp); - state_t state; move = pseudo.move[nmove]; - move_do(pos, move, &state); + move_do(pos, move); + //if (!is_in_check(pos, OPPONENT(pos->turn))) { subnodes = perft2(pos, depth - 1, ply + 1); - + nodes += subnodes; if (ply == 1) { char movestr[8]; printf("%s: %d\n", move_str(movestr, move, 0), subnodes); } - nodes += subnodes; - move_undo(pos, move, &state); + //} + move_undo(pos, move); + pos->state = state; } if (ply == 1) printf("\nTotal: %lu\n", nodes);