27 :
limit(1200), node_limit(800000), table_size(10000),
29 verbose(0), next_iteration_coefficient(3), draw_coef(0),
30 save_pv(true), node_count_hard_limit(std::numeric_limits<uint64_t>::
max()),
62 recorder_ptr(new CountRecorder()),
63 searching(0), plan_stop(false),
64 root_ignore_moves(0), prediction_for_speculative_search(0),
65 pv_history(new
PVHistory(*copy.pv_history)),
66 almost_resign_count(0)
93 std::cerr <<
"SearchPlayer not searching ";
94 const time_t now = time(0);
96 std::cerr <<
ctime_r(&now, ctime_buf);
106 recorder_ptr.reset(new_recorder);
123 const MilliSeconds started = MilliSeconds::now();
126 if (table_ptr.get() && table_ptr->verboseLevel() > 2)
128 std::cerr <<
"setUpTable " <<
ctime_r(&t, ctime_buf)
133 NonBlockDelete::reset(checkmate_ptr);
137 if (table_ptr.get()) {
143 table_ptr.reset(
new SimpleHashTable(config.table_size,
144 config.table_record_limit, config.verbose));
146 catch (std::bad_alloc&)
148 NonBlockDelete::deleteAll();
149 std::cerr <<
"\atable allocation failed, try agaian" << std::endl;
150 table_ptr.reset(
new SimpleHashTable(config.table_size,
151 config.table_record_limit, config.verbose));
154 table_ptr->setVerbose(config.verbose);
155 NonBlockDelete::deleteAll();
162 checkmate_ptr.reset(
new DualDfpn());
164 catch (std::bad_alloc&)
166 NonBlockDelete::deleteAll();
167 std::cerr <<
"\acheckmate allocation failed, try agaian" << std::endl;
168 checkmate_ptr.reset(
new DualDfpn());
173 if (table_ptr->verboseLevel() > 2)
176 std::cerr <<
"setup done in " << (MilliSeconds::now() - started).toSeconds()
177 <<
" sec. " <<
ctime_r(&t, ctime_buf)
184 return MilliSeconds::now() - started;
191 config.initial_limit = il;
192 config.deepening_step = ds;
198 config.node_limit = nl;
204 config.node_count_hard_limit = nl;
210 config.table_size = size;
211 config.table_record_limit = record_limit;
221 table_ptr->setVerbose(v);
227 config.next_iteration_coefficient = new_value;
229 searcher->setNextIterationCoefficient(new_value);
235 config.monitors.push_back(m);
242 NonBlockDelete::reset(checkmate_ptr);
243 if (speculative_search_allowed)
244 NonBlockDelete::reset(table_ptr);
249 NonBlockDelete::reset(checkmate_ptr);
250 if (speculative_search_allowed)
251 NonBlockDelete::reset(table_ptr);
258 return secondsForThisMove(state, time_limit, elapsed, byoyomi,
259 table_ptr.get() ? table_ptr->verboseLevel() : 0);
264 int byoyomi,
int verboseness)
269 if (time_limit - elapsed < byoyomi)
271 const int time_limit_org = time_limit;
278 time_limit -=
std::max(0, (240 - moves));
280 const int time_left = time_limit - elapsed;
283 int seconds_for_this_move
288 if (time_left >= 600*time_limit_org/1500)
290 if ((progress.progress16().value() >= 15)
291 && ((progress.progress16(
BLACK).value() >= 13)
292 || (progress.progress16(
WHITE).value() >= 13))) {
294 std::cerr <<
" time control endgame ext\n";
295 return seconds_for_this_move*2;
298 if (byoyomi == 0 || time_left >= byoyomi*60)
301 if (progress.progress16().value() == 0) {
303 std::cerr <<
" time control progress0 limit " << 25*time_limit_org/1500 <<
"\n";
304 return std::min(
std::max(1, 25*time_limit_org/1500), seconds_for_this_move);
306 if (progress.progress16().value() <= 3 && moves <= 40) {
308 std::cerr <<
" time control progress4 limit " << 38*time_limit_org/1500 <<
"\n";
309 return std::min(
std::max(1, 38*time_limit_org/1500), seconds_for_this_move);
313 seconds_for_this_move += byoyomi;
314 if (byoyomi >= 10 && time_left >= byoyomi*2)
315 seconds_for_this_move += byoyomi/2;
316 return seconds_for_this_move;
323 return assignTime(state, limit, elapsed, byoyomi,
324 table_ptr.get() ? table_ptr->verboseLevel() : 0);
329 int byoyomi,
int verboseness)
331 const int seconds_for_this_move
332 = secondsForThisMove(state, limit, elapsed, byoyomi, verboseness);
333 const int seconds_max = (byoyomi && (limit - elapsed) < byoyomi)
334 ? seconds_for_this_move
335 :
std::min(seconds_for_this_move*5,
std::max(seconds_for_this_move, (limit-elapsed)/2));
337 MilliSeconds::Interval(seconds_max*1000));
344 return selectBestMoveInTime(state, assignTime(state, limit, elapsed, byoyomi));
350 if (EnterKing::canDeclareWin(state.
state()))
353 && config.next_iteration_coefficient > 1.0)
354 setNextIterationCoefficient(1.0);
355 return searchWithSecondsForThisMove(state, msec);
361 (*pv_history)[state.
moveHistory().
size() % pv_history->size()] = best_move;
369 searcher->setTimeAssign(new_assign);
377 return searcher->startTime();
379 return MilliSeconds();
383 osl::game_playing::SearchPlayer::
384 NtesukiThread::NtesukiThread(
Move& next_move,
385 volatile bool *thread_finished,
386 volatile bool *stop_flag,
387 NumEffectState state)
388 : next_move(next_move), thread_finished(thread_finished),
389 stop_flag(stop_flag), state(state)
393 void osl::game_playing::SearchPlayer::
394 NtesukiThread::operator()()
396 std::cerr <<
"start ntesuki search\n";
397 *thread_finished =
false;
399 const Player P = state.turn();
400 const HashKey key = osl::HashKey::calcHash(state);;
402 boost::scoped_ptr<osl::ntesuki::NtesukiAttackMoveGenerator>
403 gam(
new osl::ntesuki::GetAttackMoves());
404 boost::scoped_ptr<osl::ntesuki::NtesukiDefenseMoveGenerator>
405 gdm(
new osl::ntesuki::GetDefenseMoves());
408 searcher(state, gam.get(), gdm.get(), 500000u, stop_flag,
true, 2);
412 int ntesuki_num = searcher.
searchSlow(P, 10000000);
413 if (-1 != ntesuki_num)
415 const osl::ntesuki::PdNtesukiTable& table
416 = searcher.getTableSlow(P);
417 const osl::ntesuki::PdNtesukiRecord *record
419 next_move = record->getBestMove(ntesuki_num).move();
422 catch (ntesuki::ReadNodeLimit& e)
425 catch (ntesuki::TableFull& e)
428 catch (std::runtime_error& e)
430 std::cerr << e.what() <<
"\n";
432 std::cerr <<
"end ntesuki search\n";
433 *thread_finished =
true;