defmodule DndCharacter do @type t :: %__MODULE__{ strength: pos_integer(), dexterity: pos_integer(), constitution: pos_integer(), intelligence: pos_integer(), wisdom: pos_integer(), charisma: pos_integer(), hitpoints: pos_integer() } @abilities ~w(strength dexterity constitution intelligence wisdom charisma hitpoints)a defstruct @abilities @spec modifier(pos_integer()) :: integer() def modifier(score), do: floor((score - 10) / 2) @spec ability :: pos_integer() def ability do 0..2 |> Enum.map(fn _x -> Enum.random(1..6) end) |> Enum.sort(:desc) |> Enum.sum() end @spec character :: t() def character do for ability <- @abilities, reduce: %{} do acc -> Map.put(acc, ability, ability()) end |> then(&Map.put(&1, :hitpoints, 10 + modifier(Map.get(&1, :constitution)))) |> then(&struct(__MODULE__, &1)) end end