--- a/src/chess/rules.h Fri Aug 21 16:08:50 2026 +0200 +++ b/src/chess/rules.h Fri Aug 21 17:04:43 2026 +0200 @@ -144,6 +144,8 @@ bool checkmate; bool stalemate; bool threefold; + /** drawn due to insufficient material on both sides */ + bool nomaterial; /** flag is only set when players agreed on remis */ bool remis; bool wresign; @@ -196,7 +198,8 @@ } static inline bool is_game_drawn(const GameState *gamestate) { - return gamestate->threefold || gamestate->stalemate || gamestate->remis; + return gamestate->threefold || gamestate->stalemate + || gamestate->nomaterial || gamestate->remis; } static inline bool is_game_running(const GameState *gamestate) { @@ -208,6 +211,10 @@ return gamestate->moves[gamestate->movecount - 1].check; } +static inline Color field_color(Row r, File f) { + return (r + f) % 2 == 0 ? BLACK : WHITE; +} + /** * Initializes a game state and prepares the chess board. * @param gamestate the game state to initialize @@ -600,5 +607,19 @@ */ bool check_threefold_repetition(const GameState *gamestate); +/** + * Checks if neither side has enough material left to win the game. + * + * Returns true if for both players one of the following three cases are true: + * - they have only the king left + * - they have a king + knight and the opponent has king + queens + * - they have a king + bishop and the opponent doesn't have + * opposite color bishops or knights or pawns + * + * @param gamestate the current game state + * @return true if neither side can win due to insufficient material + */ +bool check_no_material(const GameState *gamestate); + #endif /* RULES_H */