diff -r f87cad9445b4 -r 9cb41383540f src/chess/rules.c --- 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(¤ttstamp, 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;