본문 바로가기
Study/Python

컴퓨터와 가위바위보 하기 1

by 개발새-발 2021. 8. 12.
반응형

컴퓨터와 '가위 바위 보' 게임을 해보기로 했다. 컴퓨터와 게임을 하기 위해 프로그램을 만들어본다.

간단하게 한판 하는 프로그램

간단하게 '가위 바위 보' 게임을 한판만 하는 프로그램을 제작해보자. 이 경우 게임의 진행순서는 대략 다음과 같을 것이다.

  • 사용자에게 '가위, 바위, 보' 중 하나의 입력을 받는다.
  • 컴퓨터도 세 개의 값 중 하나를 고른다.
  • 사용자가 고른 값과 컴퓨터가 고른 값을 비교하여 승, 패 여부를 확인한다.
  • 사용자에게 결과를 출력한다.

사용자로부터 입력받기

사용자에게 가위, 바위, 보를 선택하게 하는 방법은 여러 가지가 있다. 버튼을 만들어 하나를 선택하게 할 수도 있고, 키보드로 입력을 받을 수도 있으며, 음성 혹은 카메라로 입력을 받는 방법도 존재한다. 이 글에서는 간단하게 만들 것임으로 키보드로 입력을 받는다.

그렇다면 키보드로 어떤 형식으로 입력을 받을 것인가? 키보드로 가위, 바위, 보를 선택하게 하는 방법은 다양하다. 'r', 's', 'p' 키를 각각 가위, 바위, 보를 선택하는 데 사용하게 할 수 있다. 또는, 문자열 입력으로 '가위', '바위', '보' 중 하나를 직접 받을 수도 있다.

사용자가 선택한 값은 어떤 형태로 저장할 것인가? 경우에 따라서 입력받은 값 그대로 저장하고 있을 수도 있고, 특정 숫자로 변환하여 저장할 수도 있다. 만약 사용자가 문자열로 '가위'를 입력하였다고 하자. 값을 그대로 저장한다면 '가위' 문자열을 그대로 저장할 것이다. 반면, '가위', '바위', '보'를 각각 숫자 0,1,2로 바꾸어 사용하기로 했다면 숫자 0이 저장될 것이다.

이 글에선 사용자로부터 세 개의 문자열 '가위', '바위', '보' 중 하나를 입력받고, 이를 각각 정수 0,1,2로 저장하는 방법을 택하였다. 입력을 정수로 변환하는 이유는 이후 승패 판정을 더 편하게 하기 위함이다.

이 과정을 처리하기 위한 코드는 아래와 같다.

# 가위 = 0, 바위 = 1, 보 = 2
possible_choices = ['가위', '바위', '보']

# 사용자의 입력을 받고, 선택 값을 정수형으로 반환
# 반환 값 : 가위 = 0, 바위 = 1, 보 = 2 , 기타 다른 입력 = -1
def get_user_choice():
    s = input('가위 바위 보! : ')
    if s in possible_choices:
        return possible_choices.index(s)
    return -1

possible_choices는 사용자가 선택할 수 있는 선택지를 모아놓은 리스트이다. 또, possible_choices의 값들의 위치는 get_user_choice에서 사용자로부터 받은 입력을 정수 값으로 변환할 때의 값이 된다. '가위'는 0번째에 위치함으로 정수 값 0으로 변환된다.

컴퓨터가 '가위', '바위', '보' 중 하나 고르게 하기

컴퓨터랑 이 게임을 하기 위해선 컴퓨터도 '가위', '바위', '보' 세 개의 값 중 하나를 선택하여야 한다. 이 부분을 처리할 때도 컴퓨터 선택 값의 형식을 고려해야 한다. 사용자 입력을 처리할 때처럼 문자열 형태로 반환할 수도 있고, 정수 형태로 반환할 수도 있다. 난 앞에서 사용자 입력을 정수 형태로 변환하였음으로 컴퓨터가 0,1,2의 정수 값 중 하나를 고르도록 할 것이다. 이를 위한 코드는 아래와 같다.

# 컴퓨터의 선택 값을 정수형으로 반환
# 반환 값 : 가위 = 0, 바위 = 1, 보 = 2
def get_computer_choice():
    return random.randint(0,2)

승패 판정하기

