src/chess/king.c

changeset 216
d0c3d3016650
parent 195
27d02ccb0cef
equal deleted inserted replaced
215:d20887f0e8b3 216:d0c3d3016650
28 */ 28 */
29 29
30 #include "rules.h" 30 #include "rules.h"
31 #include "king.h" 31 #include "king.h"
32 32
33 static bool king_castling_chkmoved(
34 const GameState *gamestate, File file, Rank rank) {
35
36 for (unsigned i = 0; i < gamestate->movecount; i++) {
37 if (gamestate->moves[i].fromfile == file
38 && gamestate->moves[i].fromrank == rank) {
39 return true;
40 }
41 }
42
43 return false;
44 }
45
46 bool king_chkrules(const GameState *gamestate, const Move* move) { 33 bool king_chkrules(const GameState *gamestate, const Move* move) {
47 if (abs(move->torank - move->fromrank) <= 1 && 34 if (abs(move->torank - move->fromrank) <= 1 &&
48 abs(move->tofile - move->fromfile) <= 1) { 35 abs(move->tofile - move->fromfile) <= 1) {
49 return true; 36 return true;
37 } else if (move->fromrank == move->torank) {
38 /* castling */
39 Rank backrank;
40 bool k_allowed, q_allowed;
41 if (piece_color(move->piece) == WHITE) {
42 backrank = rankidx('1');
43 k_allowed = !gamestate->castling.K;
44 q_allowed = !gamestate->castling.Q;
45 } else {
46 backrank = rankidx('8');
47 k_allowed = !gamestate->castling.k;
48 q_allowed = !gamestate->castling.q;
49 }
50 bool castle_q = false, castle_k = false;
51 if (move->fromrank == backrank && move->fromfile == fileidx('e')) {
52 castle_q = move->tofile == fileidx('c');
53 castle_k = move->tofile == fileidx('g');
54 }
55 /* note that here we do not consider threats!
56 * that is what king_isblocked() does */
57 return (castle_q && q_allowed) || (castle_k && k_allowed);
50 } else { 58 } else {
51 /* castling */ 59 return false;
52 if (move->fromrank == move->torank &&
53 move->fromrank == (piece_color(move->piece) == WHITE ? 0 : 7) &&
54 move->fromfile == fileidx('e') &&
55 (move->tofile == fileidx('c') || move->tofile == fileidx('g'))) {
56
57 return !king_castling_chkmoved(gamestate,
58 move->fromfile, move->fromrank) &&
59 !king_castling_chkmoved(gamestate,
60 move->tofile == fileidx('c') ? 0 : 7, move->fromrank);
61 } else {
62 return false;
63 }
64 } 60 }
65 } 61 }
66 62
67 bool king_isblocked(const GameState *gamestate, const Move *move) { 63 bool king_isblocked(const GameState *gamestate, const Move *move) {
68
69 Color op_color = opponent_color(piece_color(move->piece));
70
71 /* being in check does not "block" the king, so don't test it here */
72 bool blocked = false;
73
74 /* just test, if castling move is blocked */ 64 /* just test, if castling move is blocked */
75 if (abs(move->tofile - move->fromfile) == 2) { 65 if (abs(move->tofile - move->fromfile) == 2) {
76 if (move->tofile == fileidx('c')) { 66 if (move->tofile == fileidx('c')) {
77 blocked |= gamestate->board[move->torank][fileidx('b')]; 67 /* check if rook can travel the queen-side */
68 if (gamestate->board[move->torank][fileidx('b')]) {
69 return true;
70 }
78 } 71 }
72 /* check if new field for the rook is free */
79 File midfile = (move->tofile+move->fromfile)/2; 73 File midfile = (move->tofile+move->fromfile)/2;
80 bool incheck = false; 74 if (gamestate->board[move->torank][midfile]) {
81 if (gamestate->movecount > 0) { 75 return true;
82 incheck = is_check_position(gamestate);
83 } 76 }
84 blocked |= incheck || gamestate->board[move->torank][midfile] || 77 /* check if the king or the target field for the rook is threatened */
85 is_covered(gamestate, midfile, move->torank, op_color); 78 if (is_check_position(gamestate) || is_covered(gamestate,
79 midfile, move->torank, opponent_color(piece_color(move->piece)))) {
80 return true;
81 }
86 } 82 }
87 83 return false;
88 return blocked;
89 } 84 }
90 85
91 size_t king_moves(const GameState *gamestate, 86 size_t king_moves(const GameState *gamestate,
92 Color c, File f, Rank r, Move *moves) { 87 Color c, File f, Rank r, Move *moves) {
93 88

mercurial