When updating castleRights in do_move() perform only one
64bit xor with zobCastle[] instead of two.
The trick here is to define zobCastle[] keys of composite
castling rights as a xor combination of the keys of the
single castling rights, instead of 16 independent keys.
Idea from Critter although implementation is different.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
if ( st->castleRights != CASTLES_NONE
&& (castleRightsMask[from] & castleRightsMask[to]) != ALL_CASTLES)
{
if ( st->castleRights != CASTLES_NONE
&& (castleRightsMask[from] & castleRightsMask[to]) != ALL_CASTLES)
{
- k ^= zobCastle[st->castleRights];
- st->castleRights &= castleRightsMask[from] & castleRightsMask[to];
- k ^= zobCastle[st->castleRights];
+ int cr = castleRightsMask[from] & castleRightsMask[to];
+ k ^= zobCastle[st->castleRights & (cr ^ ALL_CASTLES)];
+ st->castleRights &= cr;
}
// Prefetch TT access as soon as we know key is updated
}
// Prefetch TT access as soon as we know key is updated
}
// Update castling rights
}
// Update castling rights
- st->key ^= zobCastle[st->castleRights];
- st->castleRights &= castleRightsMask[kfrom];
- st->key ^= zobCastle[st->castleRights];
+ int cr = castleRightsMask[kfrom];
+ st->key ^= zobCastle[st->castleRights & (cr ^ ALL_CASTLES)];
+ st->castleRights &= cr;
// Update checkers BB
st->checkersBB = attackers_to(king_square(~us)) & pieces(us);
// Update checkers BB
st->checkersBB = attackers_to(king_square(~us)) & pieces(us);
for (Square s = SQ_A1; s <= SQ_H8; s++)
zobEp[s] = rk.rand<Key>();
for (Square s = SQ_A1; s <= SQ_H8; s++)
zobEp[s] = rk.rand<Key>();
- for (int i = 0; i < 16; i++)
- zobCastle[i] = rk.rand<Key>();
+ for (int cr = CASTLES_NONE; cr <= ALL_CASTLES; cr++)
+ {
+ Bitboard b = cr;
+ while (b)
+ {
+ Key k = zobCastle[1 << pop_1st_bit(&b)];
+ zobCastle[cr] ^= k ? k : rk.rand<Key>();
+ }
+ }
zobSideToMove = rk.rand<Key>();
zobExclusion = rk.rand<Key>();
zobSideToMove = rk.rand<Key>();
zobExclusion = rk.rand<Key>();