Tue, 25 Aug 2026 18:59:18 +0200
rename Row to Rank
+ fix increase type safety where we overlooked it before
relates to #956
/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 2016 Mike Becker. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * */ #include "rules.h" #include "king.h" static bool king_castling_chkmoved( const GameState *gamestate, Rank rank, File file) { for (unsigned i = 0; i < gamestate->movecount; i++) { if (gamestate->moves[i].fromfile == file && gamestate->moves[i].fromrank == rank) { return true; } } return false; } bool king_chkrules(const GameState *gamestate, const Move* move) { if (abs(move->torank - move->fromrank) <= 1 && abs(move->tofile - move->fromfile) <= 1) { return true; } else { /* castling */ if (move->fromrank == move->torank && move->fromrank == (piece_color(move->piece) == WHITE ? 0 : 7) && move->fromfile == fileidx('e') && (move->tofile == fileidx('c') || move->tofile == fileidx('g'))) { return !king_castling_chkmoved(gamestate, move->fromrank, move->fromfile) && !king_castling_chkmoved(gamestate, move->fromrank, move->tofile == fileidx('c') ? 0 : 7); } else { return false; } } } bool king_isblocked(const GameState *gamestate, const Move *move) { Color op_color = opponent_color(piece_color(move->piece)); /* being in check does not "block" the king, so don't test it here */ bool blocked = false; /* just test, if castling move is blocked */ if (abs(move->tofile - move->fromfile) == 2) { if (move->tofile == fileidx('c')) { blocked |= gamestate->board[move->torank][fileidx('b')]; } File midfile = (move->tofile+move->fromfile)/2; bool incheck = false; if (gamestate->movecount > 0) { incheck = is_check_position(gamestate); } blocked |= incheck || gamestate->board[move->torank][midfile] || is_covered(gamestate, move->torank, midfile, op_color); } return blocked; } size_t king_moves(const GameState *gamestate, Color c, Rank r, File f, Move *moves) { size_t count = 0; Piece king = mkpiece(KING, c); for (int dr = -1 ; dr <= 1 ; dr++) { for (int df = -1 ; df <= 1 ; df++) { if (dr == 0 && df == 0) { continue; } Rank torank = r + dr; File tofile = f + df; if (!isidx(torank) || !isidx(tofile)) { continue; } moves[count] = (Move){0}; moves[count].piece = king; moves[count].fromrank = r; moves[count].fromfile = f; moves[count].torank = torank; moves[count].tofile = tofile; moves[count].capture = piece_at(gamestate, torank, tofile) != 0; count++; } } Rank homerank = c == WHITE ? 0 : 7; if (r == homerank && f == fileidx('e')) { moves[count] = (Move){0}; moves[count].piece = king; moves[count].fromrank = r; moves[count].fromfile = f; moves[count].torank = r; moves[count].tofile = fileidx('c'); count++; moves[count] = (Move){0}; moves[count].piece = king; moves[count].fromrank = r; moves[count].fromfile = f; moves[count].torank = r; moves[count].tofile = fileidx('g'); count++; } return count; }