A chess library for Gleam

Implement `state` function

+48 -1
+11 -1
src/starfish.gleam
··· 1 + import gleam/bool 1 2 import gleam/result 3 + import starfish/internal/board 2 4 import starfish/internal/game 3 5 import starfish/internal/move 4 6 ··· 175 177 FiftyMoves 176 178 } 177 179 180 + /// Returns the current game state: A win, draw or neither. 178 181 pub fn state(game: Game) -> GameState { 179 - todo 182 + // TODO: Check for insufficient material and threefold repetition 183 + use <- bool.guard(game.half_moves >= 50, Draw(FiftyMoves)) 184 + use <- bool.guard(move.any_legal(game), Continue) 185 + use <- bool.guard(!game.attack_information.in_check, Draw(Stalemate)) 186 + case game.to_move { 187 + board.Black -> WhiteWin 188 + board.White -> BlackWin 189 + } 180 190 }
+15
src/starfish/internal/move.gleam
··· 33 33 } 34 34 } 35 35 36 + /// Checks whether any legal moves are possible without calculating every legal 37 + /// move beforehand. 38 + pub fn any_legal(game: Game) -> Bool { 39 + use any, square, position <- iv.index_fold(game.board, False) 40 + // If we've found legal moves already, we already know that there are some, 41 + // so no need to check for more. 42 + use <- bool.guard(any, any) 43 + 44 + case square { 45 + board.Occupied(piece:, colour:) if colour == game.to_move -> 46 + moves_for_piece(game, position, piece, []) != [] 47 + board.Occupied(_, _) | board.Empty -> any 48 + } 49 + } 50 + 36 51 fn move_is_valid_with_pins( 37 52 from: Int, 38 53 to: Int,
+22
test/starfish_test.gleam
··· 112 112 let assert Error(Nil) = starfish.parse_long_algebraic_notation("Bxe4") 113 113 } 114 114 115 + pub fn state_test() { 116 + assert "8/8/8/1q6/1K6/3q4/8/8 w - - 0 1" 117 + |> starfish.from_fen 118 + |> starfish.state 119 + == starfish.BlackWin 120 + 121 + assert "8/1B6/3np3/4k3/8/2B5/5R2/8 b - - 0 1" 122 + |> starfish.from_fen 123 + |> starfish.state 124 + == starfish.WhiteWin 125 + 126 + assert "8/8/8/1q1p2pp/8/KP3r2/5r2/8 w - - 0 1" 127 + |> starfish.from_fen 128 + |> starfish.state 129 + == starfish.Draw(starfish.Stalemate) 130 + 131 + assert "8/8/1RK5/8/7N/3rp3/3kb3/8 w - - 50 82" 132 + |> starfish.from_fen 133 + |> starfish.state 134 + == starfish.Draw(starfish.FiftyMoves) 135 + } 136 + 115 137 fn perft_all(fen: String, expected: List(Int)) { 116 138 expected 117 139 |> list.index_map(fn(expected, index) { perft(fen, index + 1, expected) })