simplify FEN generation and add current_color() function to rules

Fri, 12 Jun 2026 13:34:35 +0200

author
Mike Becker <universe@uap-core.de>
date
Fri, 12 Jun 2026 13:34:35 +0200
changeset 133
c58ae152733e
parent 132
5762f2b5f87a
child 134
ce2d285d2ccb

simplify FEN generation and add current_color() function to rules

src/chess/fen.c file | annotate | diff | comparison | revisions
src/chess/fen.h file | annotate | diff | comparison | revisions
src/chess/pgn.c file | annotate | diff | comparison | revisions
src/chess/rules.c file | annotate | diff | comparison | revisions
src/chess/rules.h file | annotate | diff | comparison | revisions
src/main.c file | annotate | diff | comparison | revisions
--- a/src/chess/fen.c	Sun Jun 07 16:56:22 2026 +0200
+++ b/src/chess/fen.c	Fri Jun 12 13:34:35 2026 +0200
@@ -72,11 +72,7 @@
 }
 
 static size_t fen_color(char *str, GameState *gamestate) {
-    uint8_t color = opponent_color(gamestate->movecount > 0 ?
-        (last_move(gamestate).piece & COLOR_MASK) : BLACK);
-
-    str[0] = color == WHITE ? 'w' : 'b';
-
+    str[0] = current_color(gamestate) == WHITE ? 'w' : 'b';
     return 1;
 }
 
@@ -121,7 +117,7 @@
 
 static size_t fen_enpassant(char *str, GameState *gamestate) {
 
-    str[0] = '-'; str[1] = '\0';
+    str[0] = '-';
 
     for (int file = 0 ; file < 8 ; file++) {
         if (gamestate->board[3][file] & ENPASSANT_THREAT) {
@@ -155,17 +151,22 @@
     return sprintf(str, "%u", gamestate->movecount);
 }
 
+static size_t fen_space(char *str) {
+    *str = ' ';
+    return 1;
+}
+
 void fen_compute(char *str, GameState *gamestate) {
     str += fen_pieces(str, gamestate);
-    *str = ' '; str++;
+    str += fen_space(str);
     str += fen_color(str, gamestate);
-    *str = ' '; str++;
+    str += fen_space(str);
     str += fen_castling(str, gamestate);
-    *str = ' '; str++;
+    str += fen_space(str);
     str += fen_enpassant(str, gamestate);
-    *str = ' '; str++;
+    str += fen_space(str);
     str += fen_halfmove(str, gamestate);
-    *str = ' '; str++;
+    str += fen_space(str);
     str += fen_movenr(str, gamestate);
-    str[0] = '\0';
+    *str = '\0';
 }
--- a/src/chess/fen.h	Sun Jun 07 16:56:22 2026 +0200
+++ b/src/chess/fen.h	Fri Jun 12 13:34:35 2026 +0200
@@ -37,6 +37,13 @@
 #endif
 
 /**
+ * A generous upper bound on the length of a FEN string.
+ *
+ * This includes a terminating null character.
+ */
+#define FEN_MAX_LENGTH 96
+
+/**
  * Computes the FEN representation of the current game state.
  *
  * @param str a buffer large enough to hold the FEN string
--- a/src/chess/pgn.c	Sun Jun 07 16:56:22 2026 +0200
+++ b/src/chess/pgn.c	Fri Jun 12 13:34:35 2026 +0200
@@ -272,9 +272,8 @@
     } else if (gamestate->bresign) {
         result = "1-0";
     } else if (gamestate->checkmate) {
-        if (gamestate->movecount > 0) {
-            result = (last_move(gamestate).piece & COLOR_MASK) == WHITE ?
-                "1-0" : "0-1";
+        if (current_color(gamestate) == BLACK) {
+            result = "1-0";
         } else {
             result = "0-1";
         }
--- a/src/chess/rules.c	Sun Jun 07 16:56:22 2026 +0200
+++ b/src/chess/rules.c	Fri Jun 12 13:34:35 2026 +0200
@@ -78,6 +78,10 @@
     return simulation;
 }
 
+uint8_t current_color(GameState *gamestate) {
+    return (gamestate->movecount % 2 == 0) ? WHITE : BLACK;
+}
+
 /* MUST be called BETWEEN validating AND applying a move to work correctly */
 static void format_move(GameState *gamestate, Move *move) {
     char *string = &(move->string[0]);
--- a/src/chess/rules.h	Sun Jun 07 16:56:22 2026 +0200
+++ b/src/chess/rules.h	Fri Jun 12 13:34:35 2026 +0200
@@ -209,6 +209,14 @@
 char* getpieceunicode(uint8_t piece);
 
 /**
+ * Returns the color of the player who is next to move.
+ *
+ * @param gamestate the current game state
+ * @return the color of the player who is next to move
+ */
+uint8_t current_color(GameState *gamestate);
+
+/**
  * Checks, if a specified field is covered by a piece of a certain color.
  * 
  * The out-parameters may both be NULL, but if any of them is set, the other
--- a/src/main.c	Sun Jun 07 16:56:22 2026 +0200
+++ b/src/main.c	Fri Jun 12 13:34:35 2026 +0200
@@ -279,7 +279,7 @@
 }
 
 static void draw_board(GameState *gamestate, uint8_t perspective) {
-    char fen[90];
+    char fen[FEN_MAX_LENGTH];
     fen_compute(fen, gamestate);
     mvaddstr(0, 0, fen);
 
@@ -906,7 +906,7 @@
                 addstr("Game has ended. Use -S to analyze it.\n");
                 return;
             }
-            curcol = opponent_color(last_move(&gamestate).piece&COLOR_MASK);
+            curcol = current_color(&gamestate);
         } else {
             printw("Can't read PGN file (%s)\n", strerror(errno));
             return;
@@ -934,8 +934,7 @@
         mycolor = opponent_color(mycolor);
     }
 
-    bool myturn = (gamestate->movecount > 0 ?
-        (last_move(gamestate).piece & COLOR_MASK) : BLACK) != mycolor;
+    bool myturn = current_color(gamestate) == mycolor;
 
     bool running;
     do {

mercurial