00001
00002
00003 #include "osl/game_playing/speculativeSearchPlayer.h"
00004 #include "osl/game_playing/speculativeAllMoves.h"
00005 #include "osl/game_playing/gameState.h"
00006 #include "osl/game_playing/searchPlayer.h"
00007 #include "osl/hash/hashKeyStack.h"
00008 #include "osl/container/moveStack.h"
00009 #include "osl/sennichite.h"
00010 #include "osl/misc/nonBlockDelete.h"
00011 #include "osl/misc/ctime.h"
00012 #include <iostream>
00013 #include <ctime>
00014 #ifndef _MSC_VER
00015 # include <unistd.h>
00016 #endif
00017
00018
00019 osl::game_playing::SpeculativeSearchPlayer::
00020 SpeculativeSearchPlayer(Player my_turn, SearchPlayer *player)
00021 : main_player(player),
00022 speculative(new SpeculativeAllMoves()),
00023 my_turn(my_turn)
00024 {
00025 }
00026
00027 osl::game_playing::
00028 SpeculativeSearchPlayer::~SpeculativeSearchPlayer()
00029 {
00030 }
00031
00032 osl::game_playing::ComputerPlayer*
00033 osl::game_playing::SpeculativeSearchPlayer::clone() const
00034 {
00035 return new SpeculativeSearchPlayer(my_turn,
00036 dynamic_cast<SearchPlayer*>(main_player->clone()));
00037 }
00038
00039 void osl::game_playing::SpeculativeSearchPlayer::
00040 setMaxThreads(int new_max_threads)
00041 {
00042 speculative->setMaxThreads(new_max_threads);
00043 }
00044
00045 void osl::game_playing::SpeculativeSearchPlayer::
00046 pushMove(Move m)
00047 {
00048 main_player->pushMove(m);
00049 if (m.player() == my_turn)
00050 {
00051 if (previous_state.get() && speculative_search_allowed)
00052 {
00053 #ifndef GPSONE
00054 if (OslConfig::usiMode())
00055 OslConfig::setUsiSilent(true);
00056 #endif
00057 try
00058 {
00059 previous_state->pushMove(m);
00060 speculative->startSpeculative(previous_state, *main_player);
00061 }
00062 catch (std::exception& e)
00063 {
00064 std::cerr << e.what() << " in SpeculativeSearchPlayer::pushMove\n";
00065 speculative->clearResource();
00066 }
00067 NonBlockDelete::reset(previous_state);
00068 }
00069 }
00070 else
00071 {
00072 if (speculative_search_allowed)
00073 speculative->stopOtherThan(m);
00074 }
00075 }
00076
00077 void osl::game_playing::SpeculativeSearchPlayer::
00078 popMove()
00079 {
00080 main_player->popMove();
00081 previous_state.reset();
00082 speculative->stopAll();
00083 }
00084
00085 bool osl::game_playing::SpeculativeSearchPlayer::
00086 stopSearchNow()
00087 {
00088 return main_player->stopSearchNow();
00089 }
00090
00091 osl::search::TimeAssigned osl::game_playing::SpeculativeSearchPlayer::
00092 standardSearchSeconds(const GameState& state, int limit, int elapsed, int byoyomi) const
00093 {
00094 search::TimeAssigned result = main_player->assignTime(state, limit, elapsed, byoyomi);
00095 if (result.standard.value() > 2000) {
00096 result.standard = result.standard - MilliSeconds::Interval(500);
00097 result.max = result.max - MilliSeconds::Interval(500);
00098 }
00099 return result;
00100 }
00101
00102 const osl::search::MoveWithComment
00103 osl::game_playing::SpeculativeSearchPlayer::
00104 selectBestMove(const GameState& state, int limit, int elapsed, int byoyomi)
00105 {
00106 if (elapsed > limit)
00107 elapsed = limit;
00108 const time_t start_time = time(0);
00109 MoveWithComment result = MoveWithComment(Move::INVALID());
00110 const Move last_move = state.moveHistory().lastMove();
00111
00112 const HashKey search_key(speculative->searchState());
00113 const HashKey now_key(last_move.isNormal() ? state.hashHistory().top(1) : HashKey());
00114 const bool consistent = (search_key == now_key);
00115
00116 const search::TimeAssigned wait_for = consistent
00117 ? standardSearchSeconds(state, limit, elapsed, byoyomi)
00118 : search::TimeAssigned(MilliSeconds::Interval(0));
00119
00120 if (last_move.isNormal())
00121 result = speculative->waitResult(last_move, wait_for, *main_player,
00122 byoyomi);
00123
00124 const time_t now = time(0);
00125 char ctime_buf[64];
00126 if (! consistent && result.move.isNormal())
00127 std::cerr << "note: the current position differs from the one which previous prediction search ran on\n";
00128 if (result.move.isNormal() && consistent) {
00129 #ifdef DEBUG_SPECULATIVE_EXECUTION
00130 std::cerr << "returned " << record::csa::show(result.move)
00131 << " " << ctime_r(&now, ctime_buf);
00132 #endif
00133 selectBestMoveCleanUp(state);
00134 main_player->saveSearchResult(state, result);
00135 return result;
00136 }
00137 std::cerr << "search again " << ctime_r(&now, ctime_buf);
00138 selectBestMoveCleanUp(state);
00139 #ifndef GPSONE
00140 if (OslConfig::usiMode())
00141 OslConfig::setUsiSilent(false);
00142 #endif
00143 const int consumed = (now - start_time);
00144 if (byoyomi && (limit <= elapsed+consumed))
00145 byoyomi = std::max(1, byoyomi - (elapsed+consumed-limit));
00146
00147 result = main_player->selectBestMove(state, limit, std::min(limit-1, elapsed+consumed), byoyomi);
00148 return result;
00149 }
00150
00151 void osl::game_playing::SpeculativeSearchPlayer::
00152 selectBestMoveCleanUp(const GameState& state)
00153 {
00154 try
00155 {
00156 previous_state = state.clone();
00157 }
00158 catch (std::exception& e)
00159 {
00160 std::cerr << e.what() << std::endl;
00161 previous_state.reset();
00162 }
00163 speculative->selectBestMoveCleanUp();
00164 }
00165
00166
00167
00168
00169