src/chess/rules.c

changeset 98
9cb41383540f
parent 87
d4d67105d4e1
--- a/src/chess/rules.c	Sat Apr 04 12:35:59 2026 +0200
+++ b/src/chess/rules.c	Sat Apr 04 13:25:47 2026 +0200
@@ -41,11 +41,16 @@
 
 static GameState gamestate_copy_sim(GameState *gamestate) {
     GameState simulation = *gamestate;
-    simulation.movecount = 0; /* simulations do not count moves */
-    if (simulation.lastmove) {
-        MoveList *lastmovecopy = malloc(sizeof(MoveList));
-        *lastmovecopy = *(simulation.lastmove);
-        simulation.movelist = simulation.lastmove = lastmovecopy;
+
+    // create a new move list for the simulation
+    simulation.movecapacity = 4;
+    simulation.movecount = 0;
+    simulation.moves = malloc(4 * sizeof(Move));
+
+    // copy the most recent move if a move was played
+    if (gamestate->movecount > 0) {
+        simulation.moves[0] = last_move(gamestate);
+        simulation.movecount++;
     }
 
     return simulation;
@@ -138,39 +143,39 @@
     }
 }
 
-static void addmove(GameState* gamestate, Move *move) {
-    MoveList *elem = malloc(sizeof(MoveList));
-    elem->next = NULL;
-    elem->move = *move;
-    
+static void addmove(GameState* gamestate, Move *data) {
+    if (gamestate->movecount == gamestate->movecapacity) {
+        gamestate->movecapacity += 64; /* 32 more full moves */
+        gamestate->moves = realloc(gamestate->moves,
+            gamestate->movecapacity * sizeof(Move));
+    }
+
+    Move *move = &gamestate->moves[gamestate->movecount];
+    *move = *data;
+
     struct timeval curtimestamp;
     gettimeofday(&curtimestamp, NULL);
-    elem->move.timestamp.tv_sec = curtimestamp.tv_sec;
-    elem->move.timestamp.tv_usec = curtimestamp.tv_usec;
+    move->timestamp.tv_sec = curtimestamp.tv_sec;
+    move->timestamp.tv_usec = (int32_t) curtimestamp.tv_usec;
     
-    if (gamestate->lastmove) {
-        struct movetimeval *lasttstamp = &(gamestate->lastmove->move.timestamp);
-        uint64_t sec = curtimestamp.tv_sec - lasttstamp->tv_sec;
+    if (gamestate->movecount > 0) {
+        struct movetimeval lasttstamp = last_move(gamestate).timestamp;
+        uint64_t sec = curtimestamp.tv_sec - lasttstamp.tv_sec;
         suseconds_t micros;
-        if (curtimestamp.tv_usec < lasttstamp->tv_usec) {
-            micros = 1e6L-(lasttstamp->tv_usec - curtimestamp.tv_usec);
+        if (curtimestamp.tv_usec < lasttstamp.tv_usec) {
+            micros = 1000000-(lasttstamp.tv_usec - curtimestamp.tv_usec);
             sec--;
         } else {
-            micros = curtimestamp.tv_usec - lasttstamp->tv_usec;
+            micros = curtimestamp.tv_usec - lasttstamp.tv_usec;
         }
         
-        elem->move.movetime.tv_sec = sec;
-        elem->move.movetime.tv_usec = micros;
-        
-        gamestate->lastmove->next = elem;
-        gamestate->lastmove = elem;
-        gamestate->movecount++;
+        move->movetime.tv_sec = sec;
+        move->movetime.tv_usec = (int32_t) micros;
     } else {
-        elem->move.movetime.tv_usec = 0;
-        elem->move.movetime.tv_sec = 0;
-        gamestate->movelist = gamestate->lastmove = elem;
-        gamestate->movecount = 1;
+        move->movetime.tv_usec = 0;
+        move->movetime.tv_sec = 0;
     }
+    gamestate->movecount++;
 }
 
 char getpiecechr(uint8_t piece) {
@@ -367,7 +372,7 @@
             return KING_MOVES_INTO_CHECK;
         } else {
             /* last move is always not null in this case */
-            return gamestate->lastmove->move.check ?
+            return last_move(gamestate).check ?
                 KING_IN_CHECK : PIECE_PINNED;
         }
     }
@@ -569,7 +574,7 @@
 
     uint8_t color = move->piece & COLOR_MASK;
     uint8_t piece = move->piece & PIECE_MASK;
-    bool incheck = gamestate->lastmove?gamestate->lastmove->move.check:false;
+    bool incheck = gamestate->movecount > 0 ? last_move(gamestate).check:false;
     
     Move threats[16], *threat = NULL;
     uint8_t threatcount;
@@ -768,35 +773,30 @@
         return 0;
     }
     
-    if (gamestate->movelist) {
+    if (gamestate->movecount > 0) {
         uint16_t time = gameinfo->time;
         suseconds_t micros = 0;
-        
-        MoveList *movelist = color == WHITE ?
-            gamestate->movelist : gamestate->movelist->next;
-        
-        while (movelist) {
+
+        for (unsigned i = color == WHITE ? 0 : 1
+                ; i < gamestate->movecount ; i += 2) {
             time += gameinfo->addtime;
             
-            struct movetimeval *movetime = &(movelist->move.movetime);
-            if (movetime->tv_sec >= time) {
+            if (gamestate->moves[i].movetime.tv_sec >= time) {
                 return 0;
             }
             
-            time -= movetime->tv_sec;
-            micros += movetime->tv_usec;
-            
-            movelist = movelist->next ? movelist->next->next : NULL;
+            time -= gamestate->moves[i].movetime.tv_sec;
+            micros += gamestate->moves[i].movetime.tv_usec;
         }
         
         time_t sec;
-        movelist = gamestate->lastmove;
-        if ((movelist->move.piece & COLOR_MASK) != color) {
-            struct movetimeval *lastmovetstamp = &(movelist->move.timestamp);
+        Move *lastmove = &last_move(gamestate);
+        if ((lastmove->piece & COLOR_MASK) != color) {
+            struct movetimeval lastmovetstamp = lastmove->timestamp;
             struct timeval currenttstamp;
             gettimeofday(&currenttstamp, NULL);
-            micros += currenttstamp.tv_usec - lastmovetstamp->tv_usec;
-            sec = currenttstamp.tv_sec - lastmovetstamp->tv_sec;
+            micros += currenttstamp.tv_usec - lastmovetstamp.tv_usec;
+            sec = currenttstamp.tv_sec - lastmovetstamp.tv_sec;
             if (sec >= time) {
                 return 0;
             }
@@ -804,7 +804,7 @@
             time -= sec;
         }
         
-        sec = micros / 1e6L;
+        sec = micros / 1000000;
         
         if (sec >= time) {
             return 0;

mercurial