2424
2525static const bool randomizeOrder = true ;
2626static const uint32_t c_printPgnFrequency = 1 ;
27- static const uint32_t c_minNodes = 80000 ;
28- static const uint32_t c_maxNodes = 80000 ;
29- static const uint32_t c_maxDepth = 32 ;
30- static const int32_t c_maxEval = 3000 ;
31- static const int32_t c_openingMaxEval = 1000 ;
32- static const int32_t c_multiPv = 1 ;
33- static const int32_t c_multiPvMaxPly = 0 ;
34- static const int32_t c_multiPvScoreTreshold = 50 ;
35- static const uint32_t c_minRandomMoves = 2 ;
36- static const uint32_t c_maxRandomMoves = 2 ;
27+
28+ static const uint32_t c_minNodes = 25'000 ;
29+ static const uint32_t c_maxNodes = 30'000 ;
30+ static const uint32_t c_maxDepth = 40 ;
31+
32+ static const int32_t c_maxEval = 2000 ;
33+ static const int32_t c_openingMaxEval = 300 ;
34+
35+ static const uint32_t c_minRandomMoves = 6 ;
36+ static const uint32_t c_maxRandomMoves = 10 ;
3737
3838bool LoadOpeningPositions (const std::string& path, std::vector<PackedPosition>& outPositions)
3939{
@@ -65,8 +65,6 @@ bool LoadOpeningPositions(const std::string& path, std::vector<PackedPosition>&
6565 outPositions.push_back (packedPos);
6666 }
6767
68- std::cout << " Loaded " << outPositions.size () << " opening positions" << std::endl;
69-
7068 return true ;
7169}
7270
@@ -107,7 +105,7 @@ static bool SelfPlayThreadFunc(
107105 const std::vector<PackedPosition>& openingPositions,
108106 SelfPlayStats& stats)
109107{
110- const size_t c_transpositionTableSize = 2ull * 1024ull * 1024ull ;
108+ const size_t c_transpositionTableSize = 4ull * 1024ull * 1024ull ;
111109
112110 std::random_device rd;
113111 std::mt19937 gen (rd ());
@@ -175,7 +173,6 @@ static bool SelfPlayThreadFunc(
175173 search.Clear ();
176174 game.Reset (openingPos);
177175
178- int32_t multiPvScoreTreshold = c_multiPvScoreTreshold;
179176 int32_t halfMoveNumber = 0 ;
180177 uint32_t drawScoreCounter = 0 ;
181178 uint32_t whiteWinsCounter = 0 ;
@@ -190,9 +187,9 @@ static bool SelfPlayThreadFunc(
190187 searchParam.useRootTablebase = false ;
191188 searchParam.evalRandomization = 1 ;
192189 searchParam.seed = searchSeed;
193- searchParam.numPvLines = (halfMoveNumber < c_multiPvMaxPly) ? c_multiPv : 1 ;
194190 searchParam.limits .maxDepth = c_maxDepth;
195191 searchParam.limits .maxNodesSoft = c_minNodes + (c_maxNodes - c_minNodes) * std::max (0 , 80 - halfMoveNumber) / 80 ;
192+ if (halfMoveNumber < 10 ) searchParam.limits .maxNodesSoft *= 2 ; // more nodes in the first moves
196193 searchParam.limits .maxNodes = 5 * searchParam.limits .maxNodesSoft ;
197194
198195 searchResult.clear ();
@@ -202,39 +199,13 @@ static bool SelfPlayThreadFunc(
202199 ASSERT (!searchResult.empty ());
203200
204201 // skip game if starting position is unbalanced
205- if (halfMoveNumber == 0 && std::abs (searchResult.begin ()->score ) > c_openingMaxEval)
202+ if (halfMoveNumber == 0 && std::abs (searchResult.begin ()->score ) * 100 / wld::NormalizeToPawnValue > c_openingMaxEval)
206203 break ;
207204
208- // sort moves by score
209- std::sort (searchResult.begin (), searchResult.end (), [](const PvLine& a, const PvLine& b)
210- {
211- return a.score > b.score ;
212- });
205+ ASSERT (!searchResult.front ().moves .empty ());
206+ Move move = searchResult.front ().moves .front ();
213207
214- // if one of the move is much worse than the best candidate, ignore it and the rest
215- for (size_t i = 1 ; i < searchResult.size (); ++i)
216- {
217- ASSERT (searchResult[i].score <= searchResult[0 ].score );
218- const int32_t diff = std::abs ((int32_t )searchResult[i].score - (int32_t )searchResult[0 ].score );
219- if (diff > multiPvScoreTreshold)
220- {
221- searchResult.erase (searchResult.begin () + i, searchResult.end ());
222- break ;
223- }
224- }
225-
226- // select random move
227- // TODO prefer moves with higher score
228- std::uniform_int_distribution<size_t > distrib (0 , searchResult.size () - 1 );
229- const size_t moveIndex = distrib (gen);
230- ASSERT (!searchResult[moveIndex].moves .empty ());
231- Move move = searchResult[moveIndex].moves .front ();
232-
233- // reduce threshold of picking worse move
234- // this way the game will be more random at the beginning and there will be less blunders later in the game
235- multiPvScoreTreshold = std::max (10 , multiPvScoreTreshold - 2 );
236-
237- ScoreType moveScore = searchResult[moveIndex].score ;
208+ ScoreType moveScore = searchResult.front ().score ;
238209 ScoreType eval = Evaluate (game.GetPosition ());
239210
240211 if (game.GetSideToMove () == Black)
@@ -261,12 +232,12 @@ static bool SelfPlayThreadFunc(
261232 }
262233
263234 // adjudicate win
264- if (halfMoveNumber >= 20 )
235+ if (halfMoveNumber >= 40 )
265236 {
266237 if (moveScore > c_maxEval && eval > c_maxEval / 4 )
267238 {
268239 whiteWinsCounter++;
269- if (whiteWinsCounter > 3 ) game.SetScore (Game::Score::WhiteWins);
240+ if (whiteWinsCounter > 4 ) game.SetScore (Game::Score::WhiteWins);
270241 }
271242 else
272243 {
@@ -276,7 +247,7 @@ static bool SelfPlayThreadFunc(
276247 if (moveScore < -c_maxEval && eval < -c_maxEval / 4 )
277248 {
278249 blackWinsCounter++;
279- if (blackWinsCounter > 3 ) game.SetScore (Game::Score::BlackWins);
250+ if (blackWinsCounter > 4 ) game.SetScore (Game::Score::BlackWins);
280251 }
281252 else
282253 {
@@ -311,12 +282,12 @@ static bool SelfPlayThreadFunc(
311282 // save game
312283 if (halfMoveNumber > 0 )
313284 {
314- writer.WriteGame (game);
315-
316285 GameMetadata metadata;
317286 metadata.roundNumber = index;
318287 game.SetMetadata (metadata);
319288
289+ writer.WriteGame (game);
290+
320291 if (threadIndex == 0 && c_printPgnFrequency != 0 && (index % c_printPgnFrequency == 0 ))
321292 {
322293 const std::string pgn = game.ToPGN (true );
@@ -353,10 +324,11 @@ void SelfPlay(const std::vector<std::string>& args)
353324
354325 std::cout << " Loading opening positions..." << std::endl;
355326 std::vector<PackedPosition> openingPositions;
356- if (! args. empty () )
327+ for ( const std::string& path : args)
357328 {
358- LoadOpeningPositions (args[ 0 ] , openingPositions);
329+ LoadOpeningPositions (path , openingPositions);
359330 }
331+ std::cout << " Loaded " << openingPositions.size () << " opening positions" << std::endl;
360332
361333 alignas (CACHELINE_SIZE) SelfPlayStats stats;
362334
0 commit comments