00001 //---------------------------------------------------------------------------- 00002 /** @file GoPlayer.h 00003 Player. */ 00004 //---------------------------------------------------------------------------- 00005 00006 #ifndef GO_PLAYER_H 00007 #define GO_PLAYER_H 00008 00009 #include <string> 00010 #include "GoBoard.h" 00011 #include "GoBoardSynchronizer.h" 00012 #include "GoPlayerMove.h" 00013 #include "SgBoardColor.h" 00014 #include "SgPoint.h" 00015 00016 class SgNode; 00017 class SgTimeRecord; 00018 00019 //---------------------------------------------------------------------------- 00020 00021 /** Player. 00022 The player owns an internal Go board for computations during move 00023 generation. However, the player is linked to an external game board and 00024 needs to synchronize its internal board to the game board by calling 00025 UpdateSubscriber() inherited from its parent class GoBoardSynchronizer 00026 before calling GoPlayer::GenMove() 00027 @todo Remove non-const access to Board(). Currently still needed, because 00028 GenMove() has no toPlay argument, so if one wants to generate a move for 00029 the color not to play in the current position, one has to call 00030 Board().SetToPlay() before the GenMove(). 00031 Also, this class makes too many assumptions about the player. Not every 00032 player needs a local board for computations or needs to derive from 00033 GoBoardSynchronizer to update its state incrementally to the game board. */ 00034 class GoPlayer 00035 : public GoBoardSynchronizer 00036 { 00037 public: 00038 /** Constructor. 00039 @param bd The external game board. */ 00040 GoPlayer(const GoBoard& bd); 00041 00042 virtual ~GoPlayer(); 00043 00044 /** Deprecated. 00045 Non-const access to player board will be removed in the future. */ 00046 GoBoard& Board(); 00047 00048 /** The player's own Go board */ 00049 const GoBoard& Board() const; 00050 00051 /** Generate a move. */ 00052 virtual SgPoint GenMove(const SgTimeRecord& time, 00053 SgBlackWhite toPlay) = 0; 00054 00055 /** Get the name of this player. 00056 Default implementation returns "Unknown" */ 00057 virtual std::string Name() const; 00058 00059 /** Get node for appending search traces. 00060 @todo Rename to something more meaningful, like SearchTraces() */ 00061 SgNode* CurrentNode() const; 00062 00063 void ClearSearchTraces(); 00064 00065 /** Get node with search traces and transfer ownership to the caller. 00066 @return A node that has all search traces as children, or 0 if there 00067 are no search traces. */ 00068 SgNode* TransferSearchTraces(); 00069 00070 /** Return value for a move. 00071 Not all players assign values to moves. 00072 If a player cannot score moves in general, or cannot score this move 00073 in particular, it should return numeric_limits<int>::min() 00074 (which is what the default implementation does). 00075 Values can be positive or negative; better moves should have higher 00076 values; the units of the values are not specified. */ 00077 virtual int MoveValue(SgPoint p); 00078 00079 /** Inform the player that the game was finished. 00080 This function gives the player the opportunity to do some work at 00081 the end of a game, for example perform some learning. 00082 However it is not guaranteed that this function will be called at 00083 all, the player should not rely on it. The reason is that a game 00084 start and end is not always well-defined (setup, undo, etc.) 00085 For example, it will be called in the GTP interface if after a change 00086 on the board GoBoardUtil::EndOfGame() is true. 00087 The default implementation does nothing. */ 00088 virtual void OnGameFinished(); 00089 00090 /** Inform the player that a new game was started. 00091 This function gives the player the opportunity to clear some cached 00092 data, that is useful only within the same game. 00093 However it is not guaranteed that this function will be called at 00094 all, the player should not rely on it. The reason is that a game 00095 start and end is not always well-defined (setup, undo, etc.) 00096 For example, it will be called in the GTP interface in 00097 GoGtpEngine::Init(), or on the clear_board and loadsgf commands. 00098 The default implementation does nothing. */ 00099 virtual void OnNewGame(); 00100 00101 /** Think during opponent's time. 00102 This function should poll SgUserAbort() and return immediately if 00103 it returns true. 00104 It is good style to enable pondering in the player with a parameter 00105 and return immediately if it is not enabled. If it is enabled, it 00106 should stop after some resource limit is reached to avoid that a 00107 program is hogging the CPU if it is just waiting for commands. 00108 The function Ponder() is typically called from a different thread but 00109 without overlap with other uses of the player, so the player does not 00110 have to care about thread-safety. 00111 Default implementation does nothing and returns immediately. */ 00112 virtual void Ponder(); 00113 00114 /** See m_variant */ 00115 int Variant() const; 00116 00117 /** See m_variant */ 00118 void SetVariant(int variant); 00119 00120 protected: 00121 /** Node in game tree. Used for appending search traces */ 00122 SgNode* m_currentNode; 00123 00124 private: 00125 /** See Board() */ 00126 GoBoard m_bd; 00127 00128 /** Player variant. Used for short-term testing of small modifications. 00129 The default variant is 0. 00130 Do not use to create significantly different players - 00131 implement a new player instead. */ 00132 int m_variant; 00133 00134 /** Not implemented */ 00135 GoPlayer(const GoPlayer&); 00136 00137 /** Not implemented */ 00138 GoPlayer& operator=(const GoPlayer&); 00139 }; 00140 00141 inline GoBoard& GoPlayer::Board() 00142 { 00143 return m_bd; 00144 } 00145 00146 inline const GoBoard& GoPlayer::Board() const 00147 { 00148 return m_bd; 00149 } 00150 00151 inline SgNode* GoPlayer::CurrentNode() const 00152 { 00153 return m_currentNode; 00154 } 00155 00156 inline int GoPlayer::Variant() const 00157 { 00158 return m_variant; 00159 } 00160 00161 inline void GoPlayer::SetVariant(int variant) 00162 { 00163 m_variant = variant; 00164 } 00165 00166 //---------------------------------------------------------------------------- 00167 00168 #endif // GO_PLAYER_H 00169