tests.sh - chess-puzzles - chess puzzle book generator | |
git clone git://git.codemadness.org/chess-puzzles | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
tests.sh (28832B) | |
--- | |
1 #!/bin/sh | |
2 | |
3 statuscode=0 | |
4 failed=0 | |
5 | |
6 # testfen(name, expect, fen, moves) | |
7 testfen() { | |
8 name="$1" | |
9 expect="$2" | |
10 fen="$3" | |
11 moves="$4" | |
12 | |
13 # input FEN with no moves should match output FEN (except "start… | |
14 output=$(./fen -o fen "$fen" "") | |
15 if test "$fen" != "startpos" && test "$fen" != "$output"; then | |
16 printf '[FEN] Fail: %s, input FEN does not match output … | |
17 printf '\texpected: %s\n' "$fen" >&2 | |
18 printf '\tgot: %s\n' "$output" >&2 | |
19 statuscode=1 | |
20 failed=$((failed+1)) | |
21 fi | |
22 | |
23 output=$(./fen -o fen "$fen" "$moves") | |
24 if test "$output" = "$expect"; then | |
25 printf '[FEN] OK: %s\n' "$name" | |
26 else | |
27 printf '[FEN] Fail: %s\n' "$name" >&2 | |
28 printf '\texpected: %s\n' "$expect" >&2 | |
29 printf '\tgot: %s\n' "$output" >&2 | |
30 printf '\tInput FEN, moves: "%s" "%s"\n' "$fen" "$moves"… | |
31 statuscode=1 | |
32 failed=$((failed+1)) | |
33 fi | |
34 } | |
35 | |
36 # testpgn(name, expect, fen, moves) | |
37 testpgn() { | |
38 name="$1" | |
39 expect="$2" | |
40 fen="$3" | |
41 moves="$4" | |
42 | |
43 output=$(./fen -o pgn "$fen" "$moves") | |
44 if test "$output" = "$expect"; then | |
45 printf '[PGN] OK: %s\n' "$name" | |
46 else | |
47 printf '[PGN] Fail: %s\n' "$name" >&2 | |
48 printf '\texpected: %s\n' "$expect" >&2 | |
49 printf '\tgot: %s\n' "$output" >&2 | |
50 printf '\tInput FEN, moves: "%s" "%s"\n' "$fen" "$moves"… | |
51 statuscode=1 | |
52 failed=$((failed+1)) | |
53 fi | |
54 } | |
55 | |
56 tests_fen() { | |
57 testfen 'startpos'\ | |
58 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1' \ | |
59 "startpos"\ | |
60 "" | |
61 | |
62 # white castles kingside | |
63 testfen 'white castles kingside'\ | |
64 'rnbqkb1r/p4ppp/1pp1pn2/3p4/3P1B2/3BPN2/PPP2PPP/RN1Q1RK1 b kq - … | |
65 'rnbqkb1r/p4ppp/1pp1pn2/3p4/3P1B2/3BPN2/PPP2PPP/RN1QK2R w KQkq -… | |
66 'e1g1' | |
67 testfen 'white castles kingside'\ | |
68 'r3k2r/p2bqpp1/nppbpn1p/3p4/3P1B2/2NBPN2/PPPQ1PPP/R4RK1 b kq - 9… | |
69 'r3k2r/p2bqpp1/nppbpn1p/3p4/3P1B2/2NBPN2/PPPQ1PPP/R3K2R w KQkq -… | |
70 'e1g1' | |
71 testfen 'white castles queenside'\ | |
72 'r3k2r/p2bqpp1/nppbpn1p/3p4/3P1B2/2NBPN2/PPPQ1PPP/2KR3R b kq - 9… | |
73 'r3k2r/p2bqpp1/nppbpn1p/3p4/3P1B2/2NBPN2/PPPQ1PPP/R3K2R w KQkq -… | |
74 'e1c1' | |
75 | |
76 # black castles kingside | |
77 testfen 'black castles kingside'\ | |
78 'rnbq1rk1/p3bppp/1pp1pn2/3p4/3P1B2/3BPN2/PPPN1PPP/R2Q1RK1 w - - … | |
79 'rnbqk2r/p3bppp/1pp1pn2/3p4/3P1B2/3BPN2/PPPN1PPP/R2Q1RK1 b kq - … | |
80 'e8g8' | |
81 testfen 'black castles kingside'\ | |
82 'r4rk1/p2bqpp1/nppbpn1p/3p4/3P1B2/2NBPN2/PPPQ1PPP/R4RK1 w - - 10… | |
83 'r3k2r/p2bqpp1/nppbpn1p/3p4/3P1B2/2NBPN2/PPPQ1PPP/R4RK1 b kq - 9… | |
84 'e8g8' | |
85 testfen 'black castles queenside'\ | |
86 '2kr3r/p2bqpp1/nppbpn1p/3p4/3P1B2/2NBPN2/PPPQ1PPP/R4RK1 w - - 10… | |
87 'r3k2r/p2bqpp1/nppbpn1p/3p4/3P1B2/2NBPN2/PPPQ1PPP/R4RK1 b kq - 9… | |
88 'e8c8' | |
89 | |
90 # check castling: the white queen is in check, but this doesn't change t… | |
91 testfen 'white queen is in check, shouldnt change castling state'\ | |
92 'rnb1kb1r/pp2qppp/2p2n2/3p4/3P1B2/3B1N2/PPP2PPP/RN1QK2R w KQkq -… | |
93 'rnb1kb1r/pp2qppp/2p1pn2/3P4/3P1B2/3B1N2/PPP2PPP/RN1QK2R b KQkq … | |
94 'e6d5' | |
95 | |
96 # check castling: black moves kingside rook: this removes castling on th… | |
97 testfen 'black moves kingside rook: this removes castling on this side'\ | |
98 'rnb1kbr1/pp2qppp/2p2n2/3p4/3P1B2/3B1N2/PPP1QPPP/RN2K2R w KQq - … | |
99 'rnb1kb1r/pp2qppp/2p2n2/3p4/3P1B2/3B1N2/PPP1QPPP/RN2K2R b KQkq -… | |
100 'h8g8' | |
101 | |
102 # check castling: white moves kingside rook: this removes castling on th… | |
103 testfen 'white moves kingside rook: this removes castling on this side'\ | |
104 'rnb1kb2/pp2qppr/2p2n2/3p4/3P1B2/3B1N2/PPP1QPPP/RN2K1R1 b Qq - 3… | |
105 'rnb1kb2/pp2qppr/2p2n2/3p4/3P1B2/3B1N2/PPP1QPPP/RN2K2R w KQq - 2… | |
106 'h1g1' | |
107 # check castling: white moves queenside rook: this removes castling on t… | |
108 testfen 'white moves queenside rook: this removes castling on this side'\ | |
109 'rnb1kb2/1p2qpp1/p1p2n2/3p4/3P1B2/3B1N2/PPPNQPPr/1R2K1R1 b q - 1… | |
110 'rnb1kb2/1p2qpp1/p1p2n2/3p4/3P1B2/3B1N2/PPPNQPPr/R3K1R1 w Qq - 0… | |
111 'a1b1' | |
112 # white king move, remove castling availability | |
113 testfen 'white king move, remove castling availability'\ | |
114 'rnb1kb2/1p2qpp1/p1p2n2/3p4/3P1B2/3B1N2/PPPNQPPr/R2K2R1 b q - 1 … | |
115 'rnb1kb2/1p2qpp1/p1p2n2/3p4/3P1B2/3B1N2/PPPNQPPr/R3K1R1 w Qq - 0… | |
116 'e1d1' | |
117 # white king move, remove castling availability | |
118 testfen 'white king move, remove castling availability'\ | |
119 'r3k2r/pppppppp/8/8/8/8/PPPPPPPP/R2K3R b kq - 1 1'\ | |
120 'r3k2r/pppppppp/8/8/8/8/PPPPPPPP/R3K2R w KQkq - 0 1'\ | |
121 'e1d1' | |
122 # black king move, remove castling availability | |
123 testfen 'black king move, remove castling availability'\ | |
124 'r4k1r/pppppppp/8/8/8/8/PPPPPPPP/R2K3R w - - 2 2'\ | |
125 'r3k2r/pppppppp/8/8/8/8/PPPPPPPP/R2K3R b kq - 1 1'\ | |
126 'e8f8' | |
127 | |
128 # black is laz0rbeamed by white bishop on the queenside on b8, but not o… | |
129 # castling square it is allowed to castle. | |
130 testfen 'black is laz0rbeamed by white bishop'\ | |
131 '2kr1br1/pp2qppp/n1p1bn2/3p4/3P1B2/3BQN2/PPP2PPP/RN2K2R w KQ - 8… | |
132 'r3kbr1/pp2qppp/n1p1bn2/3p4/3P1B2/3BQN2/PPP2PPP/RN2K2R b KQq - 7… | |
133 'e8c8' | |
134 # white moves bishop and blocks castling for black, but this doesn't cha… | |
135 # castle state itself. | |
136 testfen 'white moves bishop and blocks castling for black, shouldnt chan… | |
137 'r3kbr1/pp2qppp/n1p2n2/3p1B2/3P1B2/4QN1b/PPP2PPP/RN2K2R b KQq - … | |
138 'r3kbr1/pp2qppp/n1p2n2/3p4/3P1B2/3BQN1b/PPP2PPP/RN2K2R w KQq - 8… | |
139 'd3f5' | |
140 | |
141 # test en passant: move white pawn g2 to g4, enpassant square becomes g3. | |
142 testfen 'move white pawn g2 to g4, enpassant square becomes g3'\ | |
143 'r4k1r/ppppp1pp/8/8/5pP1/4P3/PPPP1P1P/R3K2R b - g3 0 4'\ | |
144 'r4k1r/ppppp1pp/8/8/5p2/4P3/PPPP1PPP/R3K2R w - - 0 4'\ | |
145 'g2g4' | |
146 | |
147 # moving 2 squares near a pawn, but not en passant. | |
148 testfen 'moving 2 squares near a pawn, but not en passant'\ | |
149 'r4k1r/ppppp1p1/8/5p2/6P1/4P2p/PPPP1P1P/R3K2R b - - 0 6'\ | |
150 'r4k1r/ppppp1p1/8/5p2/8/4P2p/PPPP1PPP/R3K2R w - - 0 6'\ | |
151 'g2g4' | |
152 # test en passant for black. | |
153 testfen 'en passant for black'\ | |
154 'r4k1r/ppp1p1p1/8/2Pp1p2/6P1/4P2p/PP1P1P1P/R3K2R w - d6 0 9'\ | |
155 'r4k1r/ppppp1p1/8/2P2p2/6P1/4P2p/PP1P1P1P/R3K2R b - - 0 8'\ | |
156 'd7d5' | |
157 testfen 'en passant move for black'\ | |
158 'r4k1r/p1ppp1p1/8/1pP2p2/6P1/4P2p/PP1P1P1P/R3K2R w - b6 0 9'\ | |
159 'r4k1r/ppppp1p1/8/2P2p2/6P1/4P2p/PP1P1P1P/R3K2R b - - 0 8'\ | |
160 'b7b5' | |
161 # white takes en passant | |
162 testfen 'white takes en passant'\ | |
163 'rnbqkbnr/pppp1pp1/4P3/7p/8/8/PPP1PPPP/RNBQKBNR b KQkq - 0 3'\ | |
164 'rnbqkbnr/pppp1pp1/8/3Pp2p/8/8/PPP1PPPP/RNBQKBNR w KQkq e6 0 3'\ | |
165 'd5e6' | |
166 # black takes en passant | |
167 testfen 'black takes en passant'\ | |
168 'rnbqkbnr/ppppppp1/8/8/3P4/4P1p1/PPP2P1P/RNBQKBNR w KQkq - 0 4'\ | |
169 'rnbqkbnr/ppppppp1/8/8/3P2Pp/4P3/PPP2P1P/RNBQKBNR b KQkq g3 0 3'\ | |
170 'h4g3' | |
171 | |
172 # white takes en passant: should reset halfmove counter | |
173 testfen 'white takes en passant: should reset halfmove counter'\ | |
174 'rnbqkbnr/pppp1pp1/4P3/7p/8/8/PPP1PPPP/RNBQKBNR b KQkq - 0 3'\ | |
175 'rnbqkbnr/pppp1pp1/8/3Pp2p/8/8/PPP1PPPP/RNBQKBNR w KQkq e6 1 3'\ | |
176 'd5e6' | |
177 | |
178 # check halfmove counter on check, white checks black: should increase h… | |
179 testfen 'check halfmove counter on check, white checks black: should inc… | |
180 'rnbqkbnr/ppp1pp1p/6p1/1B1p4/3P4/4P3/PPP2PPP/RNBQK1NR b KQkq - 2… | |
181 'rnbqkbnr/ppp1pp1p/6p1/3p4/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq - 20 … | |
182 'f1b5' | |
183 | |
184 # TODO: this is incorrect (illegal move), fix it? | |
185 # 960 white queenside castle | |
186 testfen '960 white queenside castle'\ | |
187 'qrn1bk1n/ppb1pprp/2p3p1/3p4/1B1P4/3NPB2/PPP2PPP/Q1KR2RN b q - 5… | |
188 'qrn1bk1n/ppb1pprp/2p3p1/3p4/1B1P4/3NPB2/PPP2PPP/QR3KRN w KQq - … | |
189 'f1c1' | |
190 # 960, rook moved: remove ability for black to castle | |
191 testfen '960, rook moved: remove ability for black to castle'\ | |
192 'q1r1bk1n/ppb1pprp/2pn2p1/3p4/1B1P4/3NPB2/PPP2PPP/Q1KRR2N w - - … | |
193 'qr2bk1n/ppb1pprp/2pn2p1/3p4/1B1P4/3NPB2/PPP2PPP/Q1KRR2N b q - 7… | |
194 'b8c8' | |
195 # 960, rook moved | |
196 testfen '960, rook moved, castling ability'\ | |
197 'bbnrkrnq/ppp1p1pp/8/3p1p2/3P1P2/3R4/PPP1P1PP/BBN1KRNQ b Kkq - 1… | |
198 'bbnrkrnq/ppp1p1pp/8/3p1p2/3P1P2/8/PPP1P1PP/BBNRKRNQ w KQkq - 0 … | |
199 'd1d3' | |
200 # 960, rook moved | |
201 testfen '960, rook moved, castling ability'\ | |
202 'bbnrkrnq/ppp1p1pp/8/3p1p2/3P1P2/5R2/PPP1P1PP/BBNRK1NQ b Qkq - 1… | |
203 'bbnrkrnq/ppp1p1pp/8/3p1p2/3P1P2/8/PPP1P1PP/BBNRKRNQ w KQkq - 0 … | |
204 'f1f3' | |
205 # 960, rook moved | |
206 testfen '960, rook moved, castling ability'\ | |
207 'bbn1krnq/ppp1p1pp/3r4/3p1p2/P2P1P2/8/1PP1P1PP/BBNRKRNQ w KQk - … | |
208 'bbnrkrnq/ppp1p1pp/8/3p1p2/P2P1P2/8/1PP1P1PP/BBNRKRNQ b KQkq - 0… | |
209 'd8d6' | |
210 # 960, rook moved | |
211 testfen '960, rook moved, castling ability'\ | |
212 'bbnrk1nq/ppp1p1pp/5r2/3p1p2/P2P1P2/8/1PP1P1PP/BBNRKRNQ w KQq - … | |
213 'bbnrkrnq/ppp1p1pp/8/3p1p2/P2P1P2/8/1PP1P1PP/BBNRKRNQ b KQkq - 0… | |
214 'f8f6' | |
215 # 960, en passant move | |
216 testfen '960, en passant move'\ | |
217 'bbnrk1nq/ppp1p2p/3r4/3p1ppP/P2P1P2/8/1PP1P1P1/BBNRKRNQ w KQq g6… | |
218 'bbnrk1nq/ppp1p1pp/3r4/3p1p1P/P2P1P2/8/1PP1P1P1/BBNRKRNQ b KQq -… | |
219 'g7g5' | |
220 # 960, en passant take | |
221 testfen '960, en passant take'\ | |
222 'bbnrk1nq/ppp1p2p/3r2P1/3p1p2/P2P1P2/8/1PP1P1P1/BBNRKRNQ b KQq -… | |
223 'bbnrk1nq/ppp1p2p/3r4/3p1ppP/P2P1P2/8/1PP1P1P1/BBNRKRNQ w KQq g6… | |
224 'h5g6' | |
225 | |
226 # 960, white castle kingside with rook right next to the king, doesnt re… | |
227 testfen '960, castle with rook right next to the king, doesnt reset half… | |
228 'nnbrqkrb/ppp1pp1p/8/3p2p1/1Q1P4/8/PPP1PPPP/NNBR1RKB b kq - 1 3'\ | |
229 'nnbrqkrb/ppp1pp1p/8/3p2p1/1Q1P4/8/PPP1PPPP/NNBR1KRB w KQkq - 0 … | |
230 'f1g1' | |
231 testfen '960, black castle kingside with rook right next to the king, do… | |
232 'nnbrqrkb/ppp1pp1p/8/3p2p1/3P4/2Q5/PPP1PPPP/NNBR1KRB w KQ - 2 4'\ | |
233 'nnbrqkrb/ppp1pp1p/8/3p2p1/3P4/2Q5/PPP1PPPP/NNBR1KRB b KQkq - 1 … | |
234 'f8g8' | |
235 | |
236 testfen '960, castle king on queenside with many empty squares between t… | |
237 '1rb1krq1/pp2ppb1/3p2p1/1Np4p/2P1P3/1P2N3/P4PPP/2KR1RQB b kq - 1… | |
238 '1rb1krq1/pp2ppb1/3p2p1/1Np4p/2P1P3/1P2N3/P4PPP/1R2KRQB w KQkq -… | |
239 'e1c1' | |
240 | |
241 testfen 'black moves pawn en passant into check (not mate, can take en p… | |
242 'rnbqkbnr/p2ppppp/1p6/1PpPP3/2PKQ3/2PQQ3/P1PP1PPP/RNBQ1BNR w kq … | |
243 'rnbqkbnr/p1pppppp/1p6/1P1PP3/2PKQ3/2PQQ3/P1PP1PPP/RNBQ1BNR b kq… | |
244 'c7c5' | |
245 | |
246 # NOTE: Lichess checks if en passant moves can actually be played, but t… | |
247 # reference specifies this doesn't necesarily have to be the case. | |
248 testfen 'black moves pawn en passant into checkmate (cant take en passan… | |
249 'rnbqkbnr/p3pppp/1p6/2pPP3/2PKQ3/2PQQ3/P1PP1PPP/RNBQ1BNR w kq - … | |
250 'rnbqkbnr/p1p1pppp/1p6/3PP3/2PKQ3/2PQQ3/P1PP1PPP/RNBQ1BNR b kq -… | |
251 'c7c5' | |
252 | |
253 testfen 'white is checkmated (en passant square is not set), do not remo… | |
254 'rnbqkbnr/p2ppppp/1pP5/1Pp1P3/2PKQ3/2PQQ3/P1PP1PPP/RNBQ1BNR b kq… | |
255 'rnbqkbnr/p2ppppp/1p6/1PpPP3/2PKQ3/2PQQ3/P1PP1PPP/RNBQ1BNR w kq … | |
256 'd5c6' | |
257 | |
258 testfen 'white is not checkmated (en passant square is set and can be pl… | |
259 'rnbqkbnr/p2ppppp/1pP5/1P2P3/2PKQ3/2PQQ3/P1PP1PPP/RNBQ1BNR b kq … | |
260 'rnbqkbnr/p2ppppp/1p6/1PpPP3/2PKQ3/2PQQ3/P1PP1PPP/RNBQ1BNR w kq … | |
261 'd5c6' | |
262 | |
263 testfen 'white promote to queen'\ | |
264 'rnbqkbQr/p1pppp1p/8/8/8/8/PpPPPP1P/R1BQKBNR b KQkq - 0 1'\ | |
265 'rnbqkb1r/p1ppppPp/8/8/8/8/PpPPPP1P/R1BQKBNR w KQkq - 0 1'\ | |
266 'g7g8Q' | |
267 | |
268 testfen 'white promote to rook'\ | |
269 'rnbqkbRr/p1pppp1p/8/8/8/8/PpPPPP1P/R1BQKBNR b KQkq - 0 1'\ | |
270 'rnbqkb1r/p1ppppPp/8/8/8/8/PpPPPP1P/R1BQKBNR w KQkq - 0 1'\ | |
271 'g7g8R' | |
272 | |
273 testfen 'white promote to bishop'\ | |
274 'rnbqkbBr/p1pppp1p/8/8/8/8/PpPPPP1P/R1BQKBNR b KQkq - 0 1'\ | |
275 'rnbqkb1r/p1ppppPp/8/8/8/8/PpPPPP1P/R1BQKBNR w KQkq - 0 1'\ | |
276 'g7g8B' | |
277 | |
278 testfen 'white promote to knight'\ | |
279 'rnbqkbNr/p1pppp1p/8/8/8/8/PpPPPP1P/R1BQKBNR b KQkq - 0 1'\ | |
280 'rnbqkb1r/p1ppppPp/8/8/8/8/PpPPPP1P/R1BQKBNR w KQkq - 0 1'\ | |
281 'g7g8N' | |
282 | |
283 testfen 'white promote to knight (fixup lowercase to uppercase)'\ | |
284 'rnbqkbNr/p1pppp1p/8/8/8/8/PpPPPP1P/R1BQKBNR b KQkq - 0 1'\ | |
285 'rnbqkb1r/p1ppppPp/8/8/8/8/PpPPPP1P/R1BQKBNR w KQkq - 0 1'\ | |
286 'g7g8n' | |
287 | |
288 testfen 'black promote to queen'\ | |
289 'rnbqkb1r/p1ppppPp/8/8/8/8/P1PPPP1P/RqBQKBNR w KQkq - 0 2'\ | |
290 'rnbqkb1r/p1ppppPp/8/8/8/8/PpPPPP1P/R1BQKBNR b KQkq - 0 1'\ | |
291 'b2b1q' | |
292 | |
293 testfen 'black promote to rook'\ | |
294 'rnbqkb1r/p1ppppPp/8/8/8/8/P1PPPP1P/RrBQKBNR w KQkq - 0 2'\ | |
295 'rnbqkb1r/p1ppppPp/8/8/8/8/PpPPPP1P/R1BQKBNR b KQkq - 0 1'\ | |
296 'b2b1r' | |
297 | |
298 testfen 'black promote to bishop'\ | |
299 'rnbqkb1r/p1ppppPp/8/8/8/8/P1PPPP1P/RbBQKBNR w KQkq - 0 2'\ | |
300 'rnbqkb1r/p1ppppPp/8/8/8/8/PpPPPP1P/R1BQKBNR b KQkq - 0 1'\ | |
301 'b2b1b' | |
302 | |
303 testfen 'black promote to knight'\ | |
304 'rnbqkb1r/p1ppppPp/8/8/8/8/P1PPPP1P/RnBQKBNR w KQkq - 0 2'\ | |
305 'rnbqkb1r/p1ppppPp/8/8/8/8/PpPPPP1P/R1BQKBNR b KQkq - 0 1'\ | |
306 'b2b1n' | |
307 | |
308 testfen 'black promote to knight (fixup uppercase to lowercase)'\ | |
309 'rnbqkb1r/p1ppppPp/8/8/8/8/P1PPPP1P/RnBQKBNR w KQkq - 0 2'\ | |
310 'rnbqkb1r/p1ppppPp/8/8/8/8/PpPPPP1P/R1BQKBNR b KQkq - 0 1'\ | |
311 'b2b1N' | |
312 | |
313 testfen 'castling chess960'\ | |
314 'qnkr1r2/p1p1p2p/4nppN/1p6/1P1p4/3P2P1/PQPNPP1P/2RK2Rb w KQ - 4 … | |
315 'qnrkbnrb/pppppppp/8/8/8/8/PPPPPPPP/QNRKBNRB w KQkq - 0 1'\ | |
316 'd2d3 g7g6 e1c3 d7d5 c3h8 g8h8 b2b4 h8g8 g2g3 e8c6 f1e3 b7b5 a1e… | |
317 | |
318 testfen 'castling chess960'\ | |
319 'r2k1r2/1pb3pp/2ppqp2/p2np3/P3N1P1/1N1P1P2/1PPBP1QP/R4RK1 b kq -… | |
320 'r2k1r2/1pb3pp/2ppqp2/p2np3/P3N1P1/1N1P1P2/1PPBP1QP/R2K1R2 w KQk… | |
321 'd1g1' | |
322 | |
323 testfen 'test castles chess960'\ | |
324 'rk1r1n2/ppqp1bnp/2pbpp2/6p1/4P1P1/1PPN1P1P/P1QPBN1B/R4RK1 b kq … | |
325 'rk1r1n2/ppqp1bnp/2pbpp2/6p1/4P1P1/1PPN1P1P/P1QPBN1B/RK1R4 w KQk… | |
326 'b1g1' | |
327 | |
328 testfen 'castles chess 960'\ | |
329 'r4rk1/ppqp1bnp/2pbppn1/6p1/4P1P1/1PPN1P1P/P1QPBN1B/RK1R4 w KQ -… | |
330 'rk1r4/ppqp1bnp/2pbppn1/6p1/4P1P1/1PPN1P1P/P1QPBN1B/RK1R4 b KQkq… | |
331 'b8g8' | |
332 } | |
333 | |
334 tests_pgn() { | |
335 testpgn 'simple pawn move'\ | |
336 '2. ... e5'\ | |
337 'rnbqkbnr/ppp1pppp/8/3p4/3PP3/8/PPP2PPP/RNBQKBNR b KQkq - 0 2'\ | |
338 'e7e5' | |
339 | |
340 testpgn 'check: check with white pawn'\ | |
341 '4. gxf7+'\ | |
342 'rnbqkbnr/pppp1ppp/6P1/8/8/4p3/PPPPPP1P/RNBQKBNR w KQkq - 0 4'\ | |
343 'g6f7' | |
344 testpgn 'check: check with black pawn'\ | |
345 '4. ... exf2+'\ | |
346 'rnbqkbnr/pppp1ppP/8/8/8/4p3/PPPPPP1P/RNBQKBNR b KQkq - 0 4'\ | |
347 'e3f2' | |
348 | |
349 testpgn 'check: check with bishop'\ | |
350 '3. Bb5+'\ | |
351 'rnbqkbnr/ppp2ppp/8/3pp3/3PP3/8/PPP2PPP/RNBQKBNR w KQkq - 0 3'\ | |
352 'f1b5' | |
353 testpgn 'check: check with white queen, open file'\ | |
354 '6. Qe4+'\ | |
355 'rnbqkbnr/1ppp1pp1/p5Pp/8/3Q4/4P3/PPP1PP1P/RNB1KBNR w KQkq - 0 6… | |
356 'd4e4' | |
357 | |
358 testpgn 'check: check and takes with white knight'\ | |
359 '8. Nxc7+'\ | |
360 'rnbqkbn1/pppp1ppr/6P1/3N4/7p/4PN2/PPP1PP1P/R1BQKB1R w KQq - 2 8… | |
361 'd5c7' | |
362 | |
363 testpgn 'black moves, but the move from white is unknown, use "..."'\ | |
364 '1. ... e5'\ | |
365 'rnbqkbnr/pppppppp/8/8/3P4/8/PPP1PPPP/RNBQKBNR b KQkq - 0 1'\ | |
366 'e7e5' | |
367 | |
368 testpgn 'black moves with knight, ambigous move, needs file name'\ | |
369 '8. ... Nbd7'\ | |
370 'rn2kb1r/pp4pp/1qp1pn2/3p4/3P1B2/1P1BP3/P1P2P1P/RN1QK1NR b KQkq … | |
371 'b8d7' | |
372 | |
373 testpgn 'black moves with knight, non-ambigous move'\ | |
374 '8. ... Nd7'\ | |
375 'rn2kb1r/pp4pp/1qp1p3/3p4/3P1B2/1P1BP3/P1P2P1P/RN1QK1NR b KQkq -… | |
376 'b8d7' | |
377 | |
378 testpgn '2 queens, ambigous move, needs rank'\ | |
379 '8. Q3g3'\ | |
380 'rn2kb1r/pp4pp/1qp1p3/3p4/3P1B1Q/1P1BP2Q/P1P2P1P/RN2K1NR w KQkq … | |
381 'h3g3' | |
382 | |
383 testpgn 'king moves into range of king (illegal move), but played, so no… | |
384 '1. Kd5+'\ | |
385 '8/8/3k4/8/3K2R1/8/8/8 w - - 0 1'\ | |
386 'd4d5' | |
387 | |
388 # Long list of moves, checkmate at the end. | |
389 testpgn 'Long list of moves, compared to Lichess board analyzer'\ | |
390 '1. d4 d5 2. Bf4 c6 3. e3 Bf5 4. Bd3 e6 5. g4 Nf6 6. gxf5 Qb6 7.… | |
391 'startpos'\ | |
392 'd2d4 d7d5 c1f4 c7c6 e2e3 c8f5 f1d3 e7e6 g2g4 g8f6 g4f5 d8b6 f5e… | |
393 | |
394 testpgn 'Rook on same file, only one is legal, Rd7d1+ -> Rd1+'\ | |
395 '34. Rc6 Rd1+ 35. Rxd1 Rxd1#'\ | |
396 '3r2k1/3r2p1/R6p/4bp2/2P1p2P/7N/2P2PP1/2R3K1 w - - 1 34'\ | |
397 'a6c6 d7d1 c1d1 d8d1' | |
398 | |
399 testpgn 'black moves pawn en passant into check (not mate, can take en p… | |
400 '1. ... c5+'\ | |
401 'rnbqkbnr/p1pppppp/1p6/1P1PP3/2PKQ3/2PQQ3/P1PP1PPP/RNBQ1BNR b kq… | |
402 'c7c5' | |
403 | |
404 # NOTE: Lichess checks if en passant moves can actually be played, but t… | |
405 # reference specifies this doesn't necesarily have to be the case. | |
406 testpgn 'black moves pawn en passant into checkmate (cant take en passan… | |
407 '1. ... c5#'\ | |
408 'rnbqkbnr/p1p1pppp/1p6/3PP3/2PKQ3/2PQQ3/P1PP1PPP/RNBQ1BNR b kq -… | |
409 'c7c5' | |
410 | |
411 # check also if the en passant square is set (but it is not legal to pla… | |
412 testpgn 'black moves pawn en passant into checkmate (cant take en passan… | |
413 '1. ... c5#'\ | |
414 'rnbqkbnr/p1p1pppp/1p6/3PP3/2PKQ3/2PQQ3/P1PP1PPP/RNBQ1BNR b kq c… | |
415 'c7c5' | |
416 | |
417 testpgn 'Knights on the same rank can move to the same square'\ | |
418 '1. Nde5'\ | |
419 'rnbqkbnr/pppppppp/8/8/8/3N1N2/PPPPPPPP/R1BQKB1R w KQkq - 0 1'\ | |
420 'd3e5' | |
421 | |
422 testpgn 'Knights on the same rank can move to the same square, part 2'\ | |
423 '1. Nfe5'\ | |
424 'rnbqkbnr/pppppppp/8/8/8/3N1N2/PPPPPPPP/R1BQKB1R w KQkq - 0 1'\ | |
425 'f3e5' | |
426 | |
427 testpgn 'Knights on the same same file can move to the same square'\ | |
428 '1. N3c4'\ | |
429 'rnbqkbnr/pppppppp/8/4N3/8/4N3/PPPPPPPP/R1BQKB1R w KQkq - 0 1'\ | |
430 'e3c4' | |
431 | |
432 testpgn 'Knights on the same same file can move to the same square, part… | |
433 '1. N5c4'\ | |
434 'rnbqkbnr/pppppppp/8/4N3/8/4N3/PPPPPPPP/R1BQKB1R w KQkq - 0 1'\ | |
435 'e5c4' | |
436 | |
437 testpgn 'Knights on the same same file can move to the same square, part… | |
438 '1. N5g4'\ | |
439 'rnbqkbnr/pppppppp/8/4N3/8/4N3/PPPPPPPP/R1BQKB1R w KQkq - 0 1'\ | |
440 'e5g4' | |
441 | |
442 testpgn 'Rook on the same file can move to the same square'\ | |
443 '1. R3d4'\ | |
444 'rnbqkbnr/pppppppp/3R4/8/8/3R4/PPPPPPPP/1NBQKBN1 w kq - 0 1'\ | |
445 'd3d4' | |
446 | |
447 testpgn 'Rook on the same file can move to the same square, part 2'\ | |
448 '1. R6d4'\ | |
449 'rnbqkbnr/pppppppp/3R4/8/8/3R4/PPPPPPPP/1NBQKBN1 w kq - 0 1'\ | |
450 'd6d4' | |
451 | |
452 testpgn 'Rook on the same rank can move to the same square'\ | |
453 '1. Rge4'\ | |
454 'rnbqkbnr/pppppppp/8/8/2R3R1/8/PPPPPPPP/1NBQKBN1 w kq - 0 1'\ | |
455 'g4e4' | |
456 | |
457 testpgn 'Rook on the same rank can move to the same square, part 2'\ | |
458 '1. Rce4'\ | |
459 'rnbqkbnr/pppppppp/8/8/2R3R1/8/PPPPPPPP/1NBQKBN1 w kq - 0 1'\ | |
460 'c4e4' | |
461 | |
462 testpgn 'Rook on the same rank can take on the same square (with check),… | |
463 '1. Rgxe4+'\ | |
464 'rnbqkbnr/pppp1ppp/8/8/2R1p1R1/8/PPPPPPPP/1NBQKBN1 w kq - 0 1'\ | |
465 'g4e4' | |
466 | |
467 testpgn 'Rook on the same rank can take on the same square (with check),… | |
468 '1. Rcxe4+'\ | |
469 'rnbqkbnr/pppp1ppp/8/8/2R1p1R1/8/PPPPPPPP/1NBQKBN1 w kq - 0 1'\ | |
470 'c4e4' | |
471 | |
472 testpgn 'Knights on the same same file can take on the same square'\ | |
473 '1. N3xc4'\ | |
474 'rnbqkbnr/pppppppp/8/4N3/2p5/4N3/PPPPPPPP/R1BQKB1R w KQkq - 0 1'\ | |
475 'e3c4' | |
476 | |
477 testpgn 'Knights on the same same file can take on the same square, part… | |
478 '1. N5xc4'\ | |
479 'rnbqkbnr/pppppppp/8/4N3/2p5/4N3/PPPPPPPP/R1BQKB1R w KQkq - 0 1'\ | |
480 'e5c4' | |
481 | |
482 testpgn 'Knights on same files and ranks move to same square'\ | |
483 '1. Nf3e5'\ | |
484 'rnbqkbnr/pppNpNpp/8/8/8/3N1N2/PPPPPPPP/R1BQKB1R w KQkq - 0 1'\ | |
485 'f3e5' | |
486 | |
487 testpgn 'Knights on same files and ranks move to same square, part 2'\ | |
488 '1. Nd7e5'\ | |
489 'rnbqkbnr/pppNpNpp/8/8/8/3N1N2/PPPPPPPP/R1BQKB1R w KQkq - 0 1'\ | |
490 'd7e5' | |
491 | |
492 testpgn 'Knights on same files and ranks move to same square, part 3'\ | |
493 '1. Nd3e5'\ | |
494 'rnbqkbnr/pppNpNpp/8/8/8/3N1N2/PPPPPPPP/R1BQKB1R w KQkq - 0 1'\ | |
495 'd3e5' | |
496 | |
497 testpgn '4 knights that can move to the same square, but not on the same… | |
498 '1. Nfe5'\ | |
499 'rnbqkbnr/ppp1pNpp/2N5/8/6N1/3N4/PPPPPPPP/R1BQKB1R w KQkq - 0 1'\ | |
500 'f7e5' | |
501 | |
502 testpgn '4 knights that can move to the same square, but not on the same… | |
503 '1. Nce5'\ | |
504 'rnbqkbnr/ppp1pNpp/2N5/8/6N1/3N4/PPPPPPPP/R1BQKB1R w KQkq - 0 1'\ | |
505 'c6e5' | |
506 | |
507 testpgn '4 knights that can move to the same square, but not on the same… | |
508 '1. Nde5'\ | |
509 'rnbqkbnr/ppp1pNpp/2N5/8/6N1/3N4/PPPPPPPP/R1BQKB1R w KQkq - 0 1'\ | |
510 'd3e5' | |
511 | |
512 testpgn '4 knights that can move to the same square, but not on the same… | |
513 '1. Nge5'\ | |
514 'rnbqkbnr/ppp1pNpp/2N5/8/6N1/3N4/PPPPPPPP/R1BQKB1R w KQkq - 0 1'\ | |
515 'g4e5' | |
516 | |
517 testpgn 'Move bishop, 2 bishops can move to the same square'\ | |
518 '1. Bge4'\ | |
519 'rnbqkbnr/pppppppp/6B1/8/8/3B4/PPPP1PPP/RNBQK1NR w KQkq - 0 1'\ | |
520 'g6e4' | |
521 | |
522 testpgn 'Move bishop, 2 bishops can move to the same square, part 2'\ | |
523 '1. Bde4'\ | |
524 'rnbqkbnr/pppppppp/6B1/8/8/3B4/PPPP1PPP/RNBQK1NR w KQkq - 0 1'\ | |
525 'd3e4' | |
526 | |
527 testpgn 'Move bishop, 2 bishops can move to the same square, part 3'\ | |
528 '1. Bde4'\ | |
529 'rnbqkbnr/pppppppp/2B3B1/8/8/2BB4/PPPP1PPP/RNBQK1NR w KQkq - 0 1… | |
530 'd3e4' | |
531 | |
532 # white takes en passant | |
533 testpgn 'white takes en passant'\ | |
534 '3. dxe6'\ | |
535 'rnbqkbnr/pppp1pp1/8/3Pp2p/8/8/PPP1PPPP/RNBQKBNR w KQkq e6 0 3'\ | |
536 'd5e6' | |
537 # black takes en passant | |
538 testpgn 'black takes en passant'\ | |
539 '3. ... hxg3'\ | |
540 'rnbqkbnr/ppppppp1/8/8/3P2Pp/4P3/PPP2P1P/RNBQKBNR b KQkq g3 0 3'\ | |
541 'h4g3' | |
542 | |
543 # NOTE: this is ambigous, but this is not dc6, because the en passant sq… | |
544 testpgn 'white is checkmated (en passant square is not set), do not remo… | |
545 '1. c6'\ | |
546 'rnbqkbnr/p2ppppp/1p6/1PpPP3/2PKQ3/2PQQ3/P1PP1PPP/RNBQ1BNR w kq … | |
547 'd5c6' | |
548 | |
549 testpgn 'white is not checkmated (en passant square is set and can be pl… | |
550 '1. dxc6'\ | |
551 'rnbqkbnr/p2ppppp/1p6/1PpPP3/2PKQ3/2PQQ3/P1PP1PPP/RNBQ1BNR w kq … | |
552 'd5c6' | |
553 | |
554 testpgn 'Smothered mate, mate in 3'\ | |
555 '1. Nh6+ Kh8 2. Qg8+ Rxg8 3. Nf7#'\ | |
556 '5rk1/5Npp/8/3Q4/8/8/8/K7 w - - 0 1'\ | |
557 'f7h6 g8h8 d5g8 f8g8 h6f7' | |
558 | |
559 testpgn 'white is in check, defend with knight and checkmate'\ | |
560 '1. Ng1#'\ | |
561 '8/7k/8/8/8/7N/6RR/3r3K w - - 0 1'\ | |
562 'h3g1' | |
563 | |
564 testpgn 'Black checks white (blunder), white defends with knight and che… | |
565 '1. ... Rd1+ 2. Ng1#'\ | |
566 '8/7k/8/8/3r4/7N/6RR/7K b - - 0 1'\ | |
567 'd4d1 h3g1' | |
568 | |
569 testpgn 'Test a longer sequence of moves, promotion, castling, etc'\ | |
570 '1. d4 d5 2. Bf4 c6 3. e3 Bf5 4. Bd3 e6 5. g4 Nf6 6. gxf5 Qb6 7.… | |
571 'startpos'\ | |
572 'd2d4 d7d5 c1f4 c7c6 e2e3 c8f5 f1d3 e7e6 g2g4 g8f6 g4f5 d8b6 f5e… | |
573 | |
574 # test castling chess 960 | |
575 testpgn 'Castling chess960'\ | |
576 '1. d3 g6 2. Bc3 d5 3. Bxh8 Rxh8 4. b4 Rg8 5. g3 Bc6 6. Ne3 b5 7… | |
577 'qnrkbnrb/pppppppp/8/8/8/8/PPPPPPPP/QNRKBNRB w KQkq - 0 1'\ | |
578 'd2d3 g7g6 e1c3 d7d5 c3h8 g8h8 b2b4 h8g8 g2g3 e8c6 f1e3 b7b5 a1e… | |
579 | |
580 testpgn 'PGN chess960'\ | |
581 '1. d3 g6 2. Bc3 d5 3. Bxh8 Rxh8 4. b4 Rg8 5. g3 Bc6 6. Ne3 b5 7… | |
582 'qnrkbnrb/pppppppp/8/8/8/8/PPPPPPPP/QNRKBNRB w KQkq - 0 1'\ | |
583 'd2d3 g7g6 e1c3 d7d5 c3h8 g8h8 b2b4 h8g8 g2g3 e8c6 f1e3 b7b5 a1e… | |
584 | |
585 testpgn 'castling chess960'\ | |
586 '1. d3 c6 2. Bd2 a5 3. a4 f6 4. Ba2 Bf7 5. Bxf7 Qxf7 6. Nb3 Bc7 … | |
587 'rbnkbrqn/pppppppp/8/8/8/8/PPPPPPPP/RBNKBRQN w KQkq - 0 1'\ | |
588 'd2d3 c7c6 e1d2 a7a5 a2a4 f7f6 b1a2 e8f7 a2f7 g8f7 c1b3 b8c7 g2g… | |
589 | |
590 testpgn 'test castles chess960'\ | |
591 '14. O-O'\ | |
592 'r2k1r2/1pb3pp/2ppqp2/p2np3/P3N1P1/1N1P1P2/1PPBP1QP/R2K1R2 w KQk… | |
593 'd1g1' | |
594 | |
595 testpgn 'test castles chess960'\ | |
596 '1. O-O'\ | |
597 'rk1r1n2/ppqp1bnp/2pbpp2/6p1/4P1P1/1PPN1P1P/P1QPBN1B/RK1R4 w KQk… | |
598 'b1g1' | |
599 | |
600 testpgn 'castles chess 960'\ | |
601 '1. ... O-O'\ | |
602 'rk1r4/ppqp1bnp/2pbppn1/6p1/4P1P1/1PPN1P1P/P1QPBN1B/RK1R4 b KQkq… | |
603 'b8g8' | |
604 | |
605 testpgn 'test file/rank for pawn move (was bug)'\ | |
606 '7. gxf3 Qh4#'\ | |
607 'rn1qk1nr/ppp2ppp/3b4/8/8/2N2b2/PPPPP1PP/R1BQKB1R w KQkq - 0 7'\ | |
608 'g2f3 d8h4' | |
609 | |
610 testpgn 'test en passant check (was bug)'\ | |
611 '35. Kg4 h5+ 36. gxh6 f5+ 37. Kg5 Rg3#'\ | |
612 '8/2R2p1p/4k1p1/6P1/5P1P/r5K1/8/8 w - - 1 35'\ | |
613 'g3g4 h7h5 g5h6 f7f5 g4g5 a3g3' | |
614 | |
615 testpgn 'test ambigous queen move'\ | |
616 '1. Qf3d5'\ | |
617 '8/1Q3Q2/8/8/8/1Q3Q2/8/3K2k1 w - - 0 1'\ | |
618 'f3d5' | |
619 | |
620 testpgn 'test ambigous queen move 2'\ | |
621 '1. Q7b5'\ | |
622 '8/1Q3Q2/8/8/8/1Q3Q2/8/3K2k1 w - - 0 1'\ | |
623 'b7b5' | |
624 | |
625 testpgn 'test ambigous queen move 3'\ | |
626 '1. Qfe7'\ | |
627 '8/1Q3Q2/8/8/8/1Q3Q2/8/3K2k1 w - - 0 1'\ | |
628 'f7e7' | |
629 } | |
630 | |
631 tests_fen | |
632 tests_pgn | |
633 | |
634 # Test all castle positions for both sides for chess960 | |
635 # this includes classical positions. | |
636 | |
637 IFS=" " | |
638 while read -r kingside f kingpos rpos; do | |
639 # test last part of the side that is tested. | |
640 # 5RK1 - kingside | |
641 # 2KR4 - queenside | |
642 | |
643 # lowercase for black | |
644 fb="$(printf '%s' "$f" | tr '[:upper:]' '[:lower:]')" | |
645 | |
646 # test white kingside or queenside castle. | |
647 move="${kingpos}1${rpos}1" | |
648 if test "$kingside" = "1"; then | |
649 fullfen="${fb}/pppppppp/8/8/8/8/PPPPPPPP/${f} w Kk - 0 1" | |
650 expect="${fb}/pppppppp/8/8/8/8/PPPPPPPP/5RK1 b k - 1 1" | |
651 else | |
652 fullfen="${fb}/pppppppp/8/8/8/8/PPPPPPPP/${f} w Qq - 0 1" | |
653 expect="${fb}/pppppppp/8/8/8/8/PPPPPPPP/2KR4 b q - 1 1" | |
654 move="${kingpos}1${rpos}1" | |
655 fi | |
656 testfen "Chess960 position, $fullfen (white), $move, kingside? $… | |
657 "$expect" \ | |
658 "$fullfen" \ | |
659 "$move" | |
660 | |
661 if test "$kingside" = "1"; then | |
662 expect="1. O-O" | |
663 else | |
664 expect="1. O-O-O" | |
665 fi | |
666 testpgn "Chess960 position, $fullfen (white), $move" \ | |
667 "$expect" \ | |
668 "$fullfen" \ | |
669 "$move" | |
670 | |
671 # test black kingside or queenside castle. | |
672 move="${kingpos}8${rpos}8" | |
673 if test "$kingside" = "1"; then | |
674 fullfen="${fb}/pppppppp/8/8/8/8/PPPPPPPP/${f} b Kk - 0 1" | |
675 expect="5rk1/pppppppp/8/8/8/8/PPPPPPPP/${f} w K - 1 2" | |
676 else | |
677 fullfen="${fb}/pppppppp/8/8/8/8/PPPPPPPP/${f} b Qq - 0 1" | |
678 expect="2kr4/pppppppp/8/8/8/8/PPPPPPPP/${f} w Q - 1 2" | |
679 fi | |
680 testfen "Chess960 position, $fullfen (black), $move, kingside? $… | |
681 "$expect" \ | |
682 "$fullfen" \ | |
683 "$move" | |
684 | |
685 if test "$kingside" = "1"; then | |
686 expect="1. ... O-O" | |
687 else | |
688 expect="1. ... O-O-O" | |
689 fi | |
690 testpgn "Chess960 position, $fullfen (black), $move" \ | |
691 "$expect" \ | |
692 "$fullfen" \ | |
693 "$move" | |
694 done <<! | |
695 0 1R1K4 d b | |
696 0 1R2K3 e b | |
697 0 1R3K2 f b | |
698 0 1R4K1 g b | |
699 0 1RK5 c b | |
700 0 2R1K3 e c | |
701 0 2R2K2 f c | |
702 0 2R3K1 g c | |
703 0 2RK4 d c | |
704 0 3R1K2 f d | |
705 0 3R2K1 g d | |
706 0 3RK3 e d | |
707 0 4R1K1 g e | |
708 0 4RK2 f e | |
709 0 5RK1 g f | |
710 0 R1K5 c a | |
711 0 R2K4 d a | |
712 0 R3K3 e a | |
713 0 R4K2 f a | |
714 0 R5K1 g a | |
715 0 RK6 b a | |
716 1 1K1R4 b d | |
717 1 1K2R3 b e | |
718 1 1K3R2 b f | |
719 1 1K4R1 b g | |
720 1 1K5R b h | |
721 1 1KR5 b c | |
722 1 2K1R3 c e | |
723 1 2K2R2 c f | |
724 1 2K3R1 c g | |
725 1 2K4R c h | |
726 1 2KR4 c d | |
727 1 3K1R2 d f | |
728 1 3K2R1 d g | |
729 1 3K3R d h | |
730 1 3KR3 d e | |
731 1 4K1R1 e g | |
732 1 4K2R e h | |
733 1 4KR2 e f | |
734 1 5K1R f h | |
735 1 5KR1 f g | |
736 1 6KR g h | |
737 ! | |
738 | |
739 if test "$statuscode" = "1"; then | |
740 echo "$failed tests failed" | |
741 else | |
742 echo "All tests OK" | |
743 fi | |
744 | |
745 exit "$statuscode" |