Skip to content

Instantly share code, notes, and snippets.

@BSN4
Created November 26, 2024 19:31
Show Gist options
  • Save BSN4/ea70e8ac3c46f9a4b99d61a1e7167c3a to your computer and use it in GitHub Desktop.
Save BSN4/ea70e8ac3c46f9a4b99d61a1e7167c3a to your computer and use it in GitHub Desktop.
shorter.ex
defmodule RPS do
defmodule Score, do: defstruct player: 0, computer: 0
def play do
%Score{}
|> Stream.iterate(&play_round/1)
|> Enum.at(3)
|> announce_winner()
|> maybe_play_again()
end
defp play_round(score) do
with {:ok, player} <- get_move("Enter move (rock/paper/scissors): "),
computer = Enum.random([:rock, :paper, :scissors]) do
IO.puts("Computer chose: #{computer}")
{winner, move1, move2} = determine_winner(player, computer)
IO.puts(format_result(winner, move1, move2))
update_score(winner, score)
else
{:error, msg} -> IO.puts(msg); play_round(score)
end
end
defp get_move(prompt) do
case IO.gets(prompt) |> String.trim() |> String.downcase() do
"rock" -> {:ok, :rock}
"paper" -> {:ok, :paper}
"scissors" -> {:ok, :scissors}
_ -> {:error, "Invalid move"}
end
end
defp determine_winner(player, computer) do
wins = %{rock: :scissors, paper: :rock, scissors: :paper}
cond do
player == computer -> {:draw, player, computer}
wins[player] == computer -> {:player, player, computer}
true -> {:computer, computer, player}
end
end
defp format_result(:draw, move, _), do: "Draw! Both threw #{move}"
defp format_result(:player, threw, beat), do: "You won with #{threw} against #{beat}"
defp format_result(:computer, threw, beat), do: "Computer won with #{threw} against #{beat}"
defp update_score(:player, score), do: %{score | player: score.player + 1}
defp update_score(:computer, score), do: %{score | computer: score.computer + 1}
defp update_score(:draw, score), do: score
defp announce_winner(score = %Score{player: p, computer: c}) do
IO.puts("\nFinal Score - You: #{p}, Computer: #{c}")
IO.puts(if p > c, do: "You win!", else: if(p < c, do: "Computer wins!", else: "Draw!"))
score
end
defp maybe_play_again(_) do
if String.starts_with?(IO.gets("\nPlay again? (y/n): ") |> String.downcase(), "y") do
play()
else
IO.puts("Thanks for playing!")
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment