Current section
Files
Jump to
Current section
Files
lib/computer.ex
defmodule Computer do
def random_move(board, seed \\ :rand.seed(:exs1024)) do
_set_random_seed = seed
board
|> Board.available_spots
|> Enum.random
end
def best_move(board, current_player, next_player) do
tagged_current_player = %{current_player | turn: "CURRENT"}
minimax(board, tagged_current_player, next_player).move
end
defp minimax(board, current_player, next_player) do
untagged_current_player = untag(current_player)
available_spots = Board.available_spots(board)
moves = Enum.map(available_spots, fn spot ->
{:ok, new_board} = spot
|> Input.to_board_index
|> Board.update(board, untagged_current_player)
result = Status.result(new_board, next_player, current_player)
case result do
{:win, %Player{type: "COMPUTER", level: "HARD", turn: "CURRENT"}, _board} ->
%{move: spot, score: 10}
{:win, _opponent, _board} ->
%{move: spot, score: -10}
{:tie, _message, _board} ->
%{move: spot, score: 0}
{:play, next_player, current_player, _board} ->
score = minimax(new_board, next_player, current_player).score
%{move: spot, score: score}
end
end)
case current_player do
%Player{type: "COMPUTER", level: "HARD", turn: "CURRENT"} ->
maximizer(moves)
_opponent ->
minimizer(moves)
end
end
defp untag(player) do
%{player | turn: ""}
end
defp maximizer(moves) do
Enum.max_by(moves, fn x -> x.score end)
end
defp minimizer(moves) do
Enum.min_by(moves, fn x -> x.score end)
end
end