fen.c: code cleanup: separate parsing FEN and moves in 2 functions - chess-puzzles - chess puzzle book generator
 (HTM) git clone git://git.codemadness.org/chess-puzzles
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 2f8f9b16e1834cdd577d590efc51be17f3013585
 (DIR) parent 752c96801f72527cf5bc3faab7ad7d1d7889ddbf
 (HTM) Author: Hiltjo Posthuma <hiltjo@codemadness.org>
       Date:   Thu, 21 Dec 2023 18:27:41 +0100
       
       fen.c: code cleanup: separate parsing FEN and moves in 2 functions
       
       Diffstat:
         M TODO                                |       5 ++---
         M fen.c                               |     148 +++++++++++++++++--------------
       
       2 files changed, 85 insertions(+), 68 deletions(-)
       ---
 (DIR) diff --git a/TODO b/TODO
       @@ -1,6 +1,5 @@
       -- code cleanup:
       -  - separate parsefen() function.
       -  - separate parsemoves() function.
       +- stream_lichess.sh: lichess API: read FEN of start position, for chess 960
       +chess variant.
        
        - option for output for annotating moves in a human-like way (for screenreaders/espeak).
        https://en.wikipedia.org/wiki/Portable_Game_Notation
 (DIR) diff --git a/fen.c b/fen.c
       @@ -444,63 +444,14 @@ showboard_ascii(void)
        }
        
        void
       -usage(char *argv0)
       -{
       -        fprintf(stderr, "usage: %s [-cCfF] [-o ascii|fen|svg|tty] [FEN] [moves]\n", argv0);
       -        exit(1);
       -}
       -
       -int
       -main(int argc, char *argv[])
       +parsefen(const char *fen)
        {
       -        const char *fen, *moves, *s, *output = "svg";
       -        int x, y, x2, y2, field, piece, takepiece;
       -        int i, j;
                char square[3];
       +        const char *s;
                long l;
       +        int x, y, field;
        
       -#ifdef __OpenBSD__
       -        if (pledge("stdio", NULL) == -1)
       -                err(1, "pledge");
       -#endif
       -
       -        fen = "startpos";
       -        moves = "";
       -
       -        for (i = 1; i < argc; i++) {
       -                if (argv[i][0] != '-')
       -                        break;
       -
       -                for (j = 1; argv[i][j]; j++) {
       -                        switch (argv[i][j]) {
       -                        case 'c': showcoords = 1; break;
       -                        case 'C': showcoords = 0; break;
       -                        case 'f': flipboard = 1; break;
       -                        case 'F': flipboard = 0; break;
       -                        case 'o':
       -                                if (i + 1 >= argc)
       -                                        usage(argv[0]);
       -                                output = argv[++i];
       -                                goto next;
       -                        default:
       -                                usage(argv[0]);
       -                                break;
       -                        }
       -                }
       -next:
       -        ;
       -        }
       -        if (i < argc) {
       -                fen = argv[i];
       -                i++;
       -        }
       -        if (i < argc) {
       -                moves = argv[i];
       -                i++;
       -        }
       -
       -        if (!strcmp(fen, "startpos"))
       -                fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
       +        square[2] = '\0';
        
                /* initial board state, FEN format */
                x = y = field = 0;
       @@ -547,7 +498,6 @@ next:
                                        *(s + 1) >= '1' && *(s + 1) <= '6') {
                                        square[0] = *s;
                                        square[1] = *(s + 1);
       -                                square[2] = '\0';
                                        squaretoxy(square, &x, &y);
        
                                        enpassantsquare[0] = x;
       @@ -589,6 +539,14 @@ next:
                                continue;
                        }
                }
       +}
       +
       +void
       +parsemoves(const char *moves)
       +{
       +        char square[3];
       +        const char *s;
       +        int i, x, y, x2, y2, piece, takepiece;
        
                /* process moves */
                square[2] = '\0';
       @@ -634,10 +592,10 @@ next:
                                                place(0, x2, y2); /* clear rook square */
                                        } else if (x2 <= x - 2) { /* moved more than 1 square */
                                                /* white: queenside castling: "e1c1" */
       -                                        for (j = x2 - 1; j > 0; j--) {
       -                                                if (getpiece(j, y2) == 'R') {
       +                                        for (i = x2 - 1; i > 0; i--) {
       +                                                if (getpiece(i, y2) == 'R') {
                                                                place('R', x2 + 1, y2); /* next to king */
       -                                                        place(0, j, y2); /* clear rook square */
       +                                                        place(0, i, y2); /* clear rook square */
                                                                break;
                                                        }
                                                }
       @@ -664,21 +622,21 @@ next:
                                } else if (piece == 'k') {
                                        black_can_castle[0] = black_can_castle[1] = 0;
                                } else if (piece == 'R' && y == 7) {
       -                                for (j = 0; j < 7; j++) {
       -                                        if (getpiece(j, y) == 'K') {
       -                                                if (j < x)
       +                                for (i = 0; i < 7; i++) {
       +                                        if (getpiece(i, y) == 'K') {
       +                                                if (i < x)
                                                                white_can_castle[0] = 0;
       -                                                else if (j > x)
       +                                                else if (i > x)
                                                                white_can_castle[1] = 0;
                                                        break;
                                                }
                                        }
                                } else if (piece == 'r' && y == 0) {
       -                                for (j = 0; j < 7; j++) {
       -                                        if (getpiece(j, y) == 'k') {
       -                                                if (j > x)
       +                                for (i = 0; i < 7; i++) {
       +                                        if (getpiece(i, y) == 'k') {
       +                                                if (i > x)
                                                                black_can_castle[1] = 0;
       -                                                else if (j < x)
       +                                                else if (i < x)
                                                                black_can_castle[0] = 0;
                                                        break;
                                                }
       @@ -728,6 +686,66 @@ next:
        
                /* highlight last move */
                highlightmove(x, y, x2, y2);
       +}
       +
       +void
       +usage(char *argv0)
       +{
       +        fprintf(stderr, "usage: %s [-cCfF] [-o ascii|fen|svg|tty] [FEN] [moves]\n", argv0);
       +        exit(1);
       +}
       +
       +int
       +main(int argc, char *argv[])
       +{
       +        const char *fen, *moves, *output = "svg";
       +        int i, j;
       +
       +#ifdef __OpenBSD__
       +        if (pledge("stdio", NULL) == -1)
       +                err(1, "pledge");
       +#endif
       +
       +        fen = "startpos";
       +        moves = "";
       +
       +        for (i = 1; i < argc; i++) {
       +                if (argv[i][0] != '-')
       +                        break;
       +
       +                for (j = 1; argv[i][j]; j++) {
       +                        switch (argv[i][j]) {
       +                        case 'c': showcoords = 1; break;
       +                        case 'C': showcoords = 0; break;
       +                        case 'f': flipboard = 1; break;
       +                        case 'F': flipboard = 0; break;
       +                        case 'o':
       +                                if (i + 1 >= argc)
       +                                        usage(argv[0]);
       +                                output = argv[++i];
       +                                goto next;
       +                        default:
       +                                usage(argv[0]);
       +                                break;
       +                        }
       +                }
       +next:
       +        ;
       +        }
       +        if (i < argc) {
       +                fen = argv[i];
       +                i++;
       +        }
       +        if (i < argc) {
       +                moves = argv[i];
       +                i++;
       +        }
       +
       +        if (!strcmp(fen, "startpos"))
       +                fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
       +
       +        parsefen(fen);
       +        parsemoves(moves);
        
                if (!strcmp(output, "ascii"))
                        showboard_ascii();