가위바위보 문제를 해결하는 방법은 여러가지가 있습니다. 하지만 그 근본은 가위, 바위, 보 각각을 숫자로 매핑해서 대소를 비교하는 것입니다.
대소를 비교하는 방법은 너무 다양해서 딱히 어떤 방식이 가장 좋다고 볼 수 없습니다.
비교 가지수도 9가지 뿐이므로 모든 경우를 다 비교하는 것도 어렵지 안고 효율성도 나쁘지 않습니다.
가위를 1로 두고 바위(2), 보(3) 이렇게 숫자로 매핑하면 됩니다. 매핑은 파이썬 사전을 사용하면 됩니다.(아래 코드 참조)
여러명이 가위바위보 게임을 할 수도 있겠지만 여기서는 컴퓨터와 나, 이렇게 둘이서 게임을 하는 프로그램을 작성합니다.
다음은 모든 경우를 비교하는 방법을 사용해서 컴퓨터와 가위바위보를 하는 코드입니다.
파이썬 아나콘다 3.5.2를 사용했고 IDLE 상에서 작성합니다.
파이썬 파일은 위에 첨부했습니다.
- rps_dict 변수는 "가위", " 바위", "보"를 각각 1, 2, 3에 매핑한 사전입니다. (사전이나 random 모듈에 대해 잘 모르시면 제 블로그에서 해당 토필에 대한 파이썬 강의를 보시면 됩니다. 사전에 대한 내용을 보시면 됩니다.)
- myIn은 내가 낸 값(가위면 1, 바위면 2...)을 저장하는 변수
- computerIn은 컴퓨터가 낸 값 입니다. 컴퓨터는 랜덤 모듈로 생성된 값을 저장하고
- myIn과 computerIn의 경우의 수를 따져서 승패를 따집니다.
이번에는 경우에 수를 따지지 않고 두 값의 차이를 이용해서 구하는 방법을 생각해 보겠습니다.
- 가위(1) < 바위(2) 는 바위(2)가 이깁니다.
- 바위(2) < 보(3) 는 보(3)가 이기죠.
여기까지는 큰 수가 이깁니다. 하지만
- 가위(1) < 보(3) 는 가위(1)가 이기네요.
대소를 비교하기 위해서 컴퓨터가 낸 수와 내가 낸 수의 차를 구하는데 이 값이 음수면 내가 큰 수를 낸 것입니다.(differ 변수) differ가 0이면 둘이 같은 값을 낸거겠죠.
이렇게 차이값으로 대소를 비교하는데 앞에서 설명했듯이 내가 가위(1)를 내고 컴퓨터가 보(3)를 내거나, 내가 보(3)를 내고 컴퓨터가 가위(1)를 낸 경우는 결과가 뒤집힙니다. 이렇게 결과가 뒤집히는 것을 바로 잡기 위해 differ에 -1을 곱하면 승패의 결과가 제대로 나옵니다.(빨간 박스) 이렇게 하면 일괄적으로 대소비교를 해서 처리가 가능하게 됩니다.
그런데 가위바위보 알고리즘은 매우 간단하므로 웬지 if문을 하나로 줄일 수 있을 것 같아서 인터넷을 뒤져봤습니다. 다음과 같은 코드가 있더라구요. 결론부터 말하자면 이 코드는 틀렸습니다.
이 코드는 가위를 0으로 두었네요. 그리고 가위와 보의 승패 비교를 위해 1을 더해서 %3연산을 해줍니다.
내가 가위를 내고 상대가 보를 낸 경우
가위 : (0 + 1)% 3 =1
보 : (2 + 1)% 3 = 0
가위 는 1가 되고 보는 0이 되어 가위 > 보 가 되는구요.
하지만
바위 :(1+1)%3 = 2
보:(2+1)%3 = 0
바위 는 2가 되고 보는 0이 되네요. 바위 > 보, 이건 틀렸네요.
저도 위 방법이 맞는 줄 알고 있었는데 한마터면 그냥 넘어갈 뻔 했네요.
그 후로도 다양한 방법들을 알아보다가 결국 조건문을 하나만 사용하는 방법은 찾지 못했습니다. 있을려나요?