commit b9e10f90912e4d6c82e4a4738a2fcdbd77b0d6db
parent 526df2437b7f656c5f7f68f207478dd2ee15db53
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Thu, 21 Dec 2023 17:58:13 +0100
improve check for castling and castling availability
This improves compatibility with chess960.
Diffstat:
M | fen.c | | | 50 | ++++++++++++++++++++++++++++++++------------------ |
M | tests.sh | | | 33 | +++++++++++++++++++++++++++++++++ |
2 files changed, 65 insertions(+), 18 deletions(-)
diff --git a/fen.c b/fen.c
@@ -625,21 +625,24 @@ next:
halfmove++;
/* castling */
- if (piece == 'K' && y == 7 && y2 == 7 && x == 4) {
+ if (piece == 'K' && y == 7 && y2 == 7) {
/* white: kingside castling: "e1g1" */
- if (x2 == 6) {
+ 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 == 2) {
+ } else if (x2 <= x - 2) { /* moved more than 1 square */
/* white: queenside castling: "e1c1" */
- place('R', x2 + 1, y2);
- x2 = 0;
- y2 = 7;
- place(0, x2, y2);
+ for (j = x2 - 1; j > 0; j--) {
+ if (getpiece(j, y2) == 'R') {
+ place('R', x2 + 1, y2); /* next to king */
+ place(0, j, y2); /* clear rook square */
+ break;
+ }
+ }
}
- } else if (piece == 'k' && y == 0 && y2 == 0 && x == 4) {
+ } else if (piece == 'k' && y == 0 && y2 == 0) {
/* black: kingside castling: "e8g8" */
if (x2 == 6) {
place('r', x2 - 1, y2);
@@ -660,16 +663,26 @@ next:
white_can_castle[0] = white_can_castle[1] = 0;
} else if (piece == 'k') {
black_can_castle[0] = black_can_castle[1] = 0;
- } else if (piece == 'R') {
- if (x == 7 && y == 7)
- white_can_castle[0] = 0;
- else if (x == 0 && y == 7)
- white_can_castle[1] = 0;
- } else if (piece == 'r') {
- if (x == 0 && y == 0)
- black_can_castle[1] = 0;
- else if (x == 7 && y == 0)
- black_can_castle[0] = 0;
+ } else if (piece == 'R' && y == 7) {
+ for (j = 0; j < 7; j++) {
+ if (getpiece(j, y) == 'K') {
+ if (j < x)
+ white_can_castle[0] = 0;
+ else if (j > 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)
+ black_can_castle[1] = 0;
+ else if (j < x)
+ black_can_castle[0] = 0;
+ break;
+ }
+ }
}
/* taken en passant? */
@@ -712,6 +725,7 @@ next:
side_to_move = side_to_move == 'b' ? 'w' : 'b';
}
}
+
/* highlight last move */
highlightmove(x, y, x2, y2);
diff --git a/tests.sh b/tests.sh
@@ -91,3 +91,36 @@ testfen 'rnbqkbnr/ppppppp1/8/8/3P4/4P1p1/PPP2P1P/RNBQKBNR w KQkq - 0 4'\
testfen 'rnbqkbnr/pppp1pp1/4P3/7p/8/8/PPP1PPPP/RNBQKBNR b KQkq - 0 3'\
'rnbqkbnr/pppp1pp1/8/3Pp2p/8/8/PPP1PPPP/RNBQKBNR w KQkq e6 1 3'\
'd5e6'
+
+# 960 white queenside castle
+testfen 'qrn1bk1n/ppb1pprp/2p3p1/3p4/1B1P4/3NPB2/PPP2PPP/Q1KR2RN b q - 5 6'\
+ 'qrn1bk1n/ppb1pprp/2p3p1/3p4/1B1P4/3NPB2/PPP2PPP/QR3KRN w KQq - 4 6'\
+ 'f1c1'
+# 960, rook moved: remove ability for black to castle.
+testfen 'q1r1bk1n/ppb1pprp/2pn2p1/3p4/1B1P4/3NPB2/PPP2PPP/Q1KRR2N w - - 8 8'\
+ 'qr2bk1n/ppb1pprp/2pn2p1/3p4/1B1P4/3NPB2/PPP2PPP/Q1KRR2N b q - 7 7'\
+ 'b8c8'
+# 960, rook moved
+testfen 'bbnrkrnq/ppp1p1pp/8/3p1p2/3P1P2/3R4/PPP1P1PP/BBN1KRNQ b Kkq - 1 3'\
+ 'bbnrkrnq/ppp1p1pp/8/3p1p2/3P1P2/8/PPP1P1PP/BBNRKRNQ w KQkq - 0 3'\
+ 'd1d3'
+# 960, rook moved
+testfen 'bbnrkrnq/ppp1p1pp/8/3p1p2/3P1P2/5R2/PPP1P1PP/BBNRK1NQ b Qkq - 1 3'\
+ 'bbnrkrnq/ppp1p1pp/8/3p1p2/3P1P2/8/PPP1P1PP/BBNRKRNQ w KQkq - 0 3'\
+ 'f1f3'
+# 960, rook moved
+testfen 'bbn1krnq/ppp1p1pp/3r4/3p1p2/P2P1P2/8/1PP1P1PP/BBNRKRNQ w KQk - 1 4'\
+ 'bbnrkrnq/ppp1p1pp/8/3p1p2/P2P1P2/8/1PP1P1PP/BBNRKRNQ b KQkq - 0 3'\
+ 'd8d6'
+# 960, rook moved
+testfen 'bbnrk1nq/ppp1p1pp/5r2/3p1p2/P2P1P2/8/1PP1P1PP/BBNRKRNQ w KQq - 1 4'\
+ 'bbnrkrnq/ppp1p1pp/8/3p1p2/P2P1P2/8/1PP1P1PP/BBNRKRNQ b KQkq - 0 3'\
+ 'f8f6'
+# 960, en passant move
+testfen 'bbnrk1nq/ppp1p2p/3r4/3p1ppP/P2P1P2/8/1PP1P1P1/BBNRKRNQ w KQq g6 0 6'\
+ 'bbnrk1nq/ppp1p1pp/3r4/3p1p1P/P2P1P2/8/1PP1P1P1/BBNRKRNQ b KQq - 0 5'\
+ 'g7g5'
+# 960, en passant take
+testfen 'bbnrk1nq/ppp1p2p/3r2P1/3p1p2/P2P1P2/8/1PP1P1P1/BBNRKRNQ b KQq - 0 6'\
+ 'bbnrk1nq/ppp1p2p/3r4/3p1ppP/P2P1P2/8/1PP1P1P1/BBNRKRNQ w KQq g6 0 6'\
+ 'h5g6'