Skip to content

Commit a1b4948

Browse files
authored
Singular Margin Reductions (#880)
STC Elo | 2.33 +- 1.78 (95%) SPRT | 8.0+0.08s Threads=1 Hash=16MB LLR | 2.92 (-2.25, 2.89) [0.00, 3.00] Games | N: 38270 W: 9850 L: 9593 D: 18827 Penta | [114, 4392, 9880, 4621, 128] https://recklesschess.space/test/13332/ LTC Elo | 2.22 +- 1.69 (95%) SPRT | 40.0+0.40s Threads=1 Hash=64MB LLR | 2.92 (-2.25, 2.89) [0.00, 3.00] Games | N: 37854 W: 9469 L: 9227 D: 19158 Penta | [21, 4187, 10273, 4421, 25] https://recklesschess.space/test/13338/ Bench: 2701511
1 parent ed73260 commit a1b4948

File tree

1 file changed

+23
-7
lines changed

1 file changed

+23
-7
lines changed

src/search.rs

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,7 @@ fn search<NODE: NodeType>(
646646

647647
// Singular Extensions (SE)
648648
let mut extension = 0;
649+
let mut singular_score = Score::NONE;
649650

650651
if !NODE::ROOT && !excluded && potential_singularity {
651652
debug_assert!(is_valid(tt_score));
@@ -656,29 +657,29 @@ fn search<NODE: NodeType>(
656657
let singular_depth = (depth - 1) / 2;
657658

658659
td.stack[ply].excluded = tt_move;
659-
let score = search::<NonPV>(td, singular_beta - 1, singular_beta, singular_depth, cut_node, ply);
660+
singular_score = search::<NonPV>(td, singular_beta - 1, singular_beta, singular_depth, cut_node, ply);
660661
td.stack[ply].excluded = Move::NULL;
661662

662663
if td.shared.status.get() == Status::STOPPED {
663664
return Score::ZERO;
664665
}
665666

666-
if score < singular_beta {
667+
if singular_score < singular_beta {
667668
let double_margin =
668669
204 * NODE::PV as i32 - 16 * tt_move.is_quiet() as i32 - 16 * correction_value.abs() / 128;
669670
let triple_margin =
670671
257 * NODE::PV as i32 - 16 * tt_move.is_quiet() as i32 - 15 * correction_value.abs() / 128 + 32;
671672

672673
extension = 1;
673-
extension += (score < singular_beta - double_margin) as i32;
674-
extension += (score < singular_beta - triple_margin) as i32;
674+
extension += (singular_score < singular_beta - double_margin) as i32;
675+
extension += (singular_score < singular_beta - triple_margin) as i32;
675676
}
676677
// Multi-Cut
677-
else if score >= beta && !is_decisive(score) {
678-
return (2 * score + beta) / 3;
678+
else if singular_score >= beta && !is_decisive(singular_score) {
679+
return (2 * singular_score + beta) / 3;
679680
}
680681
// Negative Extensions
681-
else if score > tt_score {
682+
else if singular_score > tt_score {
682683
tt_move = Move::NULL;
683684
} else if tt_score >= beta {
684685
extension = -2;
@@ -698,6 +699,7 @@ fn search<NODE: NodeType>(
698699
let mut skip_quiets = false;
699700
let mut current_search_count = 0;
700701
let mut alpha_raises = 0;
702+
let mut tt_move_score = Score::NONE;
701703

702704
while let Some(mv) = move_picker.next::<NODE>(td, skip_quiets, ply) {
703705
if mv == td.stack[ply].excluded {
@@ -824,6 +826,11 @@ fn search<NODE: NodeType>(
824826
reduction += 1515;
825827
}
826828

829+
if is_valid(tt_move_score) && is_valid(singular_score) {
830+
let margin = tt_move_score - singular_score;
831+
reduction += (512 * (margin - 160) / 128).clamp(0, 2048);
832+
}
833+
827834
if !NODE::PV && td.stack[ply - 1].reduction > reduction + 485 {
828835
reduction += 129;
829836
}
@@ -882,6 +889,11 @@ fn search<NODE: NodeType>(
882889
reduction += 1360;
883890
}
884891

892+
if is_valid(tt_move_score) && is_valid(singular_score) {
893+
let margin = tt_move_score - singular_score;
894+
reduction += (400 * (margin - 160) / 128).clamp(0, 2048);
895+
}
896+
885897
if mv == tt_move {
886898
reduction -= 3281;
887899
}
@@ -947,6 +959,10 @@ fn search<NODE: NodeType>(
947959
}
948960
}
949961

962+
if mv == tt_move {
963+
tt_move_score = score;
964+
}
965+
950966
if score > best_score {
951967
best_score = score;
952968

0 commit comments

Comments
 (0)