mirror of
https://github.com/TheRealOwenRees/chess-endgame-trainer.git
synced 2026-09-19 11:03:52 +00:00
* create endgame play section * add cache tests * normalise FENs - trim and fuill move to 1 on addition * remove svg on root and allow navbar to exist across all pages * update nav items
47 lines
1.4 KiB
Elixir
47 lines
1.4 KiB
Elixir
defmodule Chesstrainer.FEN do
|
|
@spec color_from_fen(String.t()) :: :white | :black | nil
|
|
def color_from_fen(fen) do
|
|
fen
|
|
|> String.split(" ")
|
|
|> Enum.at(1)
|
|
|> color_initial_to_color_atom()
|
|
end
|
|
|
|
@doc """
|
|
Normalizes a FEN string for storage.
|
|
|
|
Trims surrounding whitespace and rewrites a fullmove number of `"0"` to
|
|
`"1"`. The fullmove rewrite is a chess.js-compatibility fix — chess.js
|
|
rejects fullmove `0` as invalid even though many board editors default
|
|
to it. Other FEN fields are left untouched; structural errors are
|
|
surfaced by the Endgame changeset, not silently masked here.
|
|
|
|
## Examples
|
|
|
|
iex> Chesstrainer.FEN.normalize(" 8/8/3k4/8/8/3K1R2/8/8 w - - 0 0\\n ")
|
|
"8/8/3k4/8/8/3K1R2/8/8 w - - 0 1"
|
|
|
|
iex> Chesstrainer.FEN.normalize("8/8/3k4/8/8/3K1R2/8/8 w - - 0 5")
|
|
"8/8/3k4/8/8/3K1R2/8/8 w - - 0 5"
|
|
|
|
iex> Chesstrainer.FEN.normalize("not a fen")
|
|
"not a fen"
|
|
"""
|
|
@spec normalize(String.t()) :: String.t()
|
|
def normalize(fen) when is_binary(fen) do
|
|
trimmed = String.trim(fen)
|
|
|
|
case String.split(trimmed, " ") do
|
|
[board, active, castling, en_passant, halfmove, "0"] ->
|
|
Enum.join([board, active, castling, en_passant, halfmove, "1"], " ")
|
|
|
|
_ ->
|
|
trimmed
|
|
end
|
|
end
|
|
|
|
defp color_initial_to_color_atom("b"), do: :black
|
|
defp color_initial_to_color_atom("w"), do: :white
|
|
defp color_initial_to_color_atom(_), do: nil
|
|
end
|