Sha256: 23d641b0e0f02d2b850b75c6a439aeb89b8fac7f0cef63f6181f7785decee0ec

Contents?: true

Size: 1.69 KB

Versions: 69

Compression:

Stored size: 1.69 KB

Contents

defmodule Connect do
  @doc """
  Calculates the winner (if any) of a board
  using "O" as the white player
  and "X" as the black player
  """
  @spec result_for([String.t()]) :: :none | :black | :white
  def result_for(board) do
    cond do
      black_wins?(board) -> :black
      white_wins?(board) -> :white
      true -> :none
    end
  end

  defp black_wins?(board) do
    board
    |> Enum.with_index()
    |> Enum.any?(fn {row, index} ->
      String.first(row) == "X" && black_wins?(board, [{index, 0}])
    end)
  end

  defp black_wins?(board, [{_, y} | _]) when y + 1 == byte_size(hd(board)), do: true

  defp black_wins?(board, history = [last_loc | _]) do
    last_loc
    |> locs_next_to(history)
    |> Enum.filter(&(get_loc(board, &1) == "X"))
    |> Enum.any?(&black_wins?(board, [&1 | history]))
  end

  defp white_wins?(board) do
    board
    |> hd
    |> String.graphemes()
    |> Enum.with_index()
    |> Enum.any?(fn {spot, index} ->
      spot == "O" && white_wins?(board, [{0, index}])
    end)
  end

  defp white_wins?(board, [{x, _} | _]) when x + 1 == length(board), do: true

  defp white_wins?(board, history = [last_loc | _]) do
    last_loc
    |> locs_next_to(history)
    |> Enum.filter(&(get_loc(board, &1) == "O"))
    |> Enum.any?(&white_wins?(board, [&1 | history]))
  end

  defp locs_next_to({x, y}, history) do
    [
      {x, y - 1},
      {x, y + 1},
      {x + 1, y},
      {x - 1, y},
      {x + 1, y - 1},
      {x - 1, y + 1}
    ]
    |> Enum.filter(&valid_next_loc(&1, history))
  end

  defp valid_next_loc({x, y}, history) do
    x >= 0 && y >= 0 && !({x, y} in history)
  end

  defp get_loc(board, {x, y}) do
    row = Enum.at(board, x)
    row && String.at(row, y)
  end
end

Version data entries

69 entries across 69 versions & 1 rubygems

Version Path
trackler-2.2.1.139 tracks/elixir/exercises/connect/example.exs
trackler-2.2.1.138 tracks/elixir/exercises/connect/example.exs
trackler-2.2.1.137 tracks/elixir/exercises/connect/example.exs
trackler-2.2.1.136 tracks/elixir/exercises/connect/example.exs
trackler-2.2.1.135 tracks/elixir/exercises/connect/example.exs
trackler-2.2.1.134 tracks/elixir/exercises/connect/example.exs
trackler-2.2.1.133 tracks/elixir/exercises/connect/example.exs
trackler-2.2.1.132 tracks/elixir/exercises/connect/example.exs
trackler-2.2.1.131 tracks/elixir/exercises/connect/example.exs
trackler-2.2.1.130 tracks/elixir/exercises/connect/example.exs
trackler-2.2.1.129 tracks/elixir/exercises/connect/example.exs
trackler-2.2.1.128 tracks/elixir/exercises/connect/example.exs
trackler-2.2.1.127 tracks/elixir/exercises/connect/example.exs
trackler-2.2.1.126 tracks/elixir/exercises/connect/example.exs
trackler-2.2.1.125 tracks/elixir/exercises/connect/example.exs
trackler-2.2.1.124 tracks/elixir/exercises/connect/example.exs
trackler-2.2.1.123 tracks/elixir/exercises/connect/example.exs
trackler-2.2.1.122 tracks/elixir/exercises/connect/example.exs
trackler-2.2.1.121 tracks/elixir/exercises/connect/example.exs
trackler-2.2.1.120 tracks/elixir/exercises/connect/example.exs