--- a/src/chess/rules.h Fri Sep 04 13:49:48 2026 +0200 +++ b/src/chess/rules.h Sat Sep 05 12:36:04 2026 +0200 @@ -166,7 +166,7 @@ /** number of (half-)moves (counting BOTH colors) */ unsigned int movecount; /** number of half-moves that have been played before reaching fen_start */ - unsigned int move_start; // TODO: use this in board view and PGN export + unsigned int move_start; /** number of half-moves w/o capture or pawn move played before fen_start */ unsigned int fifty_cntr_start; /** a premove that shall be evaluated next time it's our turn */ @@ -210,6 +210,28 @@ static inline char filechr(File file) {return (char)file+'a';} +/** + * Returns the current move number. + * + * @param gamestate the current game state + * @return the full move number of the move that is next to play + */ +static inline unsigned move_number(const GameState *gamestate) { + return 1 + (gamestate->move_start + gamestate->movecount) / 2; +} + +/** + * Returns the current half-move number. + * + * The counter starts with one. + * + * @param gamestate the current game state + * @return the half-move number of the move that is next to play + */ +static inline unsigned move_number_half(const GameState *gamestate) { + return 1 + gamestate->move_start + gamestate->movecount; +} + static inline void enpassant_threat_add(GameState *gamestate, File file, Rank rank) { gamestate->board[rank][file] |= ENPASSANT_THREAT; @@ -241,7 +263,7 @@ } static inline Color field_color(File f, Rank r) { - return (r + f) % 2 == 0 ? BLACK : WHITE; + return ((unsigned)r + (unsigned)f) % 2 == 0 ? BLACK : WHITE; } /** @@ -294,7 +316,9 @@ * @param gamestate the current game state * @return the color of the player who is next to move */ -Color current_color(const GameState *gamestate); +static inline Color current_color(const GameState *gamestate) { + return move_number_half(gamestate) % 2 ? WHITE : BLACK; +} /** * Returns the piece at the specified position.