First player wins! Building the code and make the tests pass
Tags: elixir, algorithms, webdev, tutorial
Published: 2022-08-31 15:29:09

---
series: Rock, Paper, and Scissors with Elixir
---

Now we'll continue to code our module Game following the tests. But this time, covering the scenario when the **first player wins**.

Our Game module looks like this:

```Elixir
# lib/game.ex

defmodule Game do
defmodule Game do
  @moduledoc """
  Documentation for `Game`.
  """

  def play(first_player_choice, second_player_choice) do
    result(first_player_choice, second_player_choice)
  end

  defp result(first_player_choice, second_player_choice) do
    cond do
      first_player_choice == second_player_choice -> {:ok, "Draw!"}
    end
  end
end

end
```

> With our tests done, if we run the tests now:

```Elixir
mix test
```

> We'll see the tests failures:

```Bash
  1) test Game.play/2 when first player wins when first player chooses scissors and second player chooses paper (GameTest)
     test/game_test.exs:38
     ** (CondClauseError) no cond clause evaluated to a truthy value
     code: assert {:ok, match} = Game.play(first_player_choice, second_player_choise)
     stacktrace:
       (rock_paper_scissor_elixir 0.1.0) lib/game.ex:12: Game.result/2
       test/game_test.exs:42: (test)


  2) test Game.play/2 when first player wins when first player chooses stone and second player chooses scissors (GameTest)
     test/game_test.exs:56
     ** (CondClauseError) no cond clause evaluated to a truthy value
     code: assert {:ok, match} = Game.play(first_player_choice, second_player_choise)
     stacktrace:
       (rock_paper_scissor_elixir 0.1.0) lib/game.ex:12: Game.result/2
       test/game_test.exs:60: (test)


  3) test Game.play/2 when first player wins when first player chooses paper and second player chooses stone (GameTest)
     test/game_test.exs:47
     ** (CondClauseError) no cond clause evaluated to a truthy value
     code: assert {:ok, match} = Game.play(first_player_choice, second_player_choise)
     stacktrace:
       (rock_paper_scissor_elixir 0.1.0) lib/game.ex:12: Game.result/2
       test/game_test.exs:51: (test)

..

Finished in 0.03 seconds (0.00s async, 0.03s sync)
6 tests, 3 failures
```

### Let's make those tests pass

Now, we need to create some module attributes for stone, paper, and scissors:

```Elixir
defmodule Game do
  @moduledoc """
  Documentation for `Game`.
  """

  @stone 1
  @paper 2
  @scissor 3

# ...
end

```

And then, we'll add the condition that guarantees that the first player is the winner according to our tests.

### When the first player chooses scissors and the second player chooses paper

We'll add the condition when the first player chooses scissors and the second player chooses paper:

```Elixir
defmodule Game do
  @moduledoc """
  Documentation for `Game`.
  """

  def play(first_player_choice, second_player_choice) do
    result(first_player_choice, second_player_choice)
  end

  defp result(first_player_choice, second_player_choice) do
    cond do
      first_player_choice == second_player_choice ->
        {:ok, "Draw!"}

      first_player_choice == @scissor && second_player_choice == @paper ->
        {:ok, "First player win!!!"}
    end
  end
end

```

And now, if we rerun the tests:

```Bash
mix test
```

The test with the actual scenario passed ok. And now we have just two tests with failure.

> Ps.: We have one warning message about the module attributes @stone that was set but never used.

```Bash
Compiling 1 file (.ex)
warning: module attribute @stone was set but never used
  lib/game.ex:5

...

  1) test Game.play/2 when first player wins when first player chooses stone and second player chooses scissors (GameTest)
     test/game_test.exs:56
     ** (CondClauseError) no cond clause evaluated to a truthy value
     code: assert {:ok, match} = Game.play(first_player_choice, second_player_choise)
     stacktrace:
       (rock_paper_scissor_elixir 0.1.0) lib/game.ex:18: Game.result/2
       test/game_test.exs:60: (test)

.

  2) test Game.play/2 when first player wins when first player chooses paper and second player chooses stone (GameTest)
     test/game_test.exs:47
     ** (CondClauseError) no cond clause evaluated to a truthy value
     code: assert {:ok, match} = Game.play(first_player_choice, second_player_choise)
     stacktrace:
       (rock_paper_scissor_elixir 0.1.0) lib/game.ex:18: Game.result/2
       test/game_test.exs:51: (test)



Finished in 0.03 seconds (0.00s async, 0.03s sync)
6 tests, 2 failures

Randomized with seed 797736
...

Finished in 0.02 seconds (0.00s async, 0.02s sync)
3 tests, 0 failures

Randomized with seed 352470
```

### When the first player chooses paper and the second player chooses stone

- We'll add the condition when the first player chooses paper and the second player chooses stone:

```Elixir
defmodule Game do
  @moduledoc """
  Documentation for `Game`.
  """

  def play(first_player_choice, second_player_choice) do
    result(first_player_choice, second_player_choice)
  end

  defp result(first_player_choice, second_player_choice) do
    cond do
      first_player_choice == second_player_choice ->
        {:ok, "Draw!"}

      first_player_choice == @scissor && second_player_choice == @paper ->
        {:ok, "First player win!!!"}

      first_player_choice == @paper && second_player_choice == @stone ->
        {:ok, "First player win!!!"}
    end
  end
end

```

And now, if we rerun the tests:

```Bash
mix test
```

The test with the actual scenario passed ok. And now we have just one tests with failure.

```Bash
Compiling 1 file (.ex)
..

  1) test Game.play/2 when first player wins when first player chooses stone and second player chooses scissors (GameTest)
     test/game_test.exs:56
     ** (CondClauseError) no cond clause evaluated to a truthy value
     code: assert {:ok, match} = Game.play(first_player_choice, second_player_choise)
     stacktrace:
       (rock_paper_scissor_elixir 0.1.0) lib/game.ex:21: Game.result/2
       test/game_test.exs:60: (test)

...

Finished in 0.03 seconds (0.00s async, 0.03s sync)
6 tests, 1 failure

Randomized with seed 450094
```

### When the first player chooses stone and the second player chooses scissors

- We'll add the condition when the first player chooses stone and the second player chooses scissors:

```Elixir
defmodule Game do
  @moduledoc """
  Documentation for `Game`.
  """

  def play(first_player_choice, second_player_choice) do
    result(first_player_choice, second_player_choice)
  end

  defp result(first_player_choice, second_player_choice) do
    cond do
      first_player_choice == second_player_choice ->
        {:ok, "Draw!"}

      first_player_choice == @scissor && second_player_choice == @paper ->
        {:ok, "First player win!!!"}

      first_player_choice == @paper && second_player_choice == @stone ->
        {:ok, "First player win!!!"}

      first_player_choice == @stone && second_player_choice == @scissor ->
        {:ok, "First player win!!!"}
    end
  end
end

```

And now, if we rerun the tests:

```Bash
mix test
```

All the tests pass with success. 

```Bash
Compiling 1 file (.ex)
......

Finished in 0.03 seconds (0.00s async, 0.03s sync)
6 tests, 0 failures

Randomized with seed 795123
```

In the next post, we'll build the tests covering the scenario when the second player wins.

#### Contacts
Email: contato@diegonovais.com.br
Linkedin: https://www.linkedin.com/in/diegonovais/
Twitter: https://twitter.com/diegonovaistech