00001 //---------------------------------------------------------------------------- 00002 /** @file SgTimeControl.cpp 00003 See SgTimeControl.h */ 00004 //---------------------------------------------------------------------------- 00005 00006 #include "SgSystem.h" 00007 #include "SgTimeControl.h" 00008 00009 #include "SgDebug.h" 00010 #include "SgTimeRecord.h" 00011 00012 using namespace std; 00013 00014 //---------------------------------------------------------------------------- 00015 00016 SgTimeControl::~SgTimeControl() 00017 { 00018 } 00019 00020 //---------------------------------------------------------------------------- 00021 00022 SgDefaultTimeControl::SgDefaultTimeControl() 00023 : m_fastOpenFactor(0.25), 00024 m_fastOpenMoves(0), 00025 m_minTime(0), 00026 m_remainingConstant(1.0) 00027 { 00028 } 00029 00030 double SgDefaultTimeControl::FastOpenFactor() const 00031 { 00032 return m_fastOpenFactor; 00033 } 00034 00035 int SgDefaultTimeControl::FastOpenMoves() const 00036 { 00037 return m_fastOpenMoves; 00038 } 00039 00040 double SgDefaultTimeControl::RemainingConstant() const 00041 { 00042 return m_remainingConstant; 00043 } 00044 00045 void SgDefaultTimeControl::SetRemainingConstant(double value) 00046 { 00047 m_remainingConstant = value; 00048 } 00049 00050 void SgDefaultTimeControl::SetFastOpenFactor(double factor) 00051 { 00052 m_fastOpenFactor = factor; 00053 } 00054 00055 void SgDefaultTimeControl::SetFastOpenMoves(int nummoves) 00056 { 00057 m_fastOpenMoves = nummoves; 00058 } 00059 00060 void SgDefaultTimeControl::SetMinTime(double mintime) 00061 { 00062 m_minTime = mintime; 00063 } 00064 00065 double SgDefaultTimeControl::TimeForCurrentMove(const SgTimeRecord& time, 00066 bool quiet) 00067 { 00068 SgBlackWhite toPlay; 00069 int estimatedRemainingMoves; 00070 int movesPlayed; 00071 GetPositionInfo(toPlay, movesPlayed, estimatedRemainingMoves); 00072 const bool useOvertime = time.UseOvertime(); 00073 const bool isInOvertime = (useOvertime && time.MovesLeft(toPlay) > 0); 00074 double remainingMoves = 0.0; 00075 double timeForMove = 0.0; 00076 double timeLeft = time.TimeLeft(toPlay); 00077 if (isInOvertime) 00078 { 00079 remainingMoves = time.MovesLeft(toPlay); 00080 timeForMove = timeLeft / remainingMoves - time.Overhead(); 00081 } 00082 else 00083 { 00084 double estimatedTotalMoves = movesPlayed + estimatedRemainingMoves; 00085 remainingMoves = m_remainingConstant * estimatedTotalMoves; 00086 if (useOvertime && remainingMoves > estimatedRemainingMoves) 00087 remainingMoves = estimatedRemainingMoves; 00088 remainingMoves = max(remainingMoves, 1.0); 00089 timeForMove = time.TimeLeft(toPlay) / remainingMoves - time.Overhead(); 00090 if (useOvertime) 00091 { 00092 double firstOvertimeMove = time.OTPeriod() / time.OTNumMoves(); 00093 if (timeForMove < firstOvertimeMove) 00094 timeForMove = firstOvertimeMove; 00095 } 00096 } 00097 00098 // Don't use quite as much time for the first few moves, makes no real 00099 // difference in the quality of the moves. 00100 if (m_fastOpenMoves > 0 && movesPlayed <= m_fastOpenMoves) 00101 timeForMove *= m_fastOpenFactor; 00102 00103 timeForMove = max(timeForMove, m_minTime); 00104 00105 if (! quiet) 00106 { 00107 SgDebug() << "SgDefaultTimeControl: timeLeft=" << timeLeft; 00108 if (useOvertime) 00109 SgDebug() << '/' << time.MovesLeft(toPlay); 00110 SgDebug() << " remaining=" << remainingMoves << " timeMove=" 00111 << timeForMove << '\n'; 00112 } 00113 00114 return timeForMove; 00115 } 00116 00117 //---------------------------------------------------------------------------- 00118 00119 SgObjectWithDefaultTimeControl::~SgObjectWithDefaultTimeControl() 00120 { 00121 } 00122 00123 //----------------------------------------------------------------------------