improve check for castling and castling availability - 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 b9e10f90912e4d6c82e4a4738a2fcdbd77b0d6db
 (DIR) parent 526df2437b7f656c5f7f68f207478dd2ee15db53
 (HTM) 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(-)
       ---
 (DIR) 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);
        
 (DIR) 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'