@@ -62,8 +62,9 @@ int kNodeCountSampleAt = 1000;
6262const int kMaxDepthSampled = 32 ;
6363#endif
6464
65- int contempt = 0 ;
65+ int32_t contempt = 0 ;
6666bool armageddon = false ;
67+ std::array<Score, 2 > draw_score { kDrawScore , kDrawScore };
6768
6869int rsearch_mode;
6970Milliseconds rsearch_duration;
@@ -142,6 +143,7 @@ const Depth kLMPBaseNW = 3, kLMPBasePV = 5;
142143const int32_t kLMPScalar = 12 , kLMPQuad = 4 ;
143144const Array2d<Depth, 2 , 6 > kLMP = init_lmp_breakpoints(kLMPBaseNW , kLMPBasePV , kLMPScalar , kLMPQuad );
144145#endif
146+ bool uci_show_wdl = true ;
145147
146148// Parameters used to initialize the LMR reduction table
147149LMRInitializer lmr_initializer {
@@ -599,7 +601,7 @@ Score QuiescentSearch(Thread &t, Score alpha, const Score beta) {
599601
600602 // End search immediately if trivial draw is reached
601603 if (t.board .IsTriviallyDrawnEnding ()) {
602- return kDrawScore ;
604+ return draw_score[t. board . get_turn ()] ;
603605 }
604606
605607 // TT probe
@@ -771,12 +773,14 @@ void update_counter_move_history(Thread &t, const std::vector<Move> &quiets, con
771773}
772774
773775inline const Score get_singular_beta (Score beta, Depth depth) {
774- // return beta - 4*depth;
775776 WDLScore result = WDLScore{beta.win - 2 *depth, beta.win_draw - 2 *depth};
776777 if (result.win < 0 ) {
777778 result.win_draw += result.win ;
778779 result.win = 0 ;
779780 }
781+ if (result.win_draw < 0 ) {
782+ result.win_draw = 0 ;
783+ }
780784 return result;
781785}
782786
@@ -789,15 +793,14 @@ Score AlphaBeta(Thread &t, Score alpha, const Score beta, Depth depth, bool expe
789793 assert (node_type != NodeType::kPV || !expected_cut_node);
790794
791795 const Score original_alpha = alpha;
792- // Score lower_bound_score = kMinScore+t.board.get_num_made_moves();
793796
794797 // Immediately return 0 if we detect a draw.
795798 if (t.board .IsDraw () || (settings::kRepsForDraw == 3 && t.board .CountRepetitions (min_ply) >= 2 )) {
796799 t.nodes ++;
797800 if (t.board .IsFiftyMoveDraw () && t.board .InCheck () && t.board .GetMoves <kNonQuiescent >().empty ()) {
798801 return GetMatedOnMoveScore (t.board .get_num_made_moves ());
799802 }
800- return kDrawScore ;
803+ return draw_score[t. board . get_turn ()] ;
801804 }
802805
803806 // We drop to QSearch if we run out of depth.
@@ -807,10 +810,6 @@ Score AlphaBeta(Thread &t, Score alpha, const Score beta, Depth depth, bool expe
807810 return net_evaluation::ScoreBoard (t.board );
808811 }
809812 return QuiescentSearch<Mode>(t, alpha, beta);
810- // t.board.Print();
811- // Score score = QuiescentSearch<Mode>(t, alpha, beta);
812- // std::cout << "AB QSearch return: (w:" << score.win << ", wd:" << score.win_draw << ")" << std::endl;
813- // return score;
814813 }
815814
816815 // To avoid counting nodes twice if all we do is fall through to QSearch,
@@ -890,7 +889,7 @@ Score AlphaBeta(Thread &t, Score alpha, const Score beta, Depth depth, bool expe
890889 if (in_check) {
891890 return GetMatedOnMoveScore (t.board .get_num_made_moves ());
892891 }
893- return kDrawScore ;
892+ return draw_score[t. board . get_turn ()] ;
894893 }
895894
896895// if (Mode == kSamplingSearchMode && node_type == NodeType::kNW && depth <= kMaxDepthSampled) {
@@ -1096,11 +1095,11 @@ Score RootSearchLoop(Thread &t, Score original_alpha, const Score beta,
10961095 Score alpha = original_alpha;
10971096 Score lower_bound_score = kMinScore ;
10981097 // const bool in_check = board.InCheck();
1099- if (settings::kRepsForDraw == 3 && alpha < kDrawScore .get_previous_score () && t.board .MoveInListCanRepeat (moves)) {
1100- if (beta <= kDrawScore ) {
1101- return kDrawScore ;
1098+ if (settings::kRepsForDraw == 3 && alpha < draw_score[t. board . get_turn ()] .get_previous_score () && t.board .MoveInListCanRepeat (moves)) {
1099+ if (beta <= draw_score[t. board . get_turn ()] ) {
1100+ return draw_score[t. board . get_turn ()] ;
11021101 }
1103- alpha = kDrawScore .get_previous_score ();
1102+ alpha = draw_score[t. board . get_turn ()] .get_previous_score ();
11041103 }
11051104 const bool in_check = t.board .InCheck ();
11061105 for (size_t i = 0 ; i < moves.size (); ++i) {
@@ -1109,8 +1108,8 @@ Score RootSearchLoop(Thread &t, Score original_alpha, const Score beta,
11091108 if (i == 0 ) {
11101109 Score score = -AlphaBeta<NodeType::kPV , Mode>(t, -beta, -alpha, current_depth - 1 );
11111110 assert (score.is_valid ());
1112- if (settings::kRepsForDraw == 3 && score < kDrawScore && t.board .CountRepetitions () >= 2 ) {
1113- score = kDrawScore ;
1111+ if (settings::kRepsForDraw == 3 && score < draw_score[t. board . get_turn ()] && t.board .CountRepetitions () >= 2 ) {
1112+ score = draw_score[t. board . get_turn ()] ;
11141113 }
11151114 t.board .UnMake ();
11161115 if (score >= beta) {
@@ -1133,8 +1132,8 @@ Score RootSearchLoop(Thread &t, Score original_alpha, const Score beta,
11331132 if (score > alpha) {
11341133 score = -AlphaBeta<NodeType::kPV , Mode>(t, -beta, -alpha, current_depth - 1 );
11351134 }
1136- if (settings::kRepsForDraw == 3 && score < kDrawScore && t.board .CountRepetitions () >= 2 ) {
1137- score = kDrawScore ;
1135+ if (settings::kRepsForDraw == 3 && score < draw_score[t. board . get_turn ()] && t.board .CountRepetitions () >= 2 ) {
1136+ score = draw_score[t. board . get_turn ()] ;
11381137 }
11391138 lower_bound_score = std::max (score, lower_bound_score);
11401139 t.board .UnMake ();
@@ -1227,15 +1226,10 @@ void PrintUCIInfoString(Thread &t, const Depth depth, const Time &begin,
12271226
12281227 if (!score.is_mate_score ()) {
12291228 std::cout << " score cp " ;
1230- if (armageddon) {
1231- // TODO change this to reflect armageddon odds.
1232- std::cout << (score.to_cp () / 8 );
1233- }
1234- else {
1235- std::cout << (score.to_cp () / 8 );
1229+ std::cout << (net_evaluation::RemoveContempt (score, t.board .get_turn ()).to_cp () / 8 );
1230+ if (uci_show_wdl) {
1231+ std::cout << " " << net_evaluation::RemoveContempt (score, t.board .get_turn ()).get_uci_string ();
12361232 }
1237- std::cout << " " << score.get_uci_string ();
1238-
12391233 }
12401234 else {
12411235 if (score.is_disadvantage ()) {
@@ -1338,14 +1332,14 @@ void Thread::search() {
13381332template <int Mode>
13391333Move RootSearch (Board &board, Depth depth, Milliseconds duration = Milliseconds(24 * 60 * 60 * 1000 )) {
13401334 table::UpdateGeneration ();
1341- // TODO fix contempt and armageddon.
1342- // if (armageddon) {
1343- // net_evaluation::SetContempt(60, kWhite);
1344- // }
1345- // else {
1346- // net_evaluation::SetContempt(contempt, board.get_turn());
1347- // }
1348- // draw_score = net_evaluation::GetDrawArray( );
1335+ if ( armageddon) {
1336+ net_evaluation::SetContempt ( kWhite , 60 );
1337+ }
1338+ else {
1339+ net_evaluation::SetContempt (board. get_turn (), contempt);
1340+ }
1341+ draw_score = net_evaluation::GetDrawArray ();
1342+ assert (armageddon || contempt != 0 || draw_score[ kWhite ] == kDrawScore );
13491343 min_ply = board.get_num_made_moves ();
13501344 Threads.reset_node_count ();
13511345 Threads.reset_depths ();
@@ -2129,14 +2123,18 @@ std::vector<Board> GenerateEvalSampleSet(std::string filename) {
21292123 return boards;
21302124}
21312125
2132- void SetContempt (int contempt_) {
2133- contempt = ( contempt_ + 100 ) / 2 ;
2126+ void SetContempt (int32_t contempt_) {
2127+ contempt = contempt_;
21342128}
21352129
21362130void SetArmageddon (bool armageddon_) {
21372131 armageddon = armageddon_;
21382132}
21392133
2134+ void SetUCIShowWDL (bool show_wdl) {
2135+ uci_show_wdl = show_wdl;
2136+ }
2137+
21402138#ifdef TUNE
21412139void SetInitialAspirationDelta (int32_t delta) {
21422140 kInitialAspirationDelta = delta;
0 commit comments