 
   @type coord :: Grid.coord | {non_neg_integer, String.t} | String.t
   @type seed :: {integer, integer, integer}
+  @type board_options :: [size: pos_integer, seed: seed, bomb_count: pos_integer]
   @type t :: %{grid: Grid.t, seed: seed}
 
   @default_size 15
-  @bomb_count 22
+  @default_bomb_count 22
 
   @doc """
   Starts an agent linked to the current process, storing the state of a new

      iex> {:ok, pid} = LexibombServer.Board.start_link
      iex> is_pid(pid)
      true
  """
  @spec start_link :: Agent.on_start
  def start_link do
    start_link(new)
  end

  @doc """
  Starts an agent linked to the current process, storing the state of the given
  `board`.
  """
  @spec start_link(t) :: Agent.on_start
  def start_link(%LexibombServer.Board{} = board) do
    Agent.start_link(fn -> board end)
  end

  @doc """
  Creates a board of the given `size`.

  A unique seed for the PRNG is generated and stored with the board.
  """
  @spec new(pos_integer) :: t
  def new(size \\ @default_size) do
    new(size, Utils.unique_seed)
  end

  @doc """
  Creates a board of the given `size` with a specific PRNG `seed`.
  """
  @spec new(pos_integer, seed) :: t
  def new(size, seed) do
    %LexibombServer.Board{
      grid: Grid.init(size),
      seed: seed,
    }
  end

  @doc """


  The board's PRNG seed is used to make this operation idempotent.
  """
  @spec place_random_bombs(t, pos_integer) :: t
  def place_random_bombs(%LexibombServer.Board{} = board, count \\ @default_bomb_count) do
    _ = Utils.seed_the_prng(board.seed)

    coords =
      board.grid
      |> Grid.active_squares
      |> Map.keys
      |> Enum.take_random(count)

    %{board | grid: Grid.place_bombs(board.grid, coords)}
  end

  @doc """
