All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
speculativeSearchPlayer.cc
Go to the documentation of this file.
1 /* speculativeSearchPlayer.cc
2  */
9 #include "osl/sennichite.h"
11 #include "osl/misc/ctime.h"
12 #include <iostream>
13 #include <ctime>
14 #ifndef _MSC_VER
15 # include <unistd.h>
16 #endif
17 
18 
21  : main_player(player),
22  speculative(new SpeculativeAllMoves()),
23  my_turn(my_turn)
24 {
25 }
26 
29 {
30 }
31 
34 {
35  return new SpeculativeSearchPlayer(my_turn,
36  dynamic_cast<SearchPlayer*>(main_player->clone()));
37 }
38 
40 setMaxThreads(int new_max_threads)
41 {
42  speculative->setMaxThreads(new_max_threads);
43 }
44 
47 {
48  main_player->pushMove(m);
49  if (m.player() == my_turn)
50  {
51  if (previous_state.get() && speculative_search_allowed)
52  {
53 #ifndef GPSONE
54  if (OslConfig::usiMode())
56 #endif
57  try
58  {
59  previous_state->pushMove(m);
60  speculative->startSpeculative(previous_state, *main_player);
61  }
62  catch (std::exception& e)
63  {
64  std::cerr << e.what() << " in SpeculativeSearchPlayer::pushMove\n";
65  speculative->clearResource();
66  }
67  NonBlockDelete::reset(previous_state);
68  }
69  }
70  else
71  {
72  if (speculative_search_allowed)
73  speculative->stopOtherThan(m);
74  }
75 }
76 
79 {
80  main_player->popMove();
81  previous_state.reset();
82  speculative->stopAll();
83 }
84 
87 {
88  return main_player->stopSearchNow();
89 }
90 
92 standardSearchSeconds(const GameState& state, int limit, int elapsed, int byoyomi) const
93 {
94  search::TimeAssigned result = main_player->assignTime(state, limit, elapsed, byoyomi);
95  if (result.standard.value() > 2000) {
96  result.standard = result.standard - MilliSeconds::Interval(500);
97  result.max = result.max - MilliSeconds::Interval(500);
98  }
99  return result;
100 }
101 
104 selectBestMove(const GameState& state, int limit, int elapsed, int byoyomi)
105 {
106  if (elapsed > limit)
107  elapsed = limit;
108  const time_t start_time = time(0);
109  MoveWithComment result = MoveWithComment(Move::INVALID());
110  const Move last_move = state.moveHistory().lastMove();
111 
112  const HashKey search_key(speculative->searchState());
113  const HashKey now_key(last_move.isNormal() ? state.hashHistory().top(1) : HashKey());
114  const bool consistent = (search_key == now_key);
115 
116  const search::TimeAssigned wait_for = consistent
117  ? standardSearchSeconds(state, limit, elapsed, byoyomi)
118  : search::TimeAssigned(MilliSeconds::Interval(0));
119 
120  if (last_move.isNormal())
121  result = speculative->waitResult(last_move, wait_for, *main_player,
122  byoyomi);
123 
124  const time_t now = time(0);
125  char ctime_buf[64];
126  if (! consistent && result.move.isNormal())
127  std::cerr << "note: the current position differs from the one which previous prediction search ran on\n";
128  if (result.move.isNormal() && consistent) {
129 #ifdef DEBUG_SPECULATIVE_EXECUTION
130  std::cerr << "returned " << record::csa::show(result.move)
131  << " " << ctime_r(&now, ctime_buf);
132 #endif
133  selectBestMoveCleanUp(state);
134  main_player->saveSearchResult(state, result);
135  return result;
136  }
137  std::cerr << "search again " << ctime_r(&now, ctime_buf);
138  selectBestMoveCleanUp(state);
139 #ifndef GPSONE
140  if (OslConfig::usiMode())
142 #endif
143  const int consumed = (now - start_time);
144  if (byoyomi && (limit <= elapsed+consumed))
145  byoyomi = std::max(1, byoyomi - (elapsed+consumed-limit));
146 
147  result = main_player->selectBestMove(state, limit, std::min(limit-1, elapsed+consumed), byoyomi);
148  return result;
149 }
150 
153 {
154  try
155  {
156  previous_state = state.clone();
157  }
158  catch (std::exception& e)
159  {
160  std::cerr << e.what() << std::endl;
161  previous_state.reset();
162  }
163  speculative->selectBestMoveCleanUp();
164 }
165 
166 // ;;; Local Variables:
167 // ;;; mode:c++
168 // ;;; c-basic-offset:2
169 // ;;; End: