00001 /************************************************************************** 00002 00003 Chess Clock 00004 00005 Copyright (c) Arto Hyvättinen 2010 00006 00007 This file is part of Chess Clock software. 00008 00009 Chess Clock is free software: you can redistribute it and/or modify 00010 it under the terms of the GNU General Public License as published by 00011 the Free Software Foundation, either version 3 of the License, or 00012 (at your option) any later version. 00013 00014 Chess Clock is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 GNU General Public License for more details. 00018 00019 00020 **************************************************************************/ 00021 00022 #include "chessclock.h" 00023 00024 #include "turninformation.h" 00025 00026 const int ChessClock::UPDATEINTERVAL; 00027 00028 ChessClock::ChessClock(bool white, QWidget *parent) : 00029 QWidget(parent) 00030 { 00031 isWhite_ = white; 00032 loser_ = false; 00033 turn_ = 0; 00034 timePlayedBeforeTurn_ = 0; 00035 status_ = NotRunning; 00036 another_ = 0; 00037 currentTurn_ = 0; 00038 00039 // Set clock timer calculating played time 00040 clockTime_.start(); 00041 00042 // Set updating timer 00043 updateTimer_.setInterval( UPDATEINTERVAL ); 00044 connect( &updateTimer_, SIGNAL(timeout()),this,SLOT(updateClock())); 00045 } 00046 00047 void ChessClock::startTurn() 00048 { 00049 turn_++; 00050 00051 // Turn information for this new turn 00052 currentTurn_ = new TurnInformation(turn_, isWhite_); 00053 clockTime_.restart(); 00054 updateTimer_.start(); 00055 status_=Running; 00056 00057 // Repaint clock 00058 updateClock(); 00059 } 00060 00061 void ChessClock::pauseTurn() 00062 { 00063 updateTimer_.stop(); 00064 // Update turn time 00065 currentTurn_->addTime( clockTime_.restart() ); 00066 status_ = Paused; 00067 updateClock(); 00068 } 00069 00070 void ChessClock::continueTurn() 00071 { 00072 // Continue paused game 00073 // Add pause duration to information object 00074 currentTurn_->addPause( clockTime_.restart() ); 00075 status_ = Running; 00076 updateTimer_.start(); 00077 updateClock(); 00078 } 00079 00080 00081 TurnInformation* ChessClock::endTurn() 00082 { 00083 updateTimer_.stop(); 00084 status_ = NotRunning; 00085 00086 updateClock(); 00087 // Count time played 00088 timePlayedBeforeTurn_ = getTimePlayed(); 00089 00090 // Count time available 00091 // This update current turn 00092 timeAvailableBeforeTurn_ = getTimeAvailable(); 00093 00094 00095 // Close and return turn information 00096 currentTurn_->turnReady(timeAvailableBeforeTurn_ ); 00097 TurnInformation* information = currentTurn_; 00098 currentTurn_ = 0; 00099 00100 emit turnEnded(); 00101 return information; 00102 } 00103 00104 void ChessClock::setAnother(ChessClock *another) 00105 { 00106 another_ = another; 00107 } 00108 00109 int ChessClock::getTimeAvailable() 00110 { 00111 // Most simple - will be overwritten in more complex time controls: 00112 // subtract duration time! 00113 if( currentTurn_) 00114 { 00115 // Update turn time 00116 return timeAvailableBeforeTurn_-currentTurnPlayed(); 00117 } 00118 else 00119 return timeAvailableBeforeTurn_; 00120 } 00121 00122 00123 int ChessClock::getTimePlayed() 00124 { 00125 return timePlayedBeforeTurn_ + currentTurnPlayed(); 00126 } 00127 00128 00129 void ChessClock::setTimeAvailable(int msecs) 00130 { 00131 timeAvailableBeforeTurn_ = msecs; 00132 } 00133 00134 00135 void ChessClock::addTime(int msecs) 00136 { 00137 timeAvailableBeforeTurn_ += msecs; 00138 } 00139 00140 int ChessClock::currentTurnPlayed() 00141 { 00142 if( currentTurn_ ) 00143 { 00144 // Update current time 00145 if( status_ == Running ) 00146 currentTurn_->addTime( clockTime_.restart()); 00147 00148 // Return current time 00149 return currentTurn_->getDuration(); 00150 } 00151 else 00152 // No current turn! 00153 return 0; 00154 } 00155 00156 void ChessClock::updateClock() 00157 { 00158 // Check loser 00159 if( another_ && !another_->isLoser()) 00160 { 00161 if( getTimeAvailable() < 0 && !loser_) 00162 { 00163 loser_ = true; 00164 emit timeOutLoser(); 00165 } 00166 00167 } 00168 repaintClock(); 00169 00170 } 00171