Index   Main   Namespaces   Classes   Hierarchy   Annotated   Files   Compound   Global   Pages  

GoGame.h

Go to the documentation of this file.
00001 //----------------------------------------------------------------------------
00002 /** @file GoGame.h
00003     GoGameRecord class, play and replay moves in a game tree.
00004 
00005     GoGame implements the GoGameRecord class, which provides functions for
00006     playing and replaying moves in a game tree.
00007     Derived from it is the GoGame class, which allows two Player objects
00008     to play a game against each other.
00009 */
00010 //----------------------------------------------------------------------------
00011 
00012 #ifndef GO_GAME_H
00013 #define GO_GAME_H
00014 
00015 #include <string>
00016 #include "GoBoard.h"
00017 #include "GoBoardUpdater.h"
00018 #include "GoBoardUtil.h"
00019 #include "SgNode.h"
00020 #include "SgPoint.h"
00021 #include "SgTimeRecord.h"
00022 
00023 class GoPlayer;
00024 class GoPlayerMove;
00025 class SgSearchStatistics;
00026 
00027 //----------------------------------------------------------------------------
00028 
00029 /** Game stored as a tree of moves.
00030     @note What is wrong with this class? It exposes non-const access to its
00031     data members and therefore cannot guarantee the integrity of its state. In
00032     the future, this class should only provide read access to the board, tree,
00033     and current node pointer. All modifications to and navigation in the tree
00034     should only be possible through member functions of this class, such that
00035     it can guarantee that its invariants are met (i.e. the board position
00036     always belongs to the current node and the current node always points to a
00037     valid node in the tree).
00038 */
00039 class GoGameRecord
00040 {
00041 public:
00042     /** Create a game record for replaying games on the given board. */
00043     explicit GoGameRecord(GoBoard& board);
00044 
00045     virtual ~GoGameRecord();
00046 
00047     /** Delete the old game record and start with a fresh one.
00048         If 'root' is 0, create a root node to start with,
00049         otherwise use the game tree passed in 'root'.
00050         If 'fTakeOwnership', the game record will delete this tree when
00051         it's destroyed, otherwise the client is reponsible
00052         for deleting the tree.
00053         @todo AR: change comment
00054     */
00055     virtual void InitFromRoot(SgNode* root, bool fTakeOwnership);
00056 
00057     /** Delete the old game record and start with a fresh one.
00058         Init the board with the given parameters, and create a root node
00059         to start with.
00060     */
00061     virtual void Init(int size, const GoRules& rules);
00062 
00063     /** Hook for subclasses.
00064         Default implementation does nothing.
00065     */
00066     virtual void OnGoToNode(SgNode* dest);
00067 
00068     /** Override to initialize other boards in derived classes.
00069         @see GoBoard
00070     */
00071     virtual void OnInitBoard(int size, const GoRules& rules);
00072 
00073     virtual void OnInitHandicap(const GoRules& rules, SgNode* root);
00074 
00075     /** Get the board associated with this game record. */
00076     const GoBoard& Board() const;
00077 
00078     /** Return the root of this tree. */
00079     SgNode& Root() const;
00080 
00081     /** Add move to the game record.
00082         Add move as the next move at the current position.
00083         If a node with that move already exists, then don't add a new one.
00084         Return the node with that move.
00085         Also add any statistics from 'stat' and time left to that node.
00086     */
00087     SgNode* AddMove(SgMove move, SgBlackWhite player,
00088                     const SgSearchStatistics* stat = 0);
00089 
00090     /** Add a node with a comment that a player resigned.
00091         For informational purposes only, the resign node will not be made
00092         the current node.
00093     */
00094     SgNode* AddResignNode(SgBlackWhite player);
00095 
00096     /** Play to the given node.
00097         @c dest must be in this tree, or 0.
00098         Also updates the clock.
00099     */
00100     void GoToNode(SgNode* dest);
00101 
00102     /** Play to the next node in the given direction. */
00103     void GoInDirection(SgNode::Direction dir);
00104 
00105     /** Return whether there is a next node in the given direction. */
00106     bool CanGoInDirection(SgNode::Direction dir) const;
00107 
00108     /** Set the current player. */
00109     void SetToPlay(SgBlackWhite player);
00110 
00111     /** Return whether the game is finished. */
00112     bool EndOfGame() const;
00113 
00114     /** Get the name of the given player.
00115         Return the blank string if unknown.
00116         Override to get information from an ongoing game rather than fron the
00117         game record.
00118     */
00119     virtual std::string GetPlayerName(SgBlackWhite player) const;
00120 
00121     /** Return the current score (black minus white).
00122         @todo: in what units?
00123         Return true if there's a score recorded in the tree, otherwise false.
00124         Override to return information about the score from a player.
00125     */
00126     virtual bool GetScore(int* score) const;
00127 
00128     /** The time left in the game at the current position. */
00129     SgTimeRecord& Time();
00130 
00131     /** The time left in the game at the current position. */
00132     const SgTimeRecord& Time() const;
00133 
00134     /** Return the current position in the tree.
00135         @todo changed from protected to public because of getting
00136         the current time left.
00137     */
00138     SgNode* CurrentNode();
00139 
00140     /** Return the current position in the tree.
00141         @todo changed from protected to public because of getting
00142         the current time left.
00143     */
00144     const SgNode* CurrentNode() const;
00145 
00146     /** Whether this game record owns the game tree. */
00147     bool OwnsTree() const;
00148 
00149     bool CanDeleteCurrentNode() const;
00150 
00151     /** Return the move of the current node.
00152         Return NullMove if no current move.
00153     */
00154     SgMove CurrentMove() const;
00155 
00156     /** Get the number of moves since root or last node with setup
00157         properties.
00158     */
00159     int CurrentMoveNumber() const;
00160 
00161 private:
00162     /** The position in the current tree. */
00163     SgNode* m_current;
00164 
00165     GoBoard& m_board;
00166 
00167     GoBoardUpdater m_updater;
00168 
00169     /** A record of the clock settings and time left. */
00170     SgTimeRecord m_time;
00171 
00172     /** Whether this game record owns the game tree. */
00173     bool m_ownsTree;
00174 
00175     /** Comment display. */
00176     SgNode* m_oldCommentNode;
00177 
00178     /** Moves inserted into a line of play instead of added at the end. */
00179     int m_numMovesToInsert;
00180 
00181     /** Not implemented. */
00182     GoGameRecord(const GoGameRecord&);
00183 
00184     /** Not implemented. */
00185     GoGameRecord& operator=(const GoGameRecord&);
00186 
00187     /** Delete the tree and initialize the state associated with the position
00188         in the tree.
00189     */
00190     void DeleteTreeAndInitState();
00191 };
00192 
00193 inline const GoBoard& GoGameRecord::Board() const
00194 {
00195     return m_board;
00196 }
00197 
00198 inline SgNode& GoGameRecord::Root() const
00199 {
00200     SG_ASSERT(m_current);
00201     return *m_current->Root();
00202 }
00203 
00204 inline SgTimeRecord& GoGameRecord::Time()
00205 {
00206     return m_time;
00207 }
00208 
00209 inline const SgTimeRecord& GoGameRecord::Time() const
00210 {
00211     return m_time;
00212 }
00213 
00214 inline SgNode* GoGameRecord::CurrentNode()
00215 {
00216     return m_current;
00217 }
00218 
00219 inline const SgNode* GoGameRecord::CurrentNode() const
00220 {
00221     return m_current;
00222 }
00223 
00224 inline bool GoGameRecord::OwnsTree() const
00225 {
00226     return m_ownsTree;
00227 }
00228 
00229 //----------------------------------------------------------------------------
00230 
00231 /** Utility functions for GoGameRecord. */
00232 namespace GoGameUtil
00233 {
00234     /** Goto last node in main variation before move number.
00235         This function can be used for implementing the loadsgf GTP command.
00236         @param game (current node must be root)
00237         @param moveNumber move number (-1 means goto last node in main
00238         variation)
00239         @return false if moveNumber greater than moves in main variation
00240     */
00241     bool GotoBeforeMove(GoGameRecord* game, int moveNumber);
00242 }
00243 
00244 //----------------------------------------------------------------------------
00245 
00246 /** Game record played between two players.
00247     A GoGame object handles the synchronization between the players
00248     and the board they're playing on, and keeps track of the time.
00249 */
00250 class GoGame
00251     : public GoGameRecord
00252 {
00253 public:
00254     explicit GoGame(GoBoard& board);
00255 
00256     virtual ~GoGame();
00257 
00258     /** Needed to avoid hiding of inherited virtual function by the
00259         other variants of GoGame::Init.
00260     */
00261     virtual void InitFromRoot(SgNode* root, bool fTakeOwnership)
00262     {
00263         GoGameRecord::InitFromRoot(root, fTakeOwnership);
00264     }
00265 
00266     /** Needed to avoid hiding of inherited virtual function by the
00267         other variants of GoGame::Init.
00268     */
00269     void Init(int size, const GoRules& rules);
00270 
00271     void Init(SgNode* root, bool fTakeOwnership, bool fDeletePlayers);
00272 
00273     void Init(int size, const GoRules& rules, bool fDeletePlayers);
00274 
00275     void OnGoToNode(SgNode* dest);
00276 
00277     /** Turn the clock on or off.
00278         Call this method instead of Time().TurnClockOn
00279         so that computer player is started and stopped appropriately.
00280     */
00281     void TurnClockOn(bool turnOn);
00282 
00283     /** Return whether the clock is running (not stopped or suspended). */
00284     bool ClockIsRunning() const { return Time().ClockIsRunning(); }
00285 
00286     /** Set the player 'color' to the player algorithm 'player'.
00287         The old player of that color is stopped and deleted, and the new
00288         player is initialized to the current board state.
00289         A 0 player means user interaction.
00290     */
00291     void SetPlayer(SgBlackWhite color, GoPlayer* player);
00292 
00293     /** Delete the player 'color' (set it to interactive input).
00294         @note If black and white point to the same player, delete will be
00295         called only once, but both players will be set to null.
00296     */
00297     void DeletePlayer(SgBlackWhite color);
00298 
00299     /** Whether the human move at 'move' can be played at this point.
00300         The move must be legal, and either it's a human player to play
00301         or the clock is inactive.
00302     */
00303     bool CanPlayHumanMove(SgMove move, SgBlackWhite player) const;
00304 
00305     /** Adds a move to the game record and tells all other players to update
00306         their boards.
00307         Returns whether the move was added to the game record.
00308         @todo AR: to be replaced by HumanPlayer.
00309     */
00310     bool PlayHumanMove(SgMove move, SgBlackWhite player);
00311 
00312     void PlayComputerMove(const GoPlayerMove* playerMove);
00313 
00314     GoPlayer* Player(SgBlackWhite player);
00315 
00316     /** Compute and play one move using the given player. */
00317     GoPlayerMove PlayOneMove(SgBlackWhite playerColor);
00318 
00319 private:
00320     /** Black and white player. */
00321     SgBWArray<GoPlayer*> m_player;
00322 
00323     /** Not implemented. */
00324     GoGame(const GoGame&);
00325 
00326     /** Not implemented. */
00327     GoGame& operator=(const GoGame&);
00328 
00329     void UpdatePlayer(SgBlackWhite color);
00330 
00331     void UpdatePlayers();
00332 };
00333 
00334 inline GoPlayer* GoGame::Player(SgBlackWhite player)
00335 {
00336     return m_player[player];
00337 }
00338 
00339 //----------------------------------------------------------------------------
00340 
00341 #endif // GO_GAME_H
00342 


17 Jun 2010 Doxygen 1.4.7