basic admin endgame view and add (#3)
Reviewed-on: #3
This commit was merged in pull request #3.
This commit is contained in:
@@ -0,0 +1,145 @@
|
||||
defmodule Chesstrainer.Game do
|
||||
@moduledoc """
|
||||
Game related functions
|
||||
"""
|
||||
alias Chesstrainer.Endgames
|
||||
|
||||
@type game_type :: :endgame
|
||||
@type square :: {atom(), pos_integer()}
|
||||
@type move :: {square, square}
|
||||
@type colors :: :white | :black
|
||||
@type game_state :: :continue | :loss | :draw
|
||||
@type result :: :win | :draw | :loss
|
||||
|
||||
@type t :: %__MODULE__{
|
||||
player_color: colors,
|
||||
board: map(),
|
||||
active_color: colors,
|
||||
castling: list(),
|
||||
en_passant: term() | nil,
|
||||
moves: list(),
|
||||
halfmove_clock: non_neg_integer(),
|
||||
fullmove_clock: non_neg_integer(),
|
||||
captures: list(),
|
||||
check: term() | nil,
|
||||
result: result,
|
||||
pgn: String.t() | nil,
|
||||
orientation: colors,
|
||||
move_from_square: square,
|
||||
move_to_square: square,
|
||||
game_type: game_type,
|
||||
fen: String.t(),
|
||||
tablebase: term(),
|
||||
game_state: game_state
|
||||
}
|
||||
|
||||
defstruct board: %{},
|
||||
player_color: :white,
|
||||
active_color: :white,
|
||||
castling: [],
|
||||
en_passant: nil,
|
||||
moves: [],
|
||||
halfmove_clock: 0,
|
||||
fullmove_clock: 0,
|
||||
captures: [],
|
||||
check: nil,
|
||||
result: nil,
|
||||
pgn: nil,
|
||||
orientation: :white,
|
||||
move_from_square: nil,
|
||||
move_to_square: nil,
|
||||
game_type: nil,
|
||||
fen: nil,
|
||||
tablebase: nil,
|
||||
game_state: :continue
|
||||
|
||||
@doc """
|
||||
Builds a `%ChessTrainer.Game{}` from a FEN string.
|
||||
|
||||
On success, returns `{:ok, game}` with the parsed board state.
|
||||
|
||||
If the FEN string is invalid, `Chex.Parser.FEN.parse/1` raises a
|
||||
`MatchError`. This function rescues that exception and returns
|
||||
`{:error, :invalid_fen, game}`, where `game` is a fallback position
|
||||
containing only kings.
|
||||
|
||||
This is a bad implementation in the Chex libary and should be fixed at our fork:
|
||||
https://github.com/therealowenrees/chex
|
||||
|
||||
We should return something like{:ok, game} | {:error | :invalid_fen}
|
||||
|
||||
## Examples
|
||||
|
||||
iex> ChessTrainer.Game.game_from_fen("valid fen", :endgame)
|
||||
{:ok, %ChessTrainer.Game{}}
|
||||
|
||||
iex> ChessTrainer.Game.game_from_fen("invalid fen", :endgame)
|
||||
{:error, :invalid_fen, %ChessTrainer.Game{}}
|
||||
|
||||
"""
|
||||
@dialyzer {:nowarn_function, game_from_fen: 2}
|
||||
@spec game_from_fen(String.t(), game_type()) :: {:ok, t()} | {:error, :invalid_fen, t()}
|
||||
def game_from_fen(fen, game_type) do
|
||||
try do
|
||||
{:ok, %Chex.Game{} = chex_game} = Chex.Parser.FEN.parse(fen)
|
||||
|
||||
game = %__MODULE__{
|
||||
board: chex_game.board,
|
||||
player_color: chex_game.active_color,
|
||||
active_color: chex_game.active_color,
|
||||
castling: chex_game.castling,
|
||||
en_passant: chex_game.en_passant,
|
||||
moves: chex_game.moves,
|
||||
halfmove_clock: chex_game.halfmove_clock,
|
||||
fullmove_clock: chex_game.fullmove_clock,
|
||||
captures: chex_game.captures,
|
||||
check: chex_game.check,
|
||||
result: chex_game.result,
|
||||
pgn: chex_game.pgn,
|
||||
orientation: chex_game.active_color,
|
||||
move_from_square: nil,
|
||||
move_to_square: nil,
|
||||
game_type: game_type,
|
||||
fen: fen,
|
||||
game_state: :continue,
|
||||
tablebase:
|
||||
if game_type === :endgame do
|
||||
Endgames.Tablebase.new(fen)
|
||||
else
|
||||
nil
|
||||
end
|
||||
}
|
||||
|
||||
{:ok, game}
|
||||
rescue
|
||||
# if a MatchError error is raised, then return a game with only kings on the board
|
||||
MatchError ->
|
||||
game = %__MODULE__{
|
||||
board: %{
|
||||
{:e, 1} => {:king, :white, {:e, 1}},
|
||||
{:e, 8} => {:king, :black, {:e, 8}}
|
||||
},
|
||||
player_color: :white,
|
||||
active_color: :white,
|
||||
castling: [],
|
||||
en_passant: nil,
|
||||
moves: [],
|
||||
halfmove_clock: 0,
|
||||
fullmove_clock: 0,
|
||||
captures: nil,
|
||||
check: nil,
|
||||
result: :draw,
|
||||
pgn: nil,
|
||||
orientation: :white,
|
||||
move_from_square: nil,
|
||||
move_to_square: nil,
|
||||
game_type: :endgame,
|
||||
fen: "4k3/8/8/8/8/8/8/4K3 w - - 0 1",
|
||||
game_state: :draw,
|
||||
tablebase: nil
|
||||
}
|
||||
|
||||
{:error, :invalid_fen, game}
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user