Index   Main   Namespaces   Classes   Hierarchy   Annotated   Files   Compound   Global   Pages  

SgTimeRecord.cpp

Go to the documentation of this file.
00001 //----------------------------------------------------------------------------
00002 /** @file SgTimeRecord.cpp
00003     See SgTimeRecord.h. */
00004 //----------------------------------------------------------------------------
00005 
00006 #include "SgSystem.h"
00007 #include "SgTimeRecord.h"
00008 
00009 #include <iomanip>
00010 #include <limits>
00011 #include <sstream>
00012 #include "SgDebug.h"
00013 #include "SgNode.h"
00014 #include "SgProp.h"
00015 #include "SgTime.h"
00016 #include "SgWrite.h"
00017 
00018 using namespace std;
00019 
00020 //----------------------------------------------------------------------------
00021 
00022 SgTimeRecord::SgTimeRecord(int numMoves, double period, double overhead,
00023                            bool loseOnTime)
00024     : m_overtimeNumMoves(numMoves),
00025       m_overtimePeriod(period),
00026       m_overhead(overhead),
00027       m_loseOnTime(loseOnTime),
00028       m_player(SG_BLACK),
00029       m_clockIsOn(false),
00030       m_suspended(false),
00031       m_atNode(0),
00032       m_timeLeft(0),
00033       m_movesLeft(0),
00034       m_timeOfLastUpdate(0)
00035 {
00036 }
00037 
00038 SgTimeRecord::SgTimeRecord(bool oneMoveOnly, double timeForMove)
00039     : m_overtimeNumMoves(1),
00040       m_overtimePeriod(timeForMove),
00041       m_overhead(0),
00042       m_loseOnTime(false),
00043       m_player(SG_BLACK),
00044       m_clockIsOn(false),
00045       m_suspended(false),
00046       m_atNode(0),
00047       m_timeLeft(timeForMove),
00048       m_movesLeft(1),
00049       m_timeOfLastUpdate(0)
00050 {
00051     SG_DEBUG_ONLY(oneMoveOnly);
00052     SG_ASSERT(oneMoveOnly);
00053 }
00054 
00055 SgBWArray<double> SgTimeRecord::GetTimeFromTree(SgNode& node)
00056 {
00057     SgBWArray<double> time;
00058     time[SG_BLACK] =
00059         node.TopProp(SG_PROP_TIME_BLACK)->GetRealProp(SG_PROP_TIME_BLACK);
00060     time[SG_WHITE] =
00061         node.TopProp(SG_PROP_TIME_WHITE)->GetRealProp(SG_PROP_TIME_WHITE);
00062     return time;
00063 }
00064 
00065 SgBWArray<int> SgTimeRecord::GetOTMovesFromTree(SgNode& node)
00066 {
00067     SgBWArray<int> numMoves;
00068     numMoves[SG_BLACK] =
00069         node.TopProp(SG_PROP_OT_BLACK)->GetIntProp(SG_PROP_OT_BLACK);
00070     numMoves[SG_WHITE] =
00071         node.TopProp(SG_PROP_OT_WHITE)->GetIntProp(SG_PROP_OT_WHITE);
00072     return numMoves;
00073 }
00074 
00075 SgClockState SgTimeRecord::GetClockState() const
00076 {
00077     if (m_clockIsOn)
00078         return SG_CLOCK_RUNNING;
00079     else if (m_suspended)
00080         return SG_CLOCK_SUSPENDED;
00081     else
00082         return SG_CLOCK_OFF;
00083 }
00084 
00085 double SgTimeRecord::TimeLeft(SgBlackWhite player) const
00086 {
00087     SG_ASSERT_BW(player);
00088     return m_timeLeft[player];
00089 }
00090 
00091 void SgTimeRecord::SetTimeInTree(SgNode& node, SgBWArray<double> time)
00092 {
00093     node.SetRealProp(SG_PROP_TIME_BLACK, time[SG_BLACK]);
00094     node.SetRealProp(SG_PROP_TIME_WHITE, time[SG_WHITE]);
00095 }
00096 
00097 void SgTimeRecord::TurnClockOn(bool turnOn)
00098 {
00099     if (m_suspended || (turnOn != m_clockIsOn))
00100     {
00101         if (turnOn)
00102             m_timeOfLastUpdate = SgTime::Get();
00103         else
00104             UpdateTimeLeft();
00105         m_clockIsOn = turnOn;
00106         m_suspended = false;
00107     }
00108 }
00109 
00110 void SgTimeRecord::SuspendClock()
00111 {
00112     if (m_clockIsOn && ! m_suspended)
00113     {
00114         m_clockIsOn = false;
00115         m_suspended = true;
00116     }
00117 }
00118 
00119 void SgTimeRecord::SetClock(SgNode& node, SgBlackWhite player, double time)
00120 {
00121     node.SetRealProp(SgProp::PlayerProp(SG_PROP_TIME_BLACK, player), time);
00122     m_timeLeft[player] = time;
00123     if (player == m_player)
00124         m_timeOfLastUpdate = SgTime::Get();
00125     if (m_timeLeft[player] <= 0.0001)
00126     {
00127         m_timeLeft[player] = OTPeriod();
00128         m_movesLeft[player] = OTNumMoves();
00129     }
00130 }
00131 
00132 void SgTimeRecord::UpdateTimeLeft()
00133 {
00134     double now = SgTime::Get();
00135     if (m_clockIsOn && (now > m_timeOfLastUpdate))
00136     {
00137         bool outOfTime = (m_timeLeft[m_player] < now - m_timeOfLastUpdate);
00138         m_timeLeft[m_player] -= now - m_timeOfLastUpdate;
00139         if (outOfTime)
00140         {
00141             SgDebug() << "SgTimeRecord: outOfTime\n";
00142             if (UseOvertime() && m_movesLeft[m_player] <= 0)
00143             {
00144                 SgDebug() << "SgTimeRecond: reseting overtime\n";
00145                 m_timeLeft[m_player] += OTPeriod();
00146                 if (m_timeLeft[m_player] > OTPeriod())
00147                     m_timeLeft[m_player] = OTPeriod();
00148                 m_movesLeft[m_player] = OTNumMoves();
00149             }
00150             else if (LoseOnTime())
00151             {
00152                 SgDebug() << "SgTimeRecord: lost on time\n";
00153                 SuspendClock();
00154             }
00155         }
00156     }
00157     m_timeOfLastUpdate = now;
00158 }
00159 
00160 void SgTimeRecord::EnterNode(SgNode& node, SgBlackWhite player)
00161 {
00162     if (m_clockIsOn && &node != m_atNode)
00163         SuspendClock();
00164     m_player = player;
00165     if (! m_clockIsOn)
00166     {
00167         m_atNode = &node;
00168         m_timeLeft = GetTimeFromTree(node);
00169         m_movesLeft = GetOTMovesFromTree(node);
00170         // AR: commented out in Modula-2: fTimeOfLastUpdate := Ticks();
00171     }
00172 }
00173 
00174 void SgTimeRecord::PlayedMove(SgNode& node, SgBlackWhite player)
00175 {
00176     m_atNode = &node;
00177     if (m_suspended && ! node.HasSon())
00178         TurnClockOn(true);
00179     else if (m_clockIsOn)
00180     {
00181         UpdateTimeLeft();
00182         if (UseOvertime())
00183         {
00184             if (m_movesLeft[player] > 0)
00185             {
00186                 m_movesLeft[player]--;
00187                 if (m_movesLeft[player] == 0)
00188                 {
00189                     SgDebug() << "SgTimeRecond: reseting overtime\n";
00190                     m_movesLeft[player] = OTNumMoves();
00191                     m_timeLeft[player] = OTPeriod();
00192                 }
00193             }
00194             node.SetIntProp(SgProp::PlayerProp(SG_PROP_OT_BLACK, player),
00195                             m_movesLeft[player]);
00196         }
00197         m_timeLeft[player] -= Overhead();
00198         node.SetRealProp(SgProp::PlayerProp(SG_PROP_TIME_BLACK, player),
00199                          m_timeLeft[player]);
00200     }
00201 }
00202 
00203 //----------------------------------------------------------------------------
00204 
00205 ostream& operator<<(ostream& out, const SgTimeRecord& time)
00206 {
00207     out << SgWriteLabel("Overhead") << time.Overhead() << '\n'
00208         << SgWriteLabel("UseOvertime") << time.UseOvertime() << '\n'
00209         << SgWriteLabel("OTPeriod") << time.OTPeriod() << '\n'
00210         << SgWriteLabel("OTNumMoves") << time.OTNumMoves() << '\n'
00211         << SgWriteLabel("LoseOnTime") << time.LoseOnTime() << '\n'
00212         << SgWriteLabel("ClockIsRunning") << time.ClockIsRunning() << '\n'
00213         << SgWriteLabel("ClockState") << time.GetClockState() << '\n'
00214         << SgWriteLabel("TimeLeft/B") << time.TimeLeft(SG_BLACK) << '\n'
00215         << SgWriteLabel("TimeLeft/W") << time.TimeLeft(SG_WHITE) << '\n'
00216         << SgWriteLabel("MovesLeft/B") << time.MovesLeft(SG_BLACK) << '\n'
00217         << SgWriteLabel("MovesLeft/W") << time.MovesLeft(SG_WHITE) << '\n';
00218     return out;
00219 }
00220 
00221 ostream& operator<<(ostream& out, SgClockState clockState)
00222 {
00223     switch (clockState)
00224     {
00225     case SG_CLOCK_OFF:
00226         out << "CLOCK_OFF";
00227         break;
00228     case SG_CLOCK_RUNNING:
00229         out << "CLOCK_RUNNING";
00230         break;
00231     case SG_CLOCK_SUSPENDED:
00232         out << "CLOCK_SUSPENDED";
00233         break;
00234     default:
00235         SG_ASSERT(false);
00236         out << "?";
00237     }
00238     return out;
00239 }
00240 
00241 //----------------------------------------------------------------------------
00242 


Sun Mar 13 2011 Doxygen 1.7.1