@@ -5,8 +5,8 @@ use crate::{
55 } ,
66 setwise:: { bishop_attacks_setwise, knight_attacks_setwise, pawn_attacks_setwise, rook_attacks_setwise} ,
77 types:: {
8- Bitboard , Castling , CastlingKind , Color , File , Move , PAWN_HOME_RANK , PROMO_RANK , Piece , PieceType , Square ,
9- ZOBRIST ,
8+ Bitboard , Castling , CastlingKind , Color , File , Keys , Move , PAWN_HOME_RANK , PROMO_RANK , Piece , PieceType ,
9+ Square , ZOBRIST ,
1010 } ,
1111} ;
1212
@@ -24,9 +24,7 @@ mod see;
2424/// Implements the `Copy` trait for efficient memory duplication via bitwise copying.
2525#[ derive( Copy , Clone , Default ) ]
2626struct InternalState {
27- key : u64 ,
28- pawn_key : u64 ,
29- non_pawn_keys : [ u64 ; Color :: NUM ] ,
27+ keys : Keys ,
3028 en_passant : Square ,
3129 castling : Castling ,
3230 halfmove_clock : u8 ,
@@ -83,15 +81,15 @@ impl Board {
8381 // To mitigate Graph History Interaction (GHI) problems, the hash key is changed
8482 // every 8 plies to distinguish between positions that would otherwise appear
8583 // identical to the transposition table.
86- self . state . key ^ ZOBRIST . halfmove_clock [ self . halfmove_clock_bucket ( ) ]
84+ self . state . keys . full ( ) ^ ZOBRIST . halfmove_clock [ self . halfmove_clock_bucket ( ) ]
8785 }
8886
8987 pub const fn pawn_key ( & self ) -> u64 {
90- self . state . pawn_key
88+ self . state . keys . pawn ( )
9189 }
9290
9391 pub const fn non_pawn_key ( & self , color : Color ) -> u64 {
94- self . state . non_pawn_keys [ color as usize ]
92+ self . state . keys . non_pawn ( color)
9593 }
9694
9795 pub const fn pinned ( & self , color : Color ) -> Bitboard {
@@ -222,15 +220,7 @@ impl Board {
222220 }
223221
224222 pub fn update_hash ( & mut self , piece : Piece , square : Square ) {
225- let key = ZOBRIST . pieces [ piece] [ square] ;
226-
227- self . state . key ^= key;
228-
229- if piece. piece_type ( ) == PieceType :: Pawn {
230- self . state . pawn_key ^= key;
231- } else {
232- self . state . non_pawn_keys [ piece. color ( ) ] ^= key;
233- }
223+ self . state . keys . toggle ( piece, square) ;
234224 }
235225
236226 /// Checks for a material draw
@@ -293,23 +283,23 @@ impl Board {
293283 return false ;
294284 }
295285
296- let current_key = self . state . key ;
286+ let current_key = self . state . keys . full ( ) ;
297287 let stack = & self . state_stack ;
298288 let len = stack. len ( ) ;
299289
300290 let mut index = len - 1 ;
301- let mut other = current_key ^ stack[ index] . key ^ ZOBRIST . side ;
291+ let mut other = current_key ^ stack[ index] . keys . full ( ) ^ ZOBRIST . side ;
302292
303293 for compared_ply in ( 3 ..=half_moves) . step_by ( 2 ) {
304294 index -= 1 ;
305- other ^= stack[ index] . key ^ stack[ index - 1 ] . key ^ ZOBRIST . side ;
295+ other ^= stack[ index] . keys . full ( ) ^ stack[ index - 1 ] . keys . full ( ) ^ ZOBRIST . side ;
306296 index -= 1 ;
307297
308298 if other != 0 {
309299 continue ;
310300 }
311301
312- let diff = current_key ^ stack[ index] . key ;
302+ let diff = current_key ^ stack[ index] . keys . full ( ) ;
313303 let mut cuckoo_index = h1 ( diff) ;
314304
315305 if cuckoo ( cuckoo_index) != diff {
@@ -493,9 +483,7 @@ impl Board {
493483 }
494484
495485 pub fn update_hash_keys ( & mut self ) {
496- self . state . key = 0 ;
497- self . state . pawn_key = 0 ;
498- self . state . non_pawn_keys = [ 0 ; Color :: NUM ] ;
486+ self . state . keys = Keys :: default ( ) ;
499487
500488 for piece in 0 ..Piece :: NUM {
501489 let piece = Piece :: from_index ( piece) ;
@@ -506,14 +494,14 @@ impl Board {
506494 }
507495
508496 if self . en_passant ( ) != Square :: None {
509- self . state . key ^= ZOBRIST . en_passant [ self . en_passant ( ) ] ;
497+ self . state . keys . toggle_en_passant ( self . en_passant ( ) ) ;
510498 }
511499
512500 if self . side_to_move ( ) == Color :: White {
513- self . state . key ^= ZOBRIST . side ;
501+ self . state . keys . toggle_side ( ) ;
514502 }
515503
516- self . state . key ^= ZOBRIST . castling [ self . state . castling ] ;
504+ self . state . keys . toggle_castling ( self . state . castling ) ;
517505 }
518506
519507 fn is_en_passant_valid ( & self ) -> bool {
@@ -546,7 +534,7 @@ impl Board {
546534 return ;
547535 }
548536
549- self . state . key ^= ZOBRIST . en_passant [ self . en_passant ( ) ] ;
537+ self . state . keys . toggle_en_passant ( self . en_passant ( ) ) ;
550538 self . state . en_passant = Square :: None ;
551539 }
552540
0 commit comments