게임 리팩토링
20860 단어 tutorialwebdevelixiralgorithms
시작하자...
나는 우리 게임의 논리를 풀기 위해 수학적 접근 방식으로 무언가를 찾고 있는 모듈식 산술을 찾았습니다(주제에 관심이 있다면 살펴보십시오here ).
이제 모듈식 산술을 사용하여 코드에 몇 가지 수학을 추가합니다. 그리고 코드를 더 밝고 깔끔하게 만드십시오.
수학적 접근
mod 함수는 한 정수를 다른 정수로 나눈 나머지를 제공합니다. 그리고 가위바위보의 세 가지 선택 사이의 순환 관계에 도움이 될 것입니다.
r = a mod b
r is the remainder when a is divided by b
따라서 코드, 특히 모듈 특성에 대해 살펴보겠습니다.
@stone 1
@paper 2
@scissor 3
미적분을 보다 효율적으로 만드는 데 도움이 되는 팁을 보았습니다.
(first_player_choice - second_player_choice) % 3
게임 리팩토링
게임 결과를 계산하는 기능 추가
game_calc
:defmodule Game do
@moduledoc """
Documentation for `Game`.
"""
@stone 1
@paper 2
@scissor 3
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!!!"}
first_player_choice == @paper && second_player_choice == @scissor ->
{:ok, "Second player win!!!"}
first_player_choice == @stone && second_player_choice == @paper ->
{:ok, "Second player win!!!"}
first_player_choice == @scissor && second_player_choice == @stone ->
{:ok, "Second player win!!!"}
end
end
defp game_calc(first_player_item, second_player_item) do
rem(first_player_item - second_player_item, 3)
end
end
이제 함수 결과를 단순화할 수 있습니다.
defmodule Game do
@moduledoc """
Documentation for `Game`.
"""
@stone 1
@paper 2
@scissor 3
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
game_calc_result = game_calc(first_player_choice, second_player_choice)
case game_calc_result do
0 -> {:ok, "Draw!"}
1 -> {:ok, "First player win!!!"}
_ -> {:ok, "Second player win!!!"}
end
end
defp game_calc(first_player_item, second_player_item) do
rem(first_player_item - second_player_item, 3)
end
end
테스트 실행:
mix test
뭔가 잘못되었다. 테스트를 실행했을 때 3개의 경고와 1개의 실패 메시지를 받았습니다.
Compiling 1 file (.ex)
warning: module attribute @scissor was set but never used
lib/game.ex:8
warning: module attribute @paper was set but never used
lib/game.ex:7
warning: module attribute @stone was set but never used
lib/game.ex:6
..
1) test Game.play/2 when first player wins when first player chooses stone and second player chooses scissors (GameTest)
test/game_test.exs:55
Assertion with == failed
code: assert match == "First player win!!!"
left: "Second player win!!!"
right: "First player win!!!"
stacktrace:
test/game_test.exs:61: (test)
......
Finished in 0.05 seconds (0.00s async, 0.05s sync)
9 tests, 1 failure
Randomized with seed 811857
경고 메시지를 해결하려면 모듈 속성을 제거해야 합니다.
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
game_calc_result = game_calc(first_player_choice, second_player_choice)
case game_calc_result do
0 -> {:ok, "Draw!"}
1 -> {:ok, "First player win!!!"}
_ -> {:ok, "Second player win!!!"}
end
end
defp game_calc(first_player_item, second_player_item) do
rem(first_player_item - second_player_item, 3)
end
end
이제 테스트를 다시 실행하면 다음과 같습니다.
mix test
테스트 실패만 표시됩니다.
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:55
Assertion with == failed
code: assert match == "First player win!!!"
left: "Second player win!!!"
right: "First player win!!!"
stacktrace:
test/game_test.exs:61: (test)
....
Finished in 0.04 seconds (0.00s async, 0.04s sync)
9 tests, 1 failure
Randomized with seed 730068
실패 메시지 이해
실패는 커널 함수 rem/2에 공식에서 음수 배당을 전달하기 때문입니다. 그리고 문서에 따르면 이 커널 함수는 잘린 나눗셈을 사용하는데, 이는 결과가 항상 피제수의 부호를 갖는다는 것을 의미합니다.
첫 번째 플레이어가 돌을 선택하고 두 번째 플레이어가 가위를 선택했을 때 첫 번째 플레이어가 이기면 결과는
-2
입니다.# stone = 1
# paper = 2
# scissor = 3
# R = (first_player_choice - second_player_choice) % 3
# R = (stone - scissors) % 3
# R = (1 - 3) % 3
# In elixir using rem/2
rem(1-3, 3)
> -2
실패 메시지 해결
설명서에 따르면 함수
Integer.mod/2
는 정수 나누기의 모듈로 나머지를 계산합니다.알아두어야 할 사항:
Integer.mod/2
는 바닥 분할을 사용합니다. 즉, 결과는 항상 제수의 부호를 가집니다.따라서 첫 번째 플레이어가 돌을 선택하고 두 번째 플레이어가 가위를 선택했을 때 첫 번째 플레이어가 이겼을 때 결과는
1
입니다.# stone = 1
# paper = 2
# scissor = 3
# R = (first_player_choice - second_player_choice) % 3
# R = (stone - scissors) % 3
# R = (1 - 3) % 3
# In elixir using rem/2
Integer.mod(1-3, 3)
> 1
따라서 실패 메시지를 해결하려면 rem/2 함수를 제거하고 Integer.mod/2를 추가해야 합니다.
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
game_calc_result = game_calc(first_player_choice, second_player_choice)
case game_calc_result do
0 -> {:ok, "Draw!"}
1 -> {:ok, "First player win!!!"}
_ -> {:ok, "Second player win!!!"}
end
end
defp game_calc(first_player_item, second_player_item) do
Integer.mod(first_player_item - second_player_item, 3)
end
end
이제 마지막으로 테스트를 다시 실행하면 다음과 같습니다.
mix test
모든 테스트는 성공적으로 통과했습니다\o/:
Compiling 1 file (.ex)
.........
Finished in 0.04 seconds (0.00s async, 0.04s sync)
9 tests, 0 failures
Randomized with seed 992719
이제 축하할 시간입니다. 가위바위보 게임이 "완료"되었습니다!
프로젝트 저장소: https://github.com/dnovais/rock_paper_scissor_elixir
곧 봐요!
콘택트 렌즈
이메일: [email protected]
링크드인:
트위터:
출처 및 참조
Reference
이 문제에 관하여(게임 리팩토링), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/dnovais/refactoring-the-game-j7a텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)