Thu, 03 Sep 2026 16:18:24 +0200
make castling rights part of the game state
required for issue #939
because creating a state from FEN
will not contain a move history
bonus: make is_check_position() robust
|
10
1347e4dabac0
prepared code base for implementing rules
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
1 | /* |
|
1347e4dabac0
prepared code base for implementing rules
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
|
1347e4dabac0
prepared code base for implementing rules
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
3 | * |
|
55
54ea19938d57
updated copyright and version info
Mike Becker <universe@uap-core.de>
parents:
47
diff
changeset
|
4 | * Copyright 2016 Mike Becker. All rights reserved. |
|
10
1347e4dabac0
prepared code base for implementing rules
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
5 | * |
|
1347e4dabac0
prepared code base for implementing rules
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
6 | * Redistribution and use in source and binary forms, with or without |
|
1347e4dabac0
prepared code base for implementing rules
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
7 | * modification, are permitted provided that the following conditions are met: |
|
1347e4dabac0
prepared code base for implementing rules
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
8 | * |
|
1347e4dabac0
prepared code base for implementing rules
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
9 | * 1. Redistributions of source code must retain the above copyright |
|
1347e4dabac0
prepared code base for implementing rules
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
10 | * notice, this list of conditions and the following disclaimer. |
|
1347e4dabac0
prepared code base for implementing rules
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
11 | * |
|
1347e4dabac0
prepared code base for implementing rules
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
12 | * 2. Redistributions in binary form must reproduce the above copyright |
|
1347e4dabac0
prepared code base for implementing rules
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
13 | * notice, this list of conditions and the following disclaimer in the |
|
1347e4dabac0
prepared code base for implementing rules
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
14 | * documentation and/or other materials provided with the distribution. |
|
1347e4dabac0
prepared code base for implementing rules
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
15 | * |
|
1347e4dabac0
prepared code base for implementing rules
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
|
1347e4dabac0
prepared code base for implementing rules
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
1347e4dabac0
prepared code base for implementing rules
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|
1347e4dabac0
prepared code base for implementing rules
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
|
1347e4dabac0
prepared code base for implementing rules
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
20 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
|
1347e4dabac0
prepared code base for implementing rules
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
|
1347e4dabac0
prepared code base for implementing rules
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
|
1347e4dabac0
prepared code base for implementing rules
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
|
1347e4dabac0
prepared code base for implementing rules
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
|
1347e4dabac0
prepared code base for implementing rules
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
1347e4dabac0
prepared code base for implementing rules
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
26 | * POSSIBILITY OF SUCH DAMAGE. |
|
1347e4dabac0
prepared code base for implementing rules
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
27 | * |
|
1347e4dabac0
prepared code base for implementing rules
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
28 | */ |
|
1347e4dabac0
prepared code base for implementing rules
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
29 | |
|
16
a298c6637c30
introduced status codes for get_location to produce detailed error messages + added knight rules
Mike Becker <universe@uap-core.de>
parents:
12
diff
changeset
|
30 | #include "rules.h" |
|
10
1347e4dabac0
prepared code base for implementing rules
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
31 | #include "king.h" |
| 25 | 32 | |
|
163
2a6d83f4677e
major refactoring of rules API
Mike Becker <universe@uap-core.de>
parents:
161
diff
changeset
|
33 | bool king_chkrules(const GameState *gamestate, const Move* move) { |
| 194 | 34 | if (abs(move->torank - move->fromrank) <= 1 && |
| 25 | 35 | abs(move->tofile - move->fromfile) <= 1) { |
|
80
b980a7192b5a
replace _Bool with bool from C23 and/or stdbool.h
Mike Becker <universe@uap-core.de>
parents:
64
diff
changeset
|
36 | return true; |
|
216
d0c3d3016650
make castling rights part of the game state
Mike Becker <universe@uap-core.de>
parents:
195
diff
changeset
|
37 | } else if (move->fromrank == move->torank) { |
| 25 | 38 | /* castling */ |
|
216
d0c3d3016650
make castling rights part of the game state
Mike Becker <universe@uap-core.de>
parents:
195
diff
changeset
|
39 | Rank backrank; |
|
d0c3d3016650
make castling rights part of the game state
Mike Becker <universe@uap-core.de>
parents:
195
diff
changeset
|
40 | bool k_allowed, q_allowed; |
|
d0c3d3016650
make castling rights part of the game state
Mike Becker <universe@uap-core.de>
parents:
195
diff
changeset
|
41 | if (piece_color(move->piece) == WHITE) { |
|
d0c3d3016650
make castling rights part of the game state
Mike Becker <universe@uap-core.de>
parents:
195
diff
changeset
|
42 | backrank = rankidx('1'); |
|
d0c3d3016650
make castling rights part of the game state
Mike Becker <universe@uap-core.de>
parents:
195
diff
changeset
|
43 | k_allowed = !gamestate->castling.K; |
|
d0c3d3016650
make castling rights part of the game state
Mike Becker <universe@uap-core.de>
parents:
195
diff
changeset
|
44 | q_allowed = !gamestate->castling.Q; |
| 25 | 45 | } else { |
|
216
d0c3d3016650
make castling rights part of the game state
Mike Becker <universe@uap-core.de>
parents:
195
diff
changeset
|
46 | backrank = rankidx('8'); |
|
d0c3d3016650
make castling rights part of the game state
Mike Becker <universe@uap-core.de>
parents:
195
diff
changeset
|
47 | k_allowed = !gamestate->castling.k; |
|
d0c3d3016650
make castling rights part of the game state
Mike Becker <universe@uap-core.de>
parents:
195
diff
changeset
|
48 | q_allowed = !gamestate->castling.q; |
| 25 | 49 | } |
|
216
d0c3d3016650
make castling rights part of the game state
Mike Becker <universe@uap-core.de>
parents:
195
diff
changeset
|
50 | bool castle_q = false, castle_k = false; |
|
d0c3d3016650
make castling rights part of the game state
Mike Becker <universe@uap-core.de>
parents:
195
diff
changeset
|
51 | if (move->fromrank == backrank && move->fromfile == fileidx('e')) { |
|
d0c3d3016650
make castling rights part of the game state
Mike Becker <universe@uap-core.de>
parents:
195
diff
changeset
|
52 | castle_q = move->tofile == fileidx('c'); |
|
d0c3d3016650
make castling rights part of the game state
Mike Becker <universe@uap-core.de>
parents:
195
diff
changeset
|
53 | castle_k = move->tofile == fileidx('g'); |
|
d0c3d3016650
make castling rights part of the game state
Mike Becker <universe@uap-core.de>
parents:
195
diff
changeset
|
54 | } |
|
d0c3d3016650
make castling rights part of the game state
Mike Becker <universe@uap-core.de>
parents:
195
diff
changeset
|
55 | /* note that here we do not consider threats! |
|
d0c3d3016650
make castling rights part of the game state
Mike Becker <universe@uap-core.de>
parents:
195
diff
changeset
|
56 | * that is what king_isblocked() does */ |
|
d0c3d3016650
make castling rights part of the game state
Mike Becker <universe@uap-core.de>
parents:
195
diff
changeset
|
57 | return (castle_q && q_allowed) || (castle_k && k_allowed); |
|
d0c3d3016650
make castling rights part of the game state
Mike Becker <universe@uap-core.de>
parents:
195
diff
changeset
|
58 | } else { |
|
d0c3d3016650
make castling rights part of the game state
Mike Becker <universe@uap-core.de>
parents:
195
diff
changeset
|
59 | return false; |
| 25 | 60 | } |
|
10
1347e4dabac0
prepared code base for implementing rules
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
61 | } |
|
1347e4dabac0
prepared code base for implementing rules
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
62 | |
|
163
2a6d83f4677e
major refactoring of rules API
Mike Becker <universe@uap-core.de>
parents:
161
diff
changeset
|
63 | bool king_isblocked(const GameState *gamestate, const Move *move) { |
|
64
4eda5df55f86
fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents:
55
diff
changeset
|
64 | /* just test, if castling move is blocked */ |
| 25 | 65 | if (abs(move->tofile - move->fromfile) == 2) { |
| 66 | if (move->tofile == fileidx('c')) { | |
|
216
d0c3d3016650
make castling rights part of the game state
Mike Becker <universe@uap-core.de>
parents:
195
diff
changeset
|
67 | /* check if rook can travel the queen-side */ |
|
d0c3d3016650
make castling rights part of the game state
Mike Becker <universe@uap-core.de>
parents:
195
diff
changeset
|
68 | if (gamestate->board[move->torank][fileidx('b')]) { |
|
d0c3d3016650
make castling rights part of the game state
Mike Becker <universe@uap-core.de>
parents:
195
diff
changeset
|
69 | return true; |
|
d0c3d3016650
make castling rights part of the game state
Mike Becker <universe@uap-core.de>
parents:
195
diff
changeset
|
70 | } |
| 25 | 71 | } |
|
216
d0c3d3016650
make castling rights part of the game state
Mike Becker <universe@uap-core.de>
parents:
195
diff
changeset
|
72 | /* check if new field for the rook is free */ |
| 194 | 73 | File midfile = (move->tofile+move->fromfile)/2; |
|
216
d0c3d3016650
make castling rights part of the game state
Mike Becker <universe@uap-core.de>
parents:
195
diff
changeset
|
74 | if (gamestate->board[move->torank][midfile]) { |
|
d0c3d3016650
make castling rights part of the game state
Mike Becker <universe@uap-core.de>
parents:
195
diff
changeset
|
75 | return true; |
|
161
3ff96fec144a
convert some macros to static inline functions
Mike Becker <universe@uap-core.de>
parents:
98
diff
changeset
|
76 | } |
|
216
d0c3d3016650
make castling rights part of the game state
Mike Becker <universe@uap-core.de>
parents:
195
diff
changeset
|
77 | /* check if the king or the target field for the rook is threatened */ |
|
d0c3d3016650
make castling rights part of the game state
Mike Becker <universe@uap-core.de>
parents:
195
diff
changeset
|
78 | if (is_check_position(gamestate) || is_covered(gamestate, |
|
d0c3d3016650
make castling rights part of the game state
Mike Becker <universe@uap-core.de>
parents:
195
diff
changeset
|
79 | midfile, move->torank, opponent_color(piece_color(move->piece)))) { |
|
d0c3d3016650
make castling rights part of the game state
Mike Becker <universe@uap-core.de>
parents:
195
diff
changeset
|
80 | return true; |
|
d0c3d3016650
make castling rights part of the game state
Mike Becker <universe@uap-core.de>
parents:
195
diff
changeset
|
81 | } |
| 25 | 82 | } |
|
216
d0c3d3016650
make castling rights part of the game state
Mike Becker <universe@uap-core.de>
parents:
195
diff
changeset
|
83 | return false; |
|
10
1347e4dabac0
prepared code base for implementing rules
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
84 | } |
|
169
9962f5d98764
add functions to list the possible moves for each piece
Mike Becker <universe@uap-core.de>
parents:
163
diff
changeset
|
85 | |
|
170
bde99d803caf
implements stalemate detection + fixes missing const qualifier in new *_moves[_allowed] API
Mike Becker <universe@uap-core.de>
parents:
169
diff
changeset
|
86 | size_t king_moves(const GameState *gamestate, |
|
195
27d02ccb0cef
flip File and Rank parameters into correct order
Mike Becker <universe@uap-core.de>
parents:
194
diff
changeset
|
87 | Color c, File f, Rank r, Move *moves) { |
|
169
9962f5d98764
add functions to list the possible moves for each piece
Mike Becker <universe@uap-core.de>
parents:
163
diff
changeset
|
88 | |
|
9962f5d98764
add functions to list the possible moves for each piece
Mike Becker <universe@uap-core.de>
parents:
163
diff
changeset
|
89 | size_t count = 0; |
|
9962f5d98764
add functions to list the possible moves for each piece
Mike Becker <universe@uap-core.de>
parents:
163
diff
changeset
|
90 | Piece king = mkpiece(KING, c); |
|
9962f5d98764
add functions to list the possible moves for each piece
Mike Becker <universe@uap-core.de>
parents:
163
diff
changeset
|
91 | |
|
9962f5d98764
add functions to list the possible moves for each piece
Mike Becker <universe@uap-core.de>
parents:
163
diff
changeset
|
92 | for (int dr = -1 ; dr <= 1 ; dr++) { |
|
9962f5d98764
add functions to list the possible moves for each piece
Mike Becker <universe@uap-core.de>
parents:
163
diff
changeset
|
93 | for (int df = -1 ; df <= 1 ; df++) { |
|
9962f5d98764
add functions to list the possible moves for each piece
Mike Becker <universe@uap-core.de>
parents:
163
diff
changeset
|
94 | if (dr == 0 && df == 0) { |
|
9962f5d98764
add functions to list the possible moves for each piece
Mike Becker <universe@uap-core.de>
parents:
163
diff
changeset
|
95 | continue; |
|
9962f5d98764
add functions to list the possible moves for each piece
Mike Becker <universe@uap-core.de>
parents:
163
diff
changeset
|
96 | } |
|
9962f5d98764
add functions to list the possible moves for each piece
Mike Becker <universe@uap-core.de>
parents:
163
diff
changeset
|
97 | |
| 194 | 98 | Rank torank = r + dr; |
|
169
9962f5d98764
add functions to list the possible moves for each piece
Mike Becker <universe@uap-core.de>
parents:
163
diff
changeset
|
99 | File tofile = f + df; |
|
9962f5d98764
add functions to list the possible moves for each piece
Mike Becker <universe@uap-core.de>
parents:
163
diff
changeset
|
100 | |
| 194 | 101 | if (!isidx(torank) || !isidx(tofile)) { |
|
169
9962f5d98764
add functions to list the possible moves for each piece
Mike Becker <universe@uap-core.de>
parents:
163
diff
changeset
|
102 | continue; |
|
9962f5d98764
add functions to list the possible moves for each piece
Mike Becker <universe@uap-core.de>
parents:
163
diff
changeset
|
103 | } |
|
9962f5d98764
add functions to list the possible moves for each piece
Mike Becker <universe@uap-core.de>
parents:
163
diff
changeset
|
104 | |
|
9962f5d98764
add functions to list the possible moves for each piece
Mike Becker <universe@uap-core.de>
parents:
163
diff
changeset
|
105 | moves[count] = (Move){0}; |
|
9962f5d98764
add functions to list the possible moves for each piece
Mike Becker <universe@uap-core.de>
parents:
163
diff
changeset
|
106 | moves[count].piece = king; |
| 194 | 107 | moves[count].fromrank = r; |
|
169
9962f5d98764
add functions to list the possible moves for each piece
Mike Becker <universe@uap-core.de>
parents:
163
diff
changeset
|
108 | moves[count].fromfile = f; |
| 194 | 109 | moves[count].torank = torank; |
|
169
9962f5d98764
add functions to list the possible moves for each piece
Mike Becker <universe@uap-core.de>
parents:
163
diff
changeset
|
110 | moves[count].tofile = tofile; |
|
195
27d02ccb0cef
flip File and Rank parameters into correct order
Mike Becker <universe@uap-core.de>
parents:
194
diff
changeset
|
111 | moves[count].capture = piece_at(gamestate, tofile, torank) != 0; |
|
169
9962f5d98764
add functions to list the possible moves for each piece
Mike Becker <universe@uap-core.de>
parents:
163
diff
changeset
|
112 | count++; |
|
9962f5d98764
add functions to list the possible moves for each piece
Mike Becker <universe@uap-core.de>
parents:
163
diff
changeset
|
113 | } |
|
9962f5d98764
add functions to list the possible moves for each piece
Mike Becker <universe@uap-core.de>
parents:
163
diff
changeset
|
114 | } |
|
9962f5d98764
add functions to list the possible moves for each piece
Mike Becker <universe@uap-core.de>
parents:
163
diff
changeset
|
115 | |
| 194 | 116 | Rank homerank = c == WHITE ? 0 : 7; |
| 117 | if (r == homerank && f == fileidx('e')) { | |
|
169
9962f5d98764
add functions to list the possible moves for each piece
Mike Becker <universe@uap-core.de>
parents:
163
diff
changeset
|
118 | moves[count] = (Move){0}; |
|
9962f5d98764
add functions to list the possible moves for each piece
Mike Becker <universe@uap-core.de>
parents:
163
diff
changeset
|
119 | moves[count].piece = king; |
| 194 | 120 | moves[count].fromrank = r; |
|
169
9962f5d98764
add functions to list the possible moves for each piece
Mike Becker <universe@uap-core.de>
parents:
163
diff
changeset
|
121 | moves[count].fromfile = f; |
| 194 | 122 | moves[count].torank = r; |
|
169
9962f5d98764
add functions to list the possible moves for each piece
Mike Becker <universe@uap-core.de>
parents:
163
diff
changeset
|
123 | moves[count].tofile = fileidx('c'); |
|
9962f5d98764
add functions to list the possible moves for each piece
Mike Becker <universe@uap-core.de>
parents:
163
diff
changeset
|
124 | count++; |
|
9962f5d98764
add functions to list the possible moves for each piece
Mike Becker <universe@uap-core.de>
parents:
163
diff
changeset
|
125 | |
|
9962f5d98764
add functions to list the possible moves for each piece
Mike Becker <universe@uap-core.de>
parents:
163
diff
changeset
|
126 | moves[count] = (Move){0}; |
|
9962f5d98764
add functions to list the possible moves for each piece
Mike Becker <universe@uap-core.de>
parents:
163
diff
changeset
|
127 | moves[count].piece = king; |
| 194 | 128 | moves[count].fromrank = r; |
|
169
9962f5d98764
add functions to list the possible moves for each piece
Mike Becker <universe@uap-core.de>
parents:
163
diff
changeset
|
129 | moves[count].fromfile = f; |
| 194 | 130 | moves[count].torank = r; |
|
169
9962f5d98764
add functions to list the possible moves for each piece
Mike Becker <universe@uap-core.de>
parents:
163
diff
changeset
|
131 | moves[count].tofile = fileidx('g'); |
|
9962f5d98764
add functions to list the possible moves for each piece
Mike Becker <universe@uap-core.de>
parents:
163
diff
changeset
|
132 | count++; |
|
9962f5d98764
add functions to list the possible moves for each piece
Mike Becker <universe@uap-core.de>
parents:
163
diff
changeset
|
133 | } |
|
9962f5d98764
add functions to list the possible moves for each piece
Mike Becker <universe@uap-core.de>
parents:
163
diff
changeset
|
134 | |
|
9962f5d98764
add functions to list the possible moves for each piece
Mike Becker <universe@uap-core.de>
parents:
163
diff
changeset
|
135 | return count; |
|
9962f5d98764
add functions to list the possible moves for each piece
Mike Becker <universe@uap-core.de>
parents:
163
diff
changeset
|
136 | } |