@@ -36,6 +36,7 @@ use crate::{
3636 evaluation:: ByteKnightEvaluation ,
3737 history_table:: { self , HistoryTable } ,
3838 inplace_incremental_sort:: InplaceIncrementalSort ,
39+ killer_moves_table:: KillerMovesTable ,
3940 lmr,
4041 log_level:: LogLevel ,
4142 move_order:: MoveOrder ,
@@ -159,6 +160,7 @@ impl Display for SearchParameters {
159160pub struct Search < ' search_lifetime , Log > {
160161 transposition_table : & ' search_lifetime mut TranspositionTable ,
161162 history_table : & ' search_lifetime mut HistoryTable ,
163+ killers_table : & ' search_lifetime mut KillerMovesTable ,
162164 move_gen : MoveGenerator ,
163165 nodes : u64 ,
164166 parameters : SearchParameters ,
@@ -174,6 +176,7 @@ impl<'a, Log: LogLevel> Search<'a, Log> {
174176 parameters : & SearchParameters ,
175177 ttable : & ' a mut TranspositionTable ,
176178 history_table : & ' a mut HistoryTable ,
179+ killers_table : & ' a mut KillerMovesTable ,
177180 ) -> Self {
178181 // Initialize our LMR table as a 2D array of our LMR formula for depth and moves played
179182 let mut table = Table :: < f64 , 32_000 > :: new ( MAX_DEPTH as usize , MAX_MOVE_LIST_SIZE ) ;
@@ -182,6 +185,7 @@ impl<'a, Log: LogLevel> Search<'a, Log> {
182185 Self {
183186 transposition_table : ttable,
184187 history_table,
188+ killers_table,
185189 move_gen : MoveGenerator :: new ( ) ,
186190 nodes : 0 ,
187191 parameters : parameters. clone ( ) ,
@@ -387,7 +391,7 @@ impl<'a, Log: LogLevel> Search<'a, Log> {
387391 let mut alpha_use = alpha;
388392
389393 if depth <= 0 {
390- return self . quiescence :: < Node > ( board, alpha, beta, pv) ;
394+ return self . quiescence :: < Node > ( ply as u8 , board, alpha, beta, pv) ;
391395 }
392396
393397 let mut local_pv = PrincipleVariation :: new ( ) ;
@@ -440,10 +444,12 @@ impl<'a, Log: LogLevel> Search<'a, Log> {
440444 }
441445
442446 let classify_res = MoveOrder :: classify_all (
447+ ply as u8 ,
443448 board. side_to_move ( ) ,
444449 move_list. as_slice ( ) ,
445450 & tt_move,
446451 self . history_table ,
452+ self . killers_table ,
447453 & mut order_list,
448454 ) ;
449455
@@ -535,6 +541,9 @@ impl<'a, Log: LogLevel> Search<'a, Log> {
535541 if alpha_use >= beta {
536542 // update history table for quiets
537543 if mv. is_quiet ( ) {
544+ // store the "killer" move
545+ self . killers_table . update ( ply as u8 , mv) ;
546+
538547 // calculate history bonus
539548 let bonus = history_table:: calculate_bonus_for_depth ( depth) ;
540549 self . history_table . update (
@@ -676,6 +685,7 @@ impl<'a, Log: LogLevel> Search<'a, Log> {
676685 ///
677686 fn quiescence < Node : NodeType > (
678687 & mut self ,
688+ ply : u8 ,
679689 board : & mut Board ,
680690 alpha : Score ,
681691 beta : Score ,
@@ -727,10 +737,12 @@ impl<'a, Log: LogLevel> Search<'a, Log> {
727737
728738 // sort moves by MVV/LVA
729739 let classify_res = MoveOrder :: classify_all (
740+ ply,
730741 board. side_to_move ( ) ,
731742 captures. as_slice ( ) ,
732743 & tt_move,
733744 self . history_table ,
745+ self . killers_table ,
734746 & mut move_order_list,
735747 ) ;
736748 // TODO(PT): Should we log a message to the CLI or a log?
@@ -752,7 +764,7 @@ impl<'a, Log: LogLevel> Search<'a, Log> {
752764 let score = if board. is_draw ( ) {
753765 Score :: DRAW
754766 } else {
755- let eval = -self . quiescence :: < Node > ( board, -beta, -alpha_use, & mut local_pv) ;
767+ let eval = -self . quiescence :: < Node > ( ply , board, -beta, -alpha_use, & mut local_pv) ;
756768 self . nodes += 1 ;
757769 eval
758770 } ;
@@ -823,7 +835,9 @@ mod tests {
823835 fn run_search_tests ( test_pairs : & [ ( & str , & str ) ] , config : SearchParameters ) {
824836 let mut ttable = TranspositionTable :: default ( ) ;
825837 let mut history_table = Default :: default ( ) ;
826- let mut search = Search :: < LogDebug > :: new ( & config, & mut ttable, & mut history_table) ;
838+ let mut killers_table = Default :: default ( ) ;
839+ let mut search =
840+ Search :: < LogDebug > :: new ( & config, & mut ttable, & mut history_table, & mut killers_table) ;
827841
828842 for ( fen, expected_move) in test_pairs {
829843 let mut board = Board :: from_fen ( fen) . unwrap ( ) ;
@@ -846,7 +860,9 @@ mod tests {
846860
847861 let mut ttable = TranspositionTable :: default ( ) ;
848862 let mut history_table = Default :: default ( ) ;
849- let mut search = Search :: < LogDebug > :: new ( & config, & mut ttable, & mut history_table) ;
863+ let mut killers_table = Default :: default ( ) ;
864+ let mut search =
865+ Search :: < LogDebug > :: new ( & config, & mut ttable, & mut history_table, & mut killers_table) ;
850866 let res = search. search ( & mut board. clone ( ) , None ) ;
851867 // b6a7
852868 assert_eq ! (
@@ -866,7 +882,9 @@ mod tests {
866882
867883 let mut ttable = Default :: default ( ) ;
868884 let mut history_table = Default :: default ( ) ;
869- let mut search = Search :: < LogDebug > :: new ( & config, & mut ttable, & mut history_table) ;
885+ let mut killers_table = Default :: default ( ) ;
886+ let mut search =
887+ Search :: < LogDebug > :: new ( & config, & mut ttable, & mut history_table, & mut killers_table) ;
870888 let res = search. search ( & mut board, None ) ;
871889
872890 assert_eq ! ( res. best_move. unwrap( ) . to_long_algebraic( ) , "b8a8" )
@@ -919,7 +937,9 @@ mod tests {
919937
920938 let mut ttable = Default :: default ( ) ;
921939 let mut history_table = Default :: default ( ) ;
922- let mut search = Search :: < LogDebug > :: new ( & config, & mut ttable, & mut history_table) ;
940+ let mut killers_table = Default :: default ( ) ;
941+ let mut search =
942+ Search :: < LogDebug > :: new ( & config, & mut ttable, & mut history_table, & mut killers_table) ;
923943 let res = search. search ( & mut board, None ) ;
924944 assert ! ( res. best_move. is_none( ) ) ;
925945 assert_eq ! ( res. score, Score :: DRAW ) ;
@@ -937,7 +957,9 @@ mod tests {
937957
938958 let mut ttable = Default :: default ( ) ;
939959 let mut history_table = Default :: default ( ) ;
940- let mut search = Search :: < LogDebug > :: new ( & config, & mut ttable, & mut history_table) ;
960+ let mut killers_table = Default :: default ( ) ;
961+ let mut search =
962+ Search :: < LogDebug > :: new ( & config, & mut ttable, & mut history_table, & mut killers_table) ;
941963 let res = search. search ( & mut board, None ) ;
942964
943965 assert ! ( res. best_move. is_some( ) ) ;
@@ -954,7 +976,9 @@ mod tests {
954976
955977 let mut ttable = Default :: default ( ) ;
956978 let mut history_table = Default :: default ( ) ;
957- let mut search = Search :: < LogDebug > :: new ( & config, & mut ttable, & mut history_table) ;
979+ let mut killers_table = Default :: default ( ) ;
980+ let mut search =
981+ Search :: < LogDebug > :: new ( & config, & mut ttable, & mut history_table, & mut killers_table) ;
958982 let res = search. search ( & mut board, None ) ;
959983 assert ! ( res. best_move. is_some( ) ) ;
960984 println ! ( "{}" , res. best_move. unwrap( ) . to_long_algebraic( ) ) ;
@@ -971,7 +995,9 @@ mod tests {
971995
972996 let mut ttable = Default :: default ( ) ;
973997 let mut history_table = Default :: default ( ) ;
974- let mut search = Search :: < LogDebug > :: new ( & config, & mut ttable, & mut history_table) ;
998+ let mut killers_table = Default :: default ( ) ;
999+ let mut search =
1000+ Search :: < LogDebug > :: new ( & config, & mut ttable, & mut history_table, & mut killers_table) ;
9751001 let res = search. search ( & mut board, None ) ;
9761002 assert ! ( res. best_move. is_some( ) ) ;
9771003 println ! ( "{}" , res. best_move. unwrap( ) . to_long_algebraic( ) ) ;
@@ -1031,7 +1057,13 @@ mod tests {
10311057
10321058 let mut ttable = Default :: default ( ) ;
10331059 let mut history_table = Default :: default ( ) ;
1034- let mut search = Search :: < LogDebug > :: new ( & config, & mut ttable, & mut history_table) ;
1060+ let mut killers_table = Default :: default ( ) ;
1061+ let mut search = Search :: < LogDebug > :: new (
1062+ & config,
1063+ & mut ttable,
1064+ & mut history_table,
1065+ & mut killers_table,
1066+ ) ;
10351067 let res = search. search ( & mut board, None ) ;
10361068
10371069 assert ! ( res. best_move. is_some( ) ) ;
0 commit comments