A chess library for Gleam

Detect draw by insufficient material

+28 -9
+4 -1
src/starfish.gleam
··· 196 196 197 197 /// Returns the current game state: A win, draw or neither. 198 198 pub fn state(game: Game) -> GameState { 199 - // TODO: Check for insufficient material 200 199 use <- bool.guard(game.half_moves >= 50, Draw(FiftyMoves)) 200 + use <- bool.guard( 201 + game.is_insufficient_material(game), 202 + Draw(InsufficientMaterial), 203 + ) 201 204 use <- bool.guard( 202 205 game.is_threefold_repetition(game), 203 206 Draw(ThreefoldRepetition),
+12
src/starfish/internal/game.gleam
··· 463 463 } 464 464 } 465 465 466 + pub fn is_insufficient_material(game: Game) -> Bool { 467 + { 468 + game.black_pieces.pawn_material == 0 && game.white_pieces.pawn_material == 0 469 + } 470 + && { 471 + game.black_pieces.non_pawn_material == board.bishop_value 472 + || game.black_pieces.non_pawn_material == board.knight_value 473 + || game.white_pieces.non_pawn_material == board.bishop_value 474 + || game.white_pieces.non_pawn_material == board.knight_value 475 + } 476 + } 477 + 466 478 pub fn is_threefold_repetition(game: Game) -> Bool { 467 479 is_threefold_repetition_loop( 468 480 game.previous_positions,
+4 -8
src/starfish/internal/search.gleam
··· 161 161 SearchResult(0, cached_positions, hash.Exact, False), 162 162 ) 163 163 164 - // If we have reached fifty moves, the game is already a draw, so there's no 164 + // Check for draw conditions. If it's a draw, the game is over so there's no 165 165 // point searching further. 166 166 use <- bool.guard( 167 - game.half_moves >= 50, 168 - SearchResult(0, cached_positions, hash.Exact, True), 169 - ) 170 - 171 - // Threefold repetition is also a draw 172 - use <- bool.guard( 173 - game.is_threefold_repetition(game), 167 + game.half_moves >= 50 168 + || game.is_threefold_repetition(game) 169 + || game.is_insufficient_material(game), 174 170 SearchResult(0, cached_positions, hash.Exact, True), 175 171 ) 176 172
+8
test/starfish_test.gleam
··· 336 336 |> apply_move("Nb8") 337 337 |> starfish.state 338 338 == starfish.Draw(starfish.ThreefoldRepetition) 339 + 340 + assert starfish.from_fen("8/3k4/4n3/8/4N1P1/5K2/8/8 w - - 0 1") 341 + |> starfish.state 342 + == starfish.Continue 343 + 344 + assert starfish.from_fen("8/3k4/4n3/8/4N3/5K2/8/8 w - - 0 1") 345 + |> starfish.state 346 + == starfish.Draw(starfish.InsufficientMaterial) 339 347 } 340 348 341 349 fn perft_all(fen: String, expected: List(Int)) {