src/chess/rules.c

changeset 130
3fc6b1d6cbe9
parent 129
189c7c77aaab
--- a/src/chess/rules.c	Thu May 28 12:15:26 2026 +0200
+++ b/src/chess/rules.c	Thu May 28 13:58:24 2026 +0200
@@ -170,7 +170,8 @@
     gettimeofday(&curtimestamp, NULL);
     move->timestamp.tv_sec = curtimestamp.tv_sec;
     move->timestamp.tv_usec = (int32_t) curtimestamp.tv_usec;
-
+    move->movetime.tv_usec = 0;
+    move->movetime.tv_sec = 0;
     if (gamestate->movecount > 1) {
         struct movetimeval lasttstamp = last_move(gamestate).timestamp;
         uint64_t sec = curtimestamp.tv_sec - lasttstamp.tv_sec;
@@ -181,13 +182,16 @@
         } else {
             micros = curtimestamp.tv_usec - lasttstamp.tv_usec;
         }
+        
+        while (micros >= 1000000) {
+            micros -= 1000000;
+            sec++;
+        }
 
-        move->movetime.tv_sec = sec;
-        move->movetime.tv_usec = (int32_t) micros;
-    } else {
-        /* no move time for the first move of both white and black */
-        move->movetime.tv_usec = 0;
-        move->movetime.tv_sec = 0;
+        if (sec >= gamestate->info.delay) {
+            move->movetime.tv_sec = sec;
+            move->movetime.tv_usec = (int32_t) micros;
+        }
     }
 }
 
@@ -316,6 +320,7 @@
 void gamestate_at_move(GameState *gamestate,
         unsigned move_number, GameState *replay) {
     gamestate_init(replay);
+    memcpy(&replay->info, &gamestate->info, sizeof(GameInfo));
     replay->review = true;
     if (move_number > gamestate->movecount) {
         move_number = gamestate->movecount;
@@ -841,30 +846,28 @@
     }
 }
 
-uint16_t remaining_movetime(GameInfo *gameinfo, GameState *gamestate,
-        uint8_t color) {
+uint16_t remaining_movetime(GameState *gamestate, uint8_t color) {
     unsigned move_number = gamestate->movecount;
     if (color == BLACK) {
         move_number |= 1;
     } else {
         move_number = (move_number + 1) & ~1;
     }
-    return remaining_movetime2(gameinfo, gamestate, move_number);
+    return remaining_movetime2(gamestate, move_number);
 }
 
-uint16_t remaining_movetime2(GameInfo *gameinfo, GameState *gamestate,
-        unsigned move_number) {
-    if (!gameinfo->timecontrol) {
+uint16_t remaining_movetime2(GameState *gamestate, unsigned move_number) {
+    if (!gamestate->info.timecontrol) {
         return 0;
     }
 
-    unsigned total_time = gameinfo->time;
+    unsigned total_time = gamestate->info.time;
     unsigned used_time = 0;
     suseconds_t micros = 0;
 
     /* when this is a 0+X game, the clock starts with the increment */
-    if (gameinfo->time == 0) {
-        total_time += gameinfo->addtime;
+    if (gamestate->info.time == 0) {
+        total_time += gamestate->info.addtime;
     }
 
     /* go through all already played moves */
@@ -875,7 +878,13 @@
         used_time += gamestate->moves[i].movetime.tv_sec;
         micros += gamestate->moves[i].movetime.tv_usec;
         /* add increments starting with move 2 */
-        if (i > 1) total_time += gameinfo->addtime;
+        if (i > 1) total_time += gamestate->info.addtime;
+    }
+
+    /* apply microseconds */
+    while (micros >= 1000000) {
+        micros -= 1000000;
+        used_time++;
     }
 
     /* when the player is currently playing, count down the clock */
@@ -885,13 +894,21 @@
             gamestate->moves[move_number - 1].timestamp;
         struct timeval currenttstamp;
         gettimeofday(&currenttstamp, NULL);
-        used_time += currenttstamp.tv_sec - lastmovetstamp.tv_sec;
-        micros += currenttstamp.tv_usec - lastmovetstamp.tv_usec;
+
+        /* calculate current move time */
+        unsigned cmsec = currenttstamp.tv_sec - lastmovetstamp.tv_sec;
+        suseconds_t cmusec = currenttstamp.tv_usec - lastmovetstamp.tv_usec;
+
+        /* add microseconds carried over from last move and apply both */
+        cmusec += micros;
+        cmsec += cmusec / 1000000;
+
+        /* add the time and respect a possible dealy */
+        if (cmsec >= gamestate->info.delay) {
+            used_time += cmsec - gamestate->info.delay;
+        }
     }
 
-    /* apply the microseconds */
-    used_time += micros / 1000000;
-
     return used_time >= total_time ? 0 : total_time - used_time;
 }
 

mercurial