ask for player names during PGN export

Tue, 26 May 2026 15:21:42 +0200

author
Mike Becker <universe@uap-core.de>
date
Tue, 26 May 2026 15:21:42 +0200
changeset 127
7258a46bf5ae
parent 126
d58b2abdd330
child 128
ce38ee9bc3af

ask for player names during PGN export

resolves #840

src/chess/game-info.h file | annotate | diff | comparison | revisions
src/chess/pgn.c file | annotate | diff | comparison | revisions
src/chess/pgn.h file | annotate | diff | comparison | revisions
src/game.c file | annotate | diff | comparison | revisions
--- a/src/chess/game-info.h	Fri May 22 18:34:02 2026 +0200
+++ b/src/chess/game-info.h	Tue May 26 15:21:42 2026 +0200
@@ -88,9 +88,16 @@
     uint16_t addtime;
 } GameInfo;
 
+/** The buffer length for player names in GameInfo structures. */
+#define PLAYER_NAME_BUFLEN 32
+
 typedef struct {
     Board board;
     Move* moves;
+    /** optional name of the white player */
+    char wname[PLAYER_NAME_BUFLEN];
+    /** optional name of the black player */
+    char bname[PLAYER_NAME_BUFLEN];
     /** capacity of the move array */
     unsigned movecapacity;
     /** number of (half-)moves (counting BOTH colors) */
--- a/src/chess/pgn.c	Fri May 22 18:34:02 2026 +0200
+++ b/src/chess/pgn.c	Tue May 26 15:21:42 2026 +0200
@@ -250,6 +250,11 @@
     return date;
 }
 
+const char *pgn_player_name(GameState *gamestate, uint8_t color) {
+    const char *name = color == WHITE ? gamestate->wname : gamestate->bname;
+    return name[0] != '\0' ? name : "Anonymous";
+}
+
 void write_pgn(FILE* stream, GameState *gamestate, GameInfo *gameinfo,
         bool export_comments) {
     /* STR tag pairs */
@@ -257,9 +262,8 @@
     fprintf(stream, "[Site \"%s\"]\n", "Somewhere on Earth");
     fprintf(stream, "[Date \"%s\"]\n", pgn_date(gamestate));
     fprintf(stream, "[Round \"%s\"]\n", "-");
-    // TODO: maybe allow players to enter their names before game starts
-    fprintf(stream, "[White \"%s\"]\n", "Anonymous");
-    fprintf(stream, "[Black \"%s\"]\n", "Anonymous");
+    fprintf(stream, "[White \"%s\"]\n", pgn_player_name(gamestate, WHITE));
+    fprintf(stream, "[Black \"%s\"]\n", pgn_player_name(gamestate, BLACK));
 
     char *result;
     if (gamestate->stalemate || gamestate->remis) {
--- a/src/chess/pgn.h	Fri May 22 18:34:02 2026 +0200
+++ b/src/chess/pgn.h	Tue May 26 15:21:42 2026 +0200
@@ -43,6 +43,8 @@
         bool export_comments);
 void compute_fen(char *str, GameState *gamestate);
 
+const char *pgn_player_name(GameState *gamestate, uint8_t color);
+
 const char* pgn_error_str(int code);
 
 #ifdef	__cplusplus
--- a/src/game.c	Fri May 22 18:34:02 2026 +0200
+++ b/src/game.c	Tue May 26 15:21:42 2026 +0200
@@ -180,13 +180,31 @@
 }
 
 static void save_pgn(GameState *gamestate, GameInfo *gameinfo) {
+    int y = getcury(stdscr);
+
+    /* ask for player names */
+    {
+        char pname[PLAYER_NAME_BUFLEN];
+        printw("\rWhite's name (%s): ", pgn_player_name(gamestate, WHITE));
+        clrtoeol();
+        if (getnstr(pname, PLAYER_NAME_BUFLEN) == OK && pname[0] != '\0') {
+            strncpy(gamestate->wname, pname, PLAYER_NAME_BUFLEN);
+        }
+        move(y, 0);
+        printw("\rBlack's name (%s): ", pgn_player_name(gamestate, BLACK));
+        clrtoeol();
+        if (getnstr(pname, PLAYER_NAME_BUFLEN) == OK && pname[0] != '\0') {
+            strncpy(gamestate->bname, pname, PLAYER_NAME_BUFLEN);
+        }
+        move(y, 0);
+    }
+
     bool export_comments = prompt_yesno("Export with comments");
 
     printw("\rFilename: ");
     clrtoeol();
     
     char filename[64];
-    int y = getcury(stdscr);
     if (getnstr(filename, 64) == OK && filename[0] != '\0') {
         move(y, 0);
         FILE *file = fopen(filename, "w");

mercurial