사용자가 고른 값과 컴퓨터가 고른 값을 비교해서 사용자가 승리하였는지 패배하였는지 확인해야 한다. 여기서 내가 선택한 값을 me라고 하고 상대방이 선택한 값을 opponent라고 하자. 가위바위보의 승패 판정의 결과는 크게 3개가 있다. 이기거나, 지거나 비기는 경우이다. 각각의 경우를 따로 나누어 생각하여 보자.

  • 비기는 경우

  • 내가 고른 값과 상대방이 고른 값이 동일한 경우 비긴 것이다. 즉, me==opponent인 경우이다.

  • 지는 경우python으로 이를 구현하는 경우 다양한 선택지가 존재한다. if문을 세 개를 사용하여 구현할 수도 있고, 세 개의 if문들의 조건문들을 or을 사용하여 하나의 if문으로 구현할 수도 있다. 내가 선택한 값을 넣으면 내가 패배하는 경우 상대방이 선택해야 하는 값을 알 수 있게 하는 dictionary를 사용하여 비교하여도 된다. (이 dictionary에 '가위'를 입력으로 넣으면 '바위'를 얻을 수 있을 것이다.) 구현할 수 있는 방법은 많고, 원하는 동작 시간 안에 정확한 값을 보여준다면 그 어느 방법이든 답이 될 수 있다.

    '가위'는 0, '바위'는 1, '보'는 2이다. meopponent이 두 개의 값을 (me, opponent)의 꼴로 표현하였을 때 내가 지는 경우는 (0,1), (1,2), (2,0)이다. 여기서 opponent의 값이 (me + 1) % 3와 같다는 점을 이용하면 아래와 같이 패배 판정 조건문을 작성할 수 있다.

  • if (me + 1) % 3 == opponent: #패배한 경우 동작할 코드들

  • 난 선택 값들을 숫자로 가지고 있다. 숫자 형태로 값을 가지고 있어도 위에서 언급한 방법들은 모두 사용 가능하다. 하지만 다른 방법을 한번 써볼까?

  • 만약 우리가 사용자와 컴퓨터의 선택 값을 문자열로 받았다고 한다면, 우리는 if문을 이용하여 패배 여부를 확인할 수 있다. 내가 '가위'를 냈는데 상대방이 '바위'라면 나의 패배이다. 내가 '바위'일 때 상대방이 '보', 내가 '보'일 때 상대방이 '가위'인 경우에도 나의 패배이다.
  • 이기는 경우
  • '가위, 바위, 보' 게임에서 나와 상대방이 둘 다 정해진 세 개의 값 중 하나를 골라냈다면 게임의 결과는 이기거나 지거나 비기는 경우 말고는 존재하지 않는다. 우리는 앞에서 비기거나 지는 경우에 대해 처리를 해 주었다. 이 게임에서 비기지도 않았고, 패배하지도 않은 경우라면 이겼다고 볼 수 있다.

세 가지 경우에 대해 살펴보았다. 이제 meopponent의 값을 비교하여 비기는 경우, 이기는 경우, 지는 경우를 각각 정수 0,1,2로 반환하는 함수를 작성해보자.

# 두 개의 가위바위보 선택 값을 받아 첫 번째 값의 승패 여부를 반환
# 반환 값 : 비김 = 0, 승리 = 1, 패배 = 2 
def check_win(me : int, opponent : int) :
    if me == opponent:
        return 0
    elif (me + 1) % 3 == opponent:
        return 2 
    else :
        return 1

결과 출력하기

내가 고른 값, 컴퓨터가 고른 값을 보여주며 승패 여부를 알려주려고 한다. 원하는 방식으로 출력해보자.

# 비김, 승리, 패배 각각의 경우 표시될 메시지
result_message = ['비김 - .-', '승리!!!', '패배 ㅠㅠ']

print(f'나 : {possible_choices[user]} vs {possible_choices[com]} : COM')
print(result_message[result])

코드 합치기

위에서 작성한 코드들을 하나의 함수에 매끄럽게 연결하여 보자. 함수이 이름은 play로 할 것이다. play 함수는 아래 내용을 순차적으로 실행하게 된다.

  • 사용자에게 입력을 받는다.
  • 입력을 확인 후 입력이 유효하면 아래 내용을 실행하고 그렇지 않다면 메시지를 보여주고 실행을 중지한다.
  • 컴퓨터의 선택을 결정한다.
  • 사용자의 선택과 컴퓨터의 선택을 비교하여 승패 여부를 결정한다.
  • 결과물을 출력한다.

위에서 작성한 코드들과 약간의 코드를 추가하여 play 함수를 작성하였다.

# 가위바위보 
def play():
    # 사용자 입력
    user = get_user_choice()

    # 잘못된 입력인 경우 종료
    if user == -1:
        print('가위, 바위, 보 중에 하나만 선택하세요.')
        return

    # 컴퓨터 입력
    com = get_computer_choice()

    # 승패 여부
    result = check_win(user,com)

    # 결과 출력
    print(f'나 : {possible_choices[user]} vs {possible_choices[com]} : COM')
    print(result_message[result])

이제 이 코드들을 하나의 파이썬 파일에 실행 가능한 형태로 작성하여야 한다. if __name__ == '__main__' : 문 아래에 play() 함수를 사용하여 주자.

if __name__ == '__main__':
    play()

아래는 내가 작성한 전체 파이썬 파일이다.

# rsc1.py
import random

# 가위 = 0, 바위 = 1, 보 = 2
possible_choices = ['가위','바위','보']

# 비김, 승리, 패배 각각의 경우 표시될 메시지
result_message = ['비김 - .-','승리!!!','패배 ㅠㅠ']

# 사용자의 입력을 받고, 선택 값을 정수형으로 반환
# 반환 값 : 가위 = 0, 바위 = 1, 보 = 2 , 기타 다른 입력 = -1
def get_user_choice():
    s = input('가위 바위 보! : ')
    if s in possible_choices:
        return possible_choices.index(s)
    return -1

# 컴퓨터의 선택 값을 정수형으로 반환
# 반환 값 : 가위 = 0, 바위 = 1, 보 = 2
def get_computer_choice():
    return random.randint(0,2)

# 두 개의 가위바위보 선택 값을 받아 첫 번째 값의 승패 여부를 반환
# 반환 값 : 비김 = 0, 승리 = 1, 패배 = 2 
def check_win(me : int,opponent : int) :
    if me == opponent:
        return 0
    elif (me + 1) % 3 == opponent:
        return 2 
    else :
        return 1

# 가위바위보 
def play():
    user = get_user_choice()
    if user == -1:
        print('가위, 바위, 보 중에 하나만 선택하세요.')
        return

    com = get_computer_choice()
    result = check_win(user,com)

    print(f'나 : {possible_choices[user]} vs {possible_choices[com]} : COM')
    print(result_message[result])

if __name__ == '__main__':
    play()

실행

이제 혼자서 컴퓨터랑 가위바위보를 해보자.

가위 바위 보! : 가위
나 : 가위 vs 보 : COM
승리!!!
가위 바위 보! : 바위
나 : 바위 vs 보 : COM
패배 ㅠㅠ
가위 바위 보! : 보
나 : 보 vs 보 : COM
비김 - .-
가위 바위 보! : 보라돌이
가위, 바위, 보 중에 하나만 선택하세요.

질릴 때까지 가위바위보를 할 수 있도록 프로그램 변경하기

가위바위보를 여러 번 하고 싶었다. 위에서 한판만 하도록 만든 코드를 약간 수정하여 여러 번 반복하여 게임을 할 수 있도록 하자.

그전에 프로그램이 실행될 순서를 잘 생각해보자.

  1. 사용자에게 입력을 받는다.
  2. 입력을 확인 후 입력이 유효하면 아래 내용을 실행하고 그렇지 않다면 메시지를 보여주고 실행을 중지한다.
  3. 컴퓨터의 선택을 결정한다.
  4. 사용자의 선택과 컴퓨터의 선택을 비교하여 승패 여부를 결정한다.
  5. 결과물을 출력한다.
  6. 게임을 계속할 것인지를 사용자로부터 입력받는다.
  7. 게임을 계속하는 경우 1번부터 다시 진행한다. 계속하지 않는 경우 프로그램을 종료한다.

그런데 위의 1번부터 5번 과정은 이미 한판만 하는 play 함수에 담겨있다. 이를 고려하여 위 과정을 아래처럼 다시 쓸 수 있다.

  1. play()
  2. 게임을 계속할 것인지를 사용자로부터 입력받는다.
  3. 게임을 계속하는 경우 1번부터 다시 진행한다. 계속하지 않는 경우 프로그램을 종료한다.

사용자로부터 게임을 계속할 것인지 입력받기

나는 'y', 'Y', 'Yes', '네' 혹은 '넵' 중 하나를 입력받으면 플레이를 계속한다는 뜻으로 정하였다. 이를 바탕으로 플레이 여부를 결정하는 코드를 작성하였다.

play_more = ['y','Y','Yes','네','넵']
user_play_more = input('계속 플레이 하시겠습니까? 진행하려면 y를 입력하세요.')
if user_play_more not in play_more:
    # 더 이상 게임을 하지 않을 경우

여러 번 게임을 할 수 있도록 반복문 추가하기

여러 번 게임을 하도록 하는 함수 playmany()를 만들어보자. 위에서 적은 과정을 코드로 작성하여야 한다. 이를 위해선 반복문을 사용하여야 한다.

play_more = ['y','Y','Yes','네','넵']

def playmany():

    while True:
        play()
        user_play_more = input('계속 플레이 하시겠습니까? 진행하려면 y를 입력하세요. : ')

        if user_play_more not in play_more:
            break

약간의 코드 수정

위 코드를 추가해준 뒤 if __name__ == '__main__' : 아래 play()playmany()로 수정해주자.

실행

가위 바위 보! : 가위
나 : 가위 vs 보 : COM
승리!!!
계속 플레이 하시겠습니까? 진행하려면 y를 입력하세요. : 네
가위 바위 보! : 보
나 : 보 vs 보 : COM
비김 - .-
계속 플레이 하시겠습니까? 진행하려면 y를 입력하세요. : y 
가위 바위 보! : 가위
나 : 가위 vs 바위 : COM
패배 ㅠㅠ
계속 플레이 하시겠습니까? 진행하려면 y를 입력하세요. : 싫어요

이제 질릴 때까지 가위바위보를 할 수 있게 되었다.

반응형

댓글