Index   Main   Namespaces   Classes   Hierarchy   Annotated   Files   Compound   Global   Pages  

SgTimeRecord.h

Go to the documentation of this file.
00001 //----------------------------------------------------------------------------
00002 /** @file SgTimeRecord.h
00003     Time management. */
00004 //----------------------------------------------------------------------------
00005 
00006 #ifndef SG_TIMERECORD_H
00007 #define SG_TIMERECORD_H
00008 
00009 #include <iosfwd>
00010 #include "SgBWArray.h"
00011 
00012 class SgNode;
00013 
00014 //----------------------------------------------------------------------------
00015 
00016 /** Clock states. */
00017 enum SgClockState {
00018     /** The clock is turned off; no time is counted for either player. */
00019     SG_CLOCK_OFF,
00020 
00021     /** The time is running for one of the players. */
00022     SG_CLOCK_RUNNING,
00023 
00024     /** The running clock was turned off by the computer; some
00025         actions may automatically cause it to turn back on. */
00026     SG_CLOCK_SUSPENDED
00027 };
00028 
00029 //----------------------------------------------------------------------------
00030 
00031 /** A time record contains time-related information.
00032     How much time each player has left, how overtime is regulated, and how
00033     many moves there are left in this overtime period. This information is
00034     updated when replaying a game depending on time-related properties stored
00035     in the game tree.
00036 
00037     A time contest: dynamic time record of an ongoing game.
00038     The time left at each point in the game is stored as properties in the
00039     tree. The time stored is the time left when entering a new node; the
00040     time left while the clock is running at a node is not stored anywhere
00041     except in the TimeContest object. Thus leaving a node and returning to
00042     it later will restore the time left when first entering the node, not
00043     when leaving the node.
00044  */
00045 class SgTimeRecord
00046 {
00047 public:
00048     explicit SgTimeRecord(int numMoves = 0, double period = 0,
00049                           double overhead = 0, bool loseOnTime = false);
00050 
00051     /** Constructor.
00052         'oneMoveOnly' must be true for the second constructor (just to
00053         distinguish the two constructors). The second one creates a time
00054         record that can be used to set a specific time period for one move
00055         only. */
00056     SgTimeRecord(bool oneMoveOnly, double timeForMove);
00057 
00058     ~SgTimeRecord();
00059 
00060 
00061     /** @name Time settings for the game */
00062     // @{
00063 
00064     bool UseOvertime() const;
00065 
00066     int OTNumMoves() const;
00067 
00068     double OTPeriod() const;
00069 
00070     double Overhead() const;
00071 
00072     bool LoseOnTime() const;
00073 
00074     void SetOTNumMoves(int numMoves);
00075 
00076     void SetOTPeriod(double period);
00077 
00078     void SetOverhead(double overhead);
00079 
00080     void SetLoseOnTime(bool lose);
00081 
00082     // @} // name
00083 
00084 
00085     /** @name Clock state */
00086     // @{
00087 
00088     /** Return the state of the clock: stopped, running, or suspended. */
00089     SgClockState GetClockState() const;
00090 
00091     bool ClockIsRunning() const;
00092 
00093     /** Returns the current time left.
00094         Call UpdateTimeLeft first to get the newest information. */
00095     double TimeLeft(SgBlackWhite player) const;
00096 
00097     /** The number of moves left to play in this overtime period.
00098         This is zero if the game is in main time. */
00099     int MovesLeft(SgBlackWhite color) const;
00100 
00101     void SetTimeLeft(SgBlackWhite color, double timeLeft);
00102 
00103     /** Turn the clock on or off.
00104         @todo Set gUserAbort if the time is turned off, so that for example a
00105         search is aborted. */
00106     void TurnClockOn(bool turnOn);
00107 
00108     /** Set number of moves left to play in this overtime period.
00109         This is zero if the game is in main time. */
00110     void SetMovesLeft(SgBlackWhite color, int moves);
00111 
00112     /** Set the clock into suspended state. */
00113     void SuspendClock();
00114 
00115     /** Update the internal m_timeLeft.
00116         If the time left is negative, m_movesLeft is set if overtime is
00117         starting, or a "lost on time" is shown if m_loseOnTime is true. */
00118     void UpdateTimeLeft();
00119 
00120     // @} // name
00121 
00122 
00123     /** @name Functions for using the clock in a game */
00124     // @{
00125 
00126     /** Called by GoGame to react to user events.
00127         Called when a node is entered after moving in the tree or just to
00128         refresh the current state
00129         If the clock is on and the node is not m_atNode, the clock is
00130         suspended. m_player is set to the given player, and m_timeLeft is set
00131         to reflect the time left at that node. */
00132     void EnterNode(SgNode& node, SgBlackWhite player);
00133 
00134     /** Called by GoGame to react to user events.
00135         Called when a move was played on the board.
00136         If the clock was suspended, the clock is turned back on.
00137         Otherwise, if the clock was running, the time left is stored as
00138         properties in the new node. */
00139     void PlayedMove(SgNode& node, SgBlackWhite player);
00140 
00141     /** Set time left and store it as a property in the tree. 
00142         If time is <= 0, puts it into overtime. */
00143     void SetClock(SgNode& node, SgBlackWhite player, double time);
00144 
00145     // @} // name
00146 
00147 
00148     /** @name Utility functions */
00149     // @{
00150 
00151     /** Returns the time stored at the given node or its most recent
00152         ancestor. */
00153     static SgBWArray<double> GetTimeFromTree(SgNode& node);
00154 
00155     /** Returns the number of moves left to play in overtime as determined by
00156         the given node or an ancestor with that property. */
00157     static SgBWArray<int> GetOTMovesFromTree(SgNode& node);
00158 
00159     /** Sets the time property at the given node for both players. */
00160     static void SetTimeInTree(SgNode& node, SgBWArray<double> time);
00161 
00162     // @} // name
00163 
00164 private:
00165     /** How many moves to play in one overtime period.
00166         zero if there is no overtime. */
00167     int m_overtimeNumMoves;
00168 
00169     /** The length of one overtime period. */
00170     double m_overtimePeriod;
00171 
00172     /** How much time to subtract for each move due to time
00173         used by the operator of the program (move entry, etc.). */
00174     double m_overhead;
00175 
00176     /** Whether to end the game when a player has negative time left. */
00177     bool m_loseOnTime;
00178 
00179     /** The player whose clock is running.
00180         Only relevant if the clock is running. */
00181     SgBlackWhite m_player;
00182 
00183     /** Whether the clock is turned on and running. */
00184     bool m_clockIsOn;
00185 
00186     /** Whether the clock is suspended.
00187         Note: m_clockIsOn and m_suspended cannot both be true. */
00188     bool m_suspended;
00189 
00190     /** The current node at which the time is running. */
00191     SgNode* m_atNode;
00192 
00193     /** The time left for both players.
00194         This is updated frequently, reflecting the time stored in fAtNode
00195         minus the time spent at that node. */
00196     SgBWArray<double> m_timeLeft;
00197 
00198     /**The number of moves left to play in this overtime period.
00199        This is zero if game is in main time. */
00200     SgBWArray<int> m_movesLeft;
00201 
00202     /** The time at which fTimeLeft was last updated. */
00203     double m_timeOfLastUpdate;
00204 };
00205 
00206 inline SgTimeRecord::~SgTimeRecord()
00207 {
00208 }
00209 
00210 inline bool SgTimeRecord::ClockIsRunning() const
00211 {
00212     return m_clockIsOn;
00213 }
00214 
00215 inline bool SgTimeRecord::LoseOnTime() const
00216 {
00217     return m_loseOnTime;
00218 }
00219 
00220 inline int SgTimeRecord::MovesLeft(SgBlackWhite color) const
00221 {
00222     return m_movesLeft[color];
00223 }
00224 
00225 inline int SgTimeRecord::OTNumMoves() const
00226 {
00227     return m_overtimeNumMoves;
00228 }
00229 
00230 inline double SgTimeRecord::OTPeriod() const
00231 {
00232     return m_overtimePeriod;
00233 }
00234 
00235 inline double SgTimeRecord::Overhead() const
00236 {
00237     return m_overhead;
00238 }
00239 
00240 inline void SgTimeRecord::SetLoseOnTime(bool lose)
00241 {
00242     m_loseOnTime = lose;
00243 }
00244 
00245 inline void SgTimeRecord::SetMovesLeft(SgBlackWhite color, int moves)
00246 {
00247     SG_ASSERT(moves >= 0); m_movesLeft[color] = moves;
00248 }
00249 
00250 inline void SgTimeRecord::SetOTNumMoves(int numMoves)
00251 {
00252     m_overtimeNumMoves = numMoves;
00253 }
00254 
00255 inline void SgTimeRecord::SetOTPeriod(double period)
00256 {
00257     m_overtimePeriod = period;
00258 }
00259 
00260 inline void SgTimeRecord::SetOverhead(double overhead)
00261 {
00262     m_overhead = overhead;
00263 }
00264 
00265 inline void SgTimeRecord::SetTimeLeft(SgBlackWhite color, double timeLeft)
00266 {
00267     m_timeLeft[color] = timeLeft;
00268 }
00269 
00270 inline bool SgTimeRecord::UseOvertime() const
00271 {
00272     return m_overtimeNumMoves > 0;
00273 }
00274 
00275 //----------------------------------------------------------------------------
00276 
00277 /** Output SgTimeRecord to stream.
00278     @relatesalso SgTimeRecord */
00279 std::ostream& operator<<(std::ostream& out, const SgTimeRecord& time);
00280 
00281 /** Output SgClockState to stream. */
00282 std::ostream& operator<<(std::ostream& out, SgClockState clockState);
00283 
00284 //----------------------------------------------------------------------------
00285 
00286 #endif // SG_TIMERECORD_H


Sun Mar 13 2011 Doxygen 1.7.1