src/chess/rules.c

changeset 33
866025982aa9
parent 29
c6a1ad6cf749
child 36
ebe0c961e9a6
--- a/src/chess/rules.c	Wed Apr 09 09:34:07 2014 +0200
+++ b/src/chess/rules.c	Wed Apr 09 11:12:04 2014 +0200
@@ -47,10 +47,27 @@
     elem->next = NULL;
     elem->move = *move;
     
+    clock_gettime(CLOCK_REALTIME, &(elem->move.timestamp));
+    
     if (gamestate->lastmove) {
+        struct timespec *lasttstamp = &(gamestate->lastmove->move.timestamp);
+        time_t sec = elem->move.timestamp.tv_sec - lasttstamp->tv_sec;
+        long int nanos;
+        if (elem->move.timestamp.tv_nsec < lasttstamp->tv_nsec) {
+            nanos = 1e9L-(lasttstamp->tv_nsec - elem->move.timestamp.tv_nsec);
+            sec--;
+        } else {
+            nanos = elem->move.timestamp.tv_nsec - lasttstamp->tv_nsec;
+        }
+        
+        elem->move.movetime.tv_sec = sec;
+        elem->move.movetime.tv_nsec = nanos;
+        
         gamestate->lastmove->next = elem;
         gamestate->lastmove = elem;
     } else {
+        elem->move.movetime.tv_nsec = 0;
+        elem->move.movetime.tv_sec = 0;
         gamestate->movelist = gamestate->lastmove = elem;
     }
 }
@@ -524,3 +541,59 @@
         return 0;
     }
 }
+
+uint16_t remaining_movetime(GameInfo *gameinfo, GameState *gamestate,
+        uint8_t color) {
+    if (!gameinfo->timecontrol) {
+        return 0;
+    }
+    
+    if (gamestate->movelist) {
+        uint16_t time = gameinfo->time;
+        long int nanos = 0;
+        
+        MoveList *movelist = color == WHITE ?
+            gamestate->movelist : gamestate->movelist->next;
+        
+        while (movelist) {
+            time += gameinfo->addtime;
+            
+            struct timespec *movetime = &(movelist->move.movetime);
+            if (movetime->tv_sec >= time) {
+                return 0;
+            }
+            
+            time -= movetime->tv_sec;
+            nanos += movetime->tv_nsec;
+            
+            movelist = movelist->next ? movelist->next->next : NULL;
+        }
+        
+        time_t sec;
+        movelist = gamestate->lastmove;
+        if ((movelist->move.piece & COLOR_MASK) != color) {
+            struct timespec *lastmovetstamp = &(movelist->move.timestamp);
+            struct timespec currenttstamp;
+            clock_gettime(CLOCK_REALTIME, &currenttstamp);
+            nanos += currenttstamp.tv_nsec - lastmovetstamp->tv_nsec;
+            sec = currenttstamp.tv_sec - lastmovetstamp->tv_sec;
+            if (sec >= time) {
+                return 0;
+            }
+            
+            time -= sec;
+        }
+        
+        sec = nanos / 1e9L;
+        
+        if (sec >= time) {
+            return 0;
+        }
+
+        time -= sec;
+        
+        return time;
+    } else {
+        return gameinfo->time;
+    }
+}

mercurial