Skip to content

Instantly share code, notes, and snippets.

@loganlinn
Forked from jordangarcia/board.ex
Last active March 11, 2019 04:06
Show Gist options
  • Save loganlinn/ecbfb62b02a619e3ce2b084449e7d583 to your computer and use it in GitHub Desktop.
Save loganlinn/ecbfb62b02a619e3ce2b084449e7d583 to your computer and use it in GitHub Desktop.
defmodule TicTacToe do
defmodule Board do
def create(maxX \\ 3, maxY \\ 3) do
for x <- 0..(maxX - 1),
y <- 0..(maxY - 1) do
{{x, y}, nil}
end
|> Map.new()
|> Map.put_new(:maxY, maxY)
|> Map.put_new(:maxX, maxX)
end
def valid_play?(b, {x, y}) do
Map.has_key?(b, {x, y}) and b[{x, y}] == nil
end
def play(b, {x, y}, val) do
if is_valid_play?(b, {x, y}) do
{:ok, Map.put(b, {x, y}, val)}
else
{:error, b}
end
end
def get_winner(b) do
# TODO
nil
end
end
defmodule Game do
defstruct status: :playing, winner: nil, board: nil, turn: :x
def create do
# TODO pass board or board options, turn
%Game{board: Board.create()}
end
def play(game, {x, y}, player) do
# TODO use Logger
IO.puts("Trying to play: #{player} @ {#{x}, #{y}}")
cond do
!game_active?(game) ->
{:error, game, "game not active"}
!is_players_turn?(game, player) ->
{:error, game, "not players turn"}
!Board.valid_play?(game.board, {x, y}) ->
{:error, game, "cannot play here"}
true ->
{
:ok,
game
|> update_board({x, y}, player)
|> switch_turn()
}
end
end
def update_board(game, {x, y}, player) do
Map.update!(game, :board, fn board ->
{_, new_board} = Board.play(board, {x, y}, player)
new_board
end)
end
def switch_turn(game) do
%{
game
| turn:
if game.turn == :x do
:y
else
:x
end
}
end
def game_active?(game) do
game.status == :playing
end
def players_turn?(game, player) do
game.turn === player
end
def valid_player?(x) do
x == :x or x == :o
end
end
def get_2nd(iter) do
Enum.at(Tuple.to_list(iter), 1)
end
def test do
Game.create()
|> Game.play({0, 0}, :x)
|> get_2nd
|> Game.play({1, 0}, :o)
|> get_2nd
|> Game.play({5, 0}, :x)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment