-
-
Save loganlinn/ecbfb62b02a619e3ce2b084449e7d583 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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