Verbose and non-idiomatic exercise in futility: MapSet
-based Tic-tac-toe implementation, with variable game board size. (Though not optimized for bigger boards sizes.)
Set draw when it's draw.Illegal state not being communicated via API (currently: silent NOOP).- Tests are utter mess.
- Leaky state checks.
- Leaky init/new state API (reject invalid x and y values).
- OTP app usage example.
- Function annotations.
The package can be installed
by adding ex_tic_tac_toe
to your list of dependencies in mix.exs
:
def deps do
[
{:ex_tic_tac_toe, "~> 0.2.1"}
]
end
Documentation can be generated with ExDoc and published on HexDocs. Once published, the docs can be found at https://hexdocs.pm/ex_tic_tac_toe.
iex> alias ExTicTacToe, as: TTT
iex> Enum.reduce(
...> [{0, 0}, {1, 0}, {0, 1}, {1, 1}, {1, 2}, {0, 2}, {2, 0}, {2, 1}, {2, 2}],
...> TTT.init(2, 2),
...> fn coords, acc ->
...> TTT.progress_game(acc, TTT.mark(acc, acc.next_move, coords))
...> end
...> )
iex> TTT.phase(y) === {:draw, nil}
true
# x | o | x
#-----------
# x | o | o
#-----------
# o | x | x
iex> Enum.reduce(
...> [{0, 0}, {1, 0}, {0, 1}, {1, 1}, {0, 2}],
...> TTT.init(2, 2, :x),
...> fn coords, acc ->
...> TTT.progress_game(acc, TTT.mark(acc, acc.next_move, coords))
...> end
...> )
iex> TTT.phase(y) === {:won, :x}
true
# x | o |
#-----------
# x | o |
#-----------
# x | |
iex> Enum.reduce(
...> [{0, 0}, {0, 0}],
...> TTT.init(2, 2),
...> fn coords, acc ->
...> TTT.progress_game(acc, TTT.mark(acc, acc.next_move, coords))
...> end
...> )
iex> TTT.phase(y) === {:illegal_move, nil}
true
# o | |
#-----------
# | |
#-----------
# | |