speculativeSearchPlayer.cc
Go to the documentation of this file.
00001 /* speculativeSearchPlayer.cc
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 // ;;; Local Variables:
00167 // ;;; mode:c++
00168 // ;;; c-basic-offset:2
00169 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines