00001 //---------------------------------------------------------------------------- 00002 /** @file GoUctSearch.h */ 00003 //---------------------------------------------------------------------------- 00004 00005 #ifndef GOUCT_SEARCH_H 00006 #define GOUCT_SEARCH_H 00007 00008 #include <iosfwd> 00009 #include "GoBoard.h" 00010 #include "GoBoardHistory.h" 00011 #include "GoBoardSynchronizer.h" 00012 #include "GoUctBoard.h" 00013 #include "SgUctSearch.h" 00014 #include "SgBlackWhite.h" 00015 #include "SgStatistics.h" 00016 00017 class SgNode; 00018 00019 //---------------------------------------------------------------------------- 00020 00021 /** Thread state for GoUctSearch. */ 00022 class GoUctState 00023 : public SgUctThreadState 00024 { 00025 public: 00026 /** Constructor. 00027 @param threadId The number of the thread. Needed for passing to 00028 constructor of SgUctThreadState. 00029 @param bd The board with the current position. The state has is own 00030 board that will be synchronized with the currently searched position 00031 in StartSearch() */ 00032 GoUctState(unsigned int threadId, const GoBoard& bd); 00033 00034 /** @name Pure virtual functions of SgUctThreadState */ 00035 // @{ 00036 00037 void StartSearch(); 00038 00039 /** Implementation of SgUctSearch::Execute */ 00040 void Execute(SgMove move); 00041 00042 /** Implementation of SgUctSearch::ExecutePlayout */ 00043 void ExecutePlayout(SgMove move); 00044 00045 void TakeBackInTree(std::size_t nuMoves); 00046 00047 void TakeBackPlayout(std::size_t nuMoves); 00048 00049 // @} // @name 00050 00051 00052 /** @name Virtual functions of SgUctThreadState */ 00053 // @{ 00054 00055 void GameStart(); 00056 00057 void StartPlayout(); 00058 00059 void StartPlayouts(); 00060 00061 // @} // @name 00062 00063 /** Board used during in-tree phase. */ 00064 const GoBoard& Board() const; 00065 00066 /** Board used during playout phase. */ 00067 const GoUctBoard& UctBoard() const; 00068 00069 bool IsInPlayout() const; 00070 00071 /** Length of the current game from the root position of the search. */ 00072 std::size_t GameLength() const; 00073 00074 void Dump(std::ostream& out) const; 00075 00076 private: 00077 /** Assertion handler to dump the state of a GoUctState. */ 00078 class AssertionHandler 00079 : public SgAssertionHandler 00080 { 00081 public: 00082 AssertionHandler(const GoUctState& state); 00083 00084 void Run(); 00085 00086 private: 00087 const GoUctState& m_state; 00088 }; 00089 00090 AssertionHandler m_assertionHandler; 00091 00092 /** Board used for in-tree phase. */ 00093 GoBoard m_bd; 00094 00095 /** Board used for playout phase. */ 00096 GoUctBoard m_uctBd; 00097 00098 GoBoardSynchronizer m_synchronizer; 00099 00100 bool m_isInPlayout; 00101 00102 /** See GameLength() */ 00103 std::size_t m_gameLength; 00104 }; 00105 00106 inline const GoBoard& GoUctState::Board() const 00107 { 00108 return m_bd; 00109 } 00110 00111 inline std::size_t GoUctState::GameLength() const 00112 { 00113 return m_gameLength; 00114 } 00115 00116 inline bool GoUctState::IsInPlayout() const 00117 { 00118 return m_isInPlayout; 00119 } 00120 00121 inline const GoUctBoard& GoUctState::UctBoard() const 00122 { 00123 return m_uctBd; 00124 } 00125 00126 //---------------------------------------------------------------------------- 00127 00128 /** Live-gfx mode used in GoUctSearch. 00129 @see GoUctSearch::LiveGfx. */ 00130 enum GoUctLiveGfx 00131 { 00132 /** Don't print live-gfx information. */ 00133 GOUCT_LIVEGFX_NONE, 00134 00135 /** Print values and counts as in GoUctUtil::GoGuiGfx() */ 00136 GOUCT_LIVEGFX_COUNTS, 00137 00138 /** Show GoGui live graphics with the main variation. 00139 Shows the main variation on the board instead of the counts and values 00140 (main variation and counts cannot be shown at the same time, because 00141 the sequence numbers conflict with the counts). 00142 The status line shows the same information as in GoGuiGfx() */ 00143 GOUCT_LIVEGFX_SEQUENCE 00144 }; 00145 00146 //---------------------------------------------------------------------------- 00147 00148 /** Base class for UCT searches in Go. */ 00149 class GoUctSearch 00150 : public SgUctSearch 00151 { 00152 public: 00153 /** Constructor. 00154 @param bd The board 00155 @param factory */ 00156 GoUctSearch(GoBoard& bd, SgUctThreadStateFactory* factory); 00157 00158 ~GoUctSearch(); 00159 00160 00161 /** @name Pure virtual functions of SgUctSearch */ 00162 // @{ 00163 00164 std::string MoveString(SgMove move) const; 00165 00166 /** Color to play at the root node of the last search. */ 00167 SgBlackWhite ToPlay() const; 00168 00169 // @} // @name 00170 00171 00172 /** @name Virtual functions of SgUctSearch */ 00173 // @{ 00174 00175 void OnSearchIteration(SgUctValue gameNumber, unsigned int threadId, 00176 const SgUctGameInfo& info); 00177 00178 void OnStartSearch(); 00179 00180 // @} // @name 00181 00182 00183 /** @name Go-specific functions */ 00184 // @{ 00185 00186 GoBoard& Board(); 00187 00188 const GoBoard& Board() const; 00189 00190 /** See SetKeepGames() 00191 @throws SgException if KeepGames() was false at last invocation of 00192 StartSearch() */ 00193 void SaveGames(const std::string& fileName) const; 00194 00195 /** See GoUctUtil::SaveTree() */ 00196 void SaveTree(std::ostream& out, int maxDepth = -1) const; 00197 00198 /** Set initial color to play. */ 00199 void SetToPlay(SgBlackWhite toPlay); 00200 00201 /** Identifier for the position the last search was performed on. */ 00202 const GoBoardHistory& BoardHistory() const; 00203 00204 // @} // @name 00205 00206 00207 /** @name Go-specific parameters */ 00208 // @{ 00209 00210 /** Keep a SGF tree of all games. 00211 This is reset in OnStartSearch() and can be saved with SaveGames(). */ 00212 bool KeepGames() const; 00213 00214 /** See KeepGames() */ 00215 void SetKeepGames(bool enable); 00216 00217 /** Output live graphics commands for GoGui. 00218 If enabled, LiveGfx commands for GoGui are outputted to the debug 00219 stream every n games. Note that GoUctUtil::GoGuiGfx() outputs values 00220 as influence data and assumes values in [0:1]. 00221 @see GoUctLiveGfxMode, LiveGfxInterval() */ 00222 GoUctLiveGfx LiveGfx() const; 00223 00224 /** See LiveGfx() */ 00225 void SetLiveGfx(GoUctLiveGfx mode); 00226 00227 /** Interval for outputting of live graphics commands for GoGui. 00228 Default is every 5000 games. 00229 @see LiveGfx() */ 00230 SgUctValue LiveGfxInterval() const; 00231 00232 /** See LiveGfxInterval() */ 00233 void SetLiveGfxInterval(SgUctValue interval); 00234 00235 // @} // @name 00236 00237 protected: 00238 virtual void DisplayGfx(); 00239 00240 private: 00241 /** See SetKeepGames() */ 00242 bool m_keepGames; 00243 00244 /** See SetLiveGfxInterval() */ 00245 SgUctValue m_liveGfxInterval; 00246 00247 volatile SgUctValue m_nextLiveGfx; 00248 00249 /** Color to play. 00250 Does not use GoBoard::ToPlay(), because the color to play at the 00251 root node of the search could be needed after the board has 00252 changed (e.g. when saving the tree after a move was generated and 00253 played on the board). */ 00254 SgBlackWhite m_toPlay; 00255 00256 /** Stones of position that the current search tree belongs to. 00257 Needed such that the tree can be saved even if the board has 00258 changed (e.g. after a move was generated and played). */ 00259 SgBWSet m_stones; 00260 00261 GoBoard& m_bd; 00262 00263 /** See SetKeepGames() */ 00264 SgNode* m_root; 00265 00266 GoUctLiveGfx m_liveGfx; 00267 00268 GoBoardHistory m_boardHistory; 00269 00270 /** Not implemented */ 00271 GoUctSearch(const GoUctSearch& search); 00272 00273 /** Not implemented */ 00274 GoUctSearch& operator=(const GoUctSearch& search); 00275 }; 00276 00277 inline GoBoard& GoUctSearch::Board() 00278 { 00279 return m_bd; 00280 } 00281 00282 inline const GoBoard& GoUctSearch::Board() const 00283 { 00284 return m_bd; 00285 } 00286 00287 inline const GoBoardHistory& GoUctSearch::BoardHistory() const 00288 { 00289 return m_boardHistory; 00290 } 00291 00292 inline bool GoUctSearch::KeepGames() const 00293 { 00294 return m_keepGames; 00295 } 00296 00297 inline GoUctLiveGfx GoUctSearch::LiveGfx() const 00298 { 00299 return m_liveGfx; 00300 } 00301 00302 inline SgUctValue GoUctSearch::LiveGfxInterval() const 00303 { 00304 return m_liveGfxInterval; 00305 } 00306 00307 inline void GoUctSearch::SetKeepGames(bool enable) 00308 { 00309 m_keepGames = enable; 00310 } 00311 00312 inline void GoUctSearch::SetLiveGfx(GoUctLiveGfx mode) 00313 { 00314 m_liveGfx = mode; 00315 } 00316 00317 inline void GoUctSearch::SetLiveGfxInterval(SgUctValue interval) 00318 { 00319 SG_ASSERT(interval > 0); 00320 m_liveGfxInterval = interval; 00321 } 00322 00323 inline void GoUctSearch::SetToPlay(SgBlackWhite toPlay) 00324 { 00325 m_toPlay = toPlay; 00326 m_bd.SetToPlay(toPlay); 00327 } 00328 00329 //---------------------------------------------------------------------------- 00330 00331 /** Utility functions for users of GoUctSearch. */ 00332 namespace GoUctSearchUtil 00333 { 00334 /** Checks if move is a bad pass move, if Tromp-Taylor rules are used, 00335 and tries to fix it. 00336 The rationale for this function is, that a UCT search sometimes plays 00337 an early pass move, which allows the opponent to end the game by also 00338 playing pass, and might lose the game, because all stones on the board 00339 are considered alive under Tromp-Taylor rules. This happens mostly 00340 if the UCT search uses RAVE or prior knowledge and the pass move by 00341 the opponent will not be explored for a while. Fortunately, this can 00342 be fixed after the search: if the Tromp-Taylor score of the current 00343 position is worse than the value of the root node of the search, then 00344 we extract the second best move from the search tree. 00345 @param move The move returned by the search 00346 @param search The search, containing the tree with the last search 00347 and other needed information (like board, rules, 00348 SgUctSearch::ToPlay(), SgUctSearch::UseCount()) 00349 @return The second best move, if the above applies and such a move 00350 exists. */ 00351 SgPoint TrompTaylorPassCheck(SgPoint move, const GoUctSearch& search); 00352 } 00353 00354 //---------------------------------------------------------------------------- 00355 00356 #endif // GOUCT_SEARCH_H