Introduction
Introduction Statistics Contact Development Disclaimer Help
improve and extend FEN parsing and FEN output - chess-puzzles - chess puzzle bo…
git clone git://git.codemadness.org/chess-puzzles
Log
Files
Refs
README
LICENSE
---
commit 132c4a50aae9c410bf3b505f4c61b322c388cf83
parent 29822d687c7eed634e2fd6b480ddbf84cbabf4c2
Author: Hiltjo Posthuma <[email protected]>
Date: Tue, 19 Dec 2023 20:11:09 +0100
improve and extend FEN parsing and FEN output
- improve castling availability: no castle detection yet.
- initial halfmove and move number parsing.
- parse enpassant move, but no enpassant detection yet.
- increase move number by a move by black.
work in progress
Diffstat:
M fen_to_svg.c | 116 ++++++++++++++++++++++-------…
1 file changed, 85 insertions(+), 31 deletions(-)
---
diff --git a/fen_to_svg.c b/fen_to_svg.c
@@ -2,6 +2,7 @@
#include <ctype.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#define SETFGCOLOR(r,g,b) printf("\x1b[38;2;%d;%d;%dm", r, g, b)
@@ -11,8 +12,11 @@ static char board[8][8];
static char highlight[8][8];
static int side_to_move = 'w'; /* default: white to move */
-static int white_can_castle[2] = { 0, 0 }; /* allow king side, allow queen sid…
-static int black_can_castle[2] = { 0, 0 }; /* allow king side, allow queen sid…
+static int white_can_castle[2] = { 0, 0 }; /* allow king side, allow queen sid…
+static int black_can_castle[2] = { 0, 0 }; /* allow king side, allow queen sid…
+static int enpassantsquare[2] = { -1, -1 };
+static int movenumber = 1;
+static int halfmove = 0;
static const int showcoords = 1; /* config: show board coordinates? */
@@ -94,6 +98,27 @@ showboardfen(void)
if (skip)
putchar(skip + '0');
}
+ printf(" %c ", side_to_move);
+ if (white_can_castle[0])
+ putchar('K');
+ if (white_can_castle[1])
+ putchar('Q');
+ if (black_can_castle[0])
+ putchar('k');
+ if (black_can_castle[1])
+ putchar('q');
+ if ((white_can_castle[0] + white_can_castle[1] +
+ black_can_castle[0] + black_can_castle[1]) == 0)
+ putchar('-'); /* no castling for either side */
+ putchar(' ');
+
+ if (enpassantsquare[0] != -1 && enpassantsquare[1] != -1) {
+ putchar('a' + enpassantsquare[0]);
+ putchar('8' - enpassantsquare[1]);
+ } else {
+ putchar('-');
+ }
+ printf(" %d %d", halfmove, movenumber);
/* ? TODO: detect en passant, invalid castling etc? */
}
@@ -333,7 +358,7 @@ ascii_showboard(void)
printf("\n\n");
for (y = 0; y < 8; y++) {
- printf("+---+---+---+---+---+---+---+---+\n");
+ fputs("+---+---+---+---+---+---+---+---+\n", stdout);
for (x = 0; x < 8; x++) {
if (x == 0)
putchar('|');
@@ -343,8 +368,7 @@ ascii_showboard(void)
ascii_showpiece(piece);
else
fputs(" ", stdout);
- fputs(" ", stdout);
- putchar('|');
+ fputs(" |", stdout);
}
if (showcoords) {
putchar(' ');
@@ -352,35 +376,20 @@ ascii_showboard(void)
}
putchar('\n');
}
- printf("+---+---+---+---+---+---+---+---+\n");
+ fputs("+---+---+---+---+---+---+---+---+\n", stdout);
if (showcoords)
printf(" a | b | c | d | e | f | g | h |\n");
fputs("\n", stdout);
-
-#if 0
- if (side_to_move == 'w') {
- fputs("White to move\n", stdout);
- } else if (side_to_move == 'b')
- fputs("Black to move\n", stdout);
-
- if (white_can_castle[0])
- fputs("White can castle king side\n", stdout);
- if (white_can_castle[1])
- fputs("White can castle queen side\n", stdout);
- if (black_can_castle[0])
- fputs("Black can castle king side\n", stdout);
- if (black_can_castle[1])
- fputs("Black can castle queen side\n", stdout);
-#endif
}
int
main(int argc, char *argv[])
{
const char *progname, *fen, *moves, *s;
- int x, y, x2, y2, field, piece;
+ int x, y, x2, y2, field, piece, takepiece;
char square[3];
+ long l;
if (argc != 3) {
fprintf(stderr, "usage: %s <FEN> <moves>\n", argv[0]);
@@ -396,14 +405,6 @@ main(int argc, char *argv[])
/* initial board state, FEN format */
x = y = field = 0;
for (s = fen; *s; s++) {
- /* next field, fields are: piece placement data, active color,
- Castling availability, En passant target square,
- Halfmove clock, Fullmove number */
- if (*s == ' ') {
- field++;
- continue;
- }
-
switch (field) {
case 0: /* piece placement data */
/* skip square */
@@ -442,9 +443,48 @@ main(int argc, char *argv[])
}
break;
case 3: /* TODO: en-passant square, rest of the fields */
+ if (*s >= 'a' && *s <= 'h' &&
+ *(s + 1) >= '1' && *(s + 1) >= '6') {
+
+ square[0] = *s;
+ square[1] = *(s + 1);
+ square[2] = '\0';
+ squaretoxy(square, &x, &y);
+
+ enpassantsquare[0] = x;
+ enpassantsquare[1] = y;
+ }
+ break;
+ case 4: /* halfmove */
+ if (!(*s >= '0' && *s <= '9'))
+ continue;
+
+ l = strtol(s, NULL, 10);
+ if (l >= 0 && l < 32767) {
+ halfmove = l;
+ s += strspn(s, "0123456789");
+ }
+ break;
+ case 5: /* move number */
+ if (!(*s >= '0' && *s <= '9'))
+ continue;
+
+ l = strtol(s, NULL, 10);
+ if (l >= 0 && l < 32767) {
+ movenumber = l;
+ s += strspn(s, "0123456789");
+ }
break;
}
/* TODO: parse which side to move, en-passant, etc */
+
+ /* next field, fields are: piece placement data, active color,
+ Castling availability, En passant target square,
+ Halfmove clock, Fullmove number */
+ if (*s == ' ') {
+ field++;
+ continue;
+ }
}
/* process moves */
@@ -470,9 +510,17 @@ main(int argc, char *argv[])
square[0] = *s;
square[1] = *(s + 1);
squaretoxy(square, &x2, &y2);
+ takepiece = getpiece(x, y);
place(piece, x2, y2);
s += 2;
+ /* if pawn move or taken a piece increase halfmove cou…
+ /* TODO: taking enpassant should reset halfmove too */
+ if (piece == 'p' || piece == 'P' || takepiece != 0)
+ halfmove = 0;
+ else
+ halfmove++;
+
/* castling */
if (piece == 'K' && y == 7 && y2 == 7 && x == 4) {
/* white: kingside castling: "e1g1" */
@@ -514,8 +562,14 @@ main(int argc, char *argv[])
s++;
}
+ /* a move by black increases the move number */
+ if (side_to_move == 'b')
+ movenumber++;
+
/* switch which side it is to move */
side_to_move = side_to_move == 'b' ? 'w' : 'b';
+
+ /* TODO: reset enpassant square if applicable */
}
}
/* highlight last move */
You are viewing proxied material from codemadness.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.