From 2069d6073d6a1fabd47ce554540398b18b66bfa5 Mon Sep 17 00:00:00 2001 From: Bruno Raoult Date: Thu, 16 May 2024 07:16:17 +0200 Subject: [PATCH] add pos_copy(); pos->king[] set at higher level --- Makefile | 6 +++--- src/fen.c | 2 ++ src/hash.c | 2 +- src/hash.h | 5 +++++ src/move-do.c | 58 ++++++++++++++++++++++++++++++++++++++++---------- src/position.c | 18 +++++++++++++++- src/position.h | 20 +++++++++++++---- 7 files changed, 91 insertions(+), 20 deletions(-) diff --git a/Makefile b/Makefile index b9b359c..1e917ee 100644 --- a/Makefile +++ b/Makefile @@ -68,8 +68,8 @@ CPPFLAGS += -DWARN_ON # brlib bug.h # fen.c #CPPFLAGS += -DDEBUG_FEN # FEN decoding -# hash -CPPFLAGS += -DDEBUG_HASH # chk zobrist consistency +# hash.c +#CPPFLAGS += -HASH_VERIFY # chk zobrist consistency # attack.c #CPPFLAGS += -DDEBUG_ATTACK_ATTACKERS # sq_attackers @@ -390,7 +390,7 @@ bin/attack-test: test/attack-test.c test/common-test.h $(ATTACK_OBJS) bin/movedo-test: test/movedo-test.c test/common-test.h $(MOVEDO_OBJS) @echo compiling $@ test executable. - $(CC) $(ALL_CFLAGS) $< $(MOVEDO_OBJS) $(ALL_LDFLAGS) -o $@ + @$(CC) $(ALL_CFLAGS) $< $(MOVEDO_OBJS) $(ALL_LDFLAGS) -o $@ bin/perft-test: test/perft-test.c test/common-test.h $(PERFT_OBJS) @echo compiling $@ test executable. diff --git a/src/fen.c b/src/fen.c index 6f8d2c1..bf7a3f0 100644 --- a/src/fen.c +++ b/src/fen.c @@ -184,6 +184,8 @@ pos_t *fen2pos(pos_t *pos, const char *fen) piece, PIECE(piece), COLOR(piece)); # endif pos_set_sq(&tmppos, sq_make(file, rank), piece); + if (PIECE(piece) == KING) + tmppos.king[COLOR(piece)] = sq_make(file, rank); file++; } else { /* error */ err_line = __LINE__, err_char = *cur, err_pos = cur - fen; diff --git a/src/hash.c b/src/hash.c index b8eb00d..762ea70 100644 --- a/src/hash.c +++ b/src/hash.c @@ -93,7 +93,7 @@ key_t zobrist_calc(pos_t *pos) * * @return: True if Zobrist key is OK. */ -#ifdef DEBUG_HASH +#ifdef ZOBRIST_VERIFY bool zobrist_verify(pos_t *pos) { key_t diff, key = zobrist_calc(pos); diff --git a/src/hash.h b/src/hash.h index e639250..438ffee 100644 --- a/src/hash.h +++ b/src/hash.h @@ -90,7 +90,12 @@ extern hasht_t hash_tt; /* main transposition table */ void zobrist_init(void); key_t zobrist_calc(pos_t *pos); + +#ifdef ZOBRIST_VERIFY bool zobrist_verify(pos_t *pos); +#else +#define zobrist_verify(p) true +#endif int hash_create(int Mb); void hash_clear(void); diff --git a/src/move-do.c b/src/move-do.c index 6a27021..8fbf9e4 100644 --- a/src/move-do.c +++ b/src/move-do.c @@ -61,9 +61,12 @@ pos_t *move_do(pos_t *pos, const move_t move) //, state_t *state) piece_type_t ptype = PIECE(piece); piece_t new_piece = piece; int up = sq_up(us); + key_t key = pos->key; - /* update turn, reset castling and ep */ - pos->key ^= zobrist_turn; + /* update key: switch turn, reset castling and ep */ + key ^= zobrist_turn; + key ^= zobrist_castling[pos->castle]; + key ^= zobrist_ep[EP_ZOBRIST_IDX(pos->en_passant)]; ++pos->clock_50; ++pos->plycount; @@ -82,6 +85,7 @@ pos_t *move_do(pos_t *pos, const move_t move) //, state_t *state) pos->clock_50 = 0; //pos->captured = pos->board[to]; /* save capture info */ bug_on(pos->board[to] == EMPTY || COLOR(pos->captured) != them); + key ^= zobrist_pieces[captured][to]; pos_clr_sq(pos, to); /* clear square */ } else if (is_castle(move)) { /* handle rook move */ square_t rookfrom, rookto; @@ -92,20 +96,26 @@ pos_t *move_do(pos_t *pos, const move_t move) //, state_t *state) rookfrom = sq_rel(A1, us); rookto = sq_rel(D1, us); } + key ^= zobrist_pieces[pos->board[rookfrom]][rookto] ^ + zobrist_pieces[pos->board[rookfrom]][rookfrom]; pos_set_sq(pos, rookto, pos->board[rookfrom]); pos_clr_sq(pos, rookfrom); - pos->castle = clr_castle(pos->castle, us); + //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. */ + if (is_dpush(move)) { /* if pawn double push, set e.p. */ pos->en_passant = from + up; - else if (is_enpassant(move)) { /* clear grabbed pawn */ + /* update ep key */ + key ^= zobrist_ep[EP_ZOBRIST_IDX(pos->en_passant)]; + } else if (is_enpassant(move)) { /* clear grabbed pawn */ square_t grabbed = to - up; + key ^= zobrist_pieces[pos->board[grabbed]][grabbed]; pos_clr_sq(pos, grabbed); } } - pos_clr_sq(pos, from); /* always clear "from" and set "to" */ + key ^= zobrist_pieces[piece][from] ^ zobrist_pieces[new_piece][to]; + pos_clr_sq(pos, from); /* clear "from" and set "to" */ pos_set_sq(pos, to, new_piece); if (ptype == KING) @@ -127,7 +137,6 @@ pos_t *move_do(pos_t *pos, const move_t move) //, state_t *state) else if (from == rel_h1) pos->castle = clr_oo(pos->castle, us); } - if (can_castle(pos->castle, them)) { square_t rel_a8 = sq_rel(A8, us); square_t rel_h8 = sq_rel(H8, us); @@ -137,6 +146,12 @@ pos_t *move_do(pos_t *pos, const move_t move) //, state_t *state) pos->castle = clr_oo(pos->castle, them); } + /* update castle key */ + key ^= zobrist_castling[pos->castle]; + + pos->key = key; + + bug_on(zobrist_verify(pos) == false); return pos; } @@ -153,9 +168,15 @@ pos_t *move_do2(pos_t *pos, const move_t move, state_t *state) piece_type_t ptype = PIECE(piece); piece_t new_piece = piece; int up = sq_up(us); + key_t key = pos->key; *state = pos->state; /* save irreversible changes */ + /* update key: switch turn, reset castling and ep */ + key ^= zobrist_turn; + key ^= zobrist_castling[pos->castle]; + key ^= zobrist_ep[EP_ZOBRIST_IDX(pos->en_passant)]; + ++pos->clock_50; ++pos->plycount; pos->en_passant = SQUARE_NONE; @@ -173,6 +194,7 @@ pos_t *move_do2(pos_t *pos, const move_t move, state_t *state) pos->clock_50 = 0; //pos->captured = pos->board[to]; /* save capture info */ bug_on(pos->board[to] == EMPTY || COLOR(pos->captured) != them); + key ^= zobrist_pieces[captured][to]; pos_clr_sq(pos, to); /* clear square */ } else if (is_castle(move)) { /* handle rook move */ square_t rookfrom, rookto; @@ -183,20 +205,27 @@ pos_t *move_do2(pos_t *pos, const move_t move, state_t *state) rookfrom = sq_rel(A1, us); rookto = sq_rel(D1, us); } + key ^= zobrist_pieces[pos->board[rookfrom]][rookto]; + key ^= zobrist_pieces[pos->board[rookfrom]][rookfrom]; 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. */ + if (is_dpush(move)) { /* if pawn double push, set e.p. */ pos->en_passant = from + up; - else if (is_enpassant(move)) { /* clear grabbed pawn */ + /* update key */ + key ^= zobrist_ep[EP_ZOBRIST_IDX(pos->en_passant)]; + } else if (is_enpassant(move)) { /* clear grabbed pawn */ square_t grabbed = to - up; + key ^= zobrist_pieces[pos->board[grabbed]][grabbed]; pos_clr_sq(pos, grabbed); } } - pos_clr_sq(pos, from); /* always clear "from" and set "to" */ + key ^= zobrist_pieces[piece][from]; + key ^= zobrist_pieces[new_piece][to]; + pos_clr_sq(pos, from); /* clear "from" and set "to" */ pos_set_sq(pos, to, new_piece); if (ptype == KING) @@ -218,7 +247,7 @@ pos_t *move_do2(pos_t *pos, const move_t move, state_t *state) 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 ? */ + if (can_castle(pos->castle, them)) { square_t rel_a8 = sq_rel(A8, us); square_t rel_h8 = sq_rel(H8, us); if (to == rel_a8) @@ -227,6 +256,13 @@ pos_t *move_do2(pos_t *pos, const move_t move, state_t *state) pos->castle = clr_oo(pos->castle, them); } + /* update castle key */ + key ^= zobrist_castling[pos->castle]; + + pos->key = key; + + bug_on(zobrist_verify(pos) == false); + return pos; } diff --git a/src/position.c b/src/position.c index ab277ec..f95bda3 100644 --- a/src/position.c +++ b/src/position.c @@ -62,6 +62,21 @@ pos_t *pos_dup(const pos_t *pos) return newpos; } +/** + * pos_copy() - copy a position into another one. + * @from: &position to duplicate. + * @to: &destination position. + * + * Return a copy of @from into @to. + * + * @Return: @to. + */ +pos_t *pos_copy(const pos_t *from, pos_t *to) +{ + *to = *from; + return to; +} + /** * pos_del() - delete a position. * @pos: &position. @@ -87,6 +102,7 @@ pos_t *pos_clear(pos_t *pos) pos->turn = WHITE; /* move_do/undo position state */ + pos->key = 0; pos->en_passant = SQUARE_NONE; pos->castle = 0; pos->clock_50 = 0; @@ -336,9 +352,9 @@ bool pos_ok(const pos_t *pos, const bool strict) /* force BUG_ON and WARN_ON */ # pragma push_macro("BUG_ON") -# pragma push_macro("WARN_ON") # undef BUG_ON # define BUG_ON +# pragma push_macro("WARN_ON") # undef WARN_ON # define WARN_ON diff --git a/src/position.h b/src/position.h index 3885710..b99bb30 100644 --- a/src/position.h +++ b/src/position.h @@ -19,6 +19,7 @@ #include #include #include +#include #include "chessdefs.h" #include "hash.h" @@ -74,11 +75,16 @@ static __always_inline void pos_set_sq(pos_t *pos, square_t square, piece_t piec { color_t color = COLOR(piece); piece_type_t type = PIECE(piece); + + bug_on(pos->board[square] != EMPTY); + pos->board[square] = piece; pos->bb[color][type] |= BIT(square); pos->bb[color][ALL_PIECES] |= BIT(square); - if (type == KING) - pos->king[color] = square; + //if (type == KING) + // pos->king[color] = square; + + //pos->key ^= zobrist_pieces[piece][square]; } /** @@ -93,11 +99,16 @@ static __always_inline void pos_clr_sq(pos_t *pos, square_t square) piece_t piece = pos->board[square]; piece_type_t type = PIECE(piece); color_t color = COLOR(piece); + + bug_on(pos->board[square] == EMPTY); + + //pos->key ^= zobrist_pieces[piece][square]; + pos->board[square] = EMPTY; pos->bb[color][type] &= ~BIT(square); pos->bb[color][ALL_PIECES] &= ~BIT(square); - if (type == KING) - pos->king[color] = SQUARE_NONE; + //if (type == KING) + // pos->king[color] = SQUARE_NONE; } /** @@ -158,6 +169,7 @@ static __always_inline int pos_between_count(const pos_t *pos, pos_t *pos_new(); pos_t *pos_dup(const pos_t *pos); +pos_t *pos_copy(const pos_t *from, pos_t *to); void pos_del(pos_t *pos); pos_t *pos_clear(pos_t *pos); bool pos_cmp(const pos_t *pos1, const pos_t *pos2);