chess-puzzles

chess puzzle book generator
git clone git://git.codemadness.org/chess-puzzles
Log | Files | Refs | README | LICENSE

commit 35cfce88175a31ca9b1db67e70575f66182d8ab2
parent cb828aa3fa341d3af5e9338132497cf49671369f
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date:   Thu, 21 Dec 2023 22:19:16 +0100

fen.c: improve castling for chess960

In chess960 you can castle right next to the king also.

This is handled in the code by "taking a piece", although this is of course
your own piece.

Note that this doesn't reset the halfmove counter.

Diffstat:
Mfen.c | 86+++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
1 file changed, 58 insertions(+), 28 deletions(-)

diff --git a/fen.c b/fen.c @@ -39,6 +39,20 @@ isvalidsquare(int x, int y) } int +iswhitepiece(int piece) +{ + return piece == 'K' || piece == 'Q' || piece == 'R' || + piece == 'B' || piece == 'N' || piece == 'P'; +} + +int +isblackpiece(int piece) +{ + return piece == 'k' || piece == 'q' || piece == 'r' || + piece == 'b' || piece == 'n' || piece == 'p'; +} + +int isvalidpiece(int c) { static char pieces[] = "PNBRQKpnbrqk"; @@ -535,33 +549,40 @@ parsemoves(const char *moves) squaretoxy(square, &x, &y); piece = getpiece(x, y); - place(0, x, y); /* clear square */ - - /* place piece at new location */ + /* target location */ square[0] = *s; square[1] = *(s + 1); squaretoxy(square, &x2, &y2); + + /* place piece at new location */ + place(0, x, y); /* clear previous square */ + /* take piece (can be your own) */ takepiece = getpiece(x2, y2); - place(piece, x2, y2); + s += 2; /* if pawn move or taken a piece increase halfmove counter */ - if (piece == 'p' || piece == 'P' || takepiece != 0) + if (piece == 'p' || piece == 'P' || + (side_to_move == 'w' && isblackpiece(takepiece)) || + (side_to_move == 'b' && iswhitepiece(takepiece))) halfmove = 0; else halfmove++; /* castling */ if (piece == 'K' && y == 7 && y2 == 7) { - /* white: kingside castling: "e1g1" */ - if (x2 >= x + 2) { /* moved more than 1 square */ - place('R', x2 - 1, y2); - x2 = 7; - y2 = 7; - place(0, x2, y2); /* clear rook square */ - } else if (x2 <= x - 2) { /* moved more than 1 square */ - /* white: queenside castling: "e1c1" */ - for (i = x2 - 1; i > 0; i--) { + /* white: kingside castling */ + if (x2 > x + 1 || takepiece == 'R') { + for (i = x2; i < 8; i++) { + if (getpiece(i, y2) == 'R') { + place(0, i, y2); /* clear rook square */ + place('R', x2 - 1, y2); /* next to king */ + break; + } + } + } else if (x2 < x - 1 || takepiece == 'R') { + /* white: queenside castling */ + for (i = x2; i >= 0; i--) { if (getpiece(i, y2) == 'R') { place('R', x2 + 1, y2); /* next to king */ place(0, i, y2); /* clear rook square */ @@ -570,18 +591,24 @@ parsemoves(const char *moves) } } } else if (piece == 'k' && y == 0 && y2 == 0) { - /* black: kingside castling: "e8g8" */ - if (x2 == 6) { - place('r', x2 - 1, y2); - x2 = 7; - y2 = 0; - place(0, x2, y2); /* clear rook square */ - } else if (x2 == 2) { - /* black: queenside castling: "e8c8" */ - place('r', x2 + 1, y2); - x2 = 0; - y2 = 0; - place(0, x2, y2); /* clear rook square */ + /* black: kingside castling */ + if (x2 > x + 1 || takepiece == 'r') { + for (i = x2; i < 8; i++) { + if (getpiece(i, y2) == 'r') { + place(0, i, y2); /* clear rook square */ + place('r', x2 - 1, y2); /* next to king */ + break; + } + } + } else if (x2 < x - 1 || takepiece == 'R') { + /* black: queenside castling */ + for (i = x2; i >= 0; i--) { + if (getpiece(i, y2) == 'r') { + place('r', x2 + 1, y2); /* next to king */ + place(0, i, y2); /* clear rook square */ + break; + } + } } } @@ -591,7 +618,7 @@ parsemoves(const char *moves) } else if (piece == 'k') { black_can_castle[0] = black_can_castle[1] = 0; } else if (piece == 'R' && y == 7) { - for (i = 0; i < 7; i++) { + for (i = 0; i < 8; i++) { if (getpiece(i, y) == 'K') { if (i < x) white_can_castle[0] = 0; @@ -601,7 +628,7 @@ parsemoves(const char *moves) } } } else if (piece == 'r' && y == 0) { - for (i = 0; i < 7; i++) { + for (i = 0; i < 8; i++) { if (getpiece(i, y) == 'k') { if (i > x) black_can_castle[1] = 0; @@ -634,6 +661,9 @@ parsemoves(const char *moves) } } + /* place piece */ + place(piece, x2, y2); + /* possible promotion: queen, knight, bishop */ if (*s == 'q' || *s == 'n' || *s == 'b') { if (side_to_move == 'w')