서비스 기획자의 성장기록

[Python 실습] 야구게임 만들기 본문

Python/Python 실습

[Python 실습] 야구게임 만들기

Jenny Noh 2023. 10. 30. 09:43

문제

다음과 같은 규칙에 따라 컴퓨터가 0~9 사이의 중복되지 않은 임의의 정수 3개를 생성한 숫자를 숫자와 순서까지 맞추는 게임 프로그램을 작성하세요.
    - 랜덤하게 생성된 3개의 숫자와 플레이어가 입력한 숫자 3개에 대해 순서와 숫자를 비교하여 다음의 결과를 보여준다.
    * 숫자는 맞았으나 위치가 다른 경우: 맞춘 숫자 갯수 만큼 볼 (ball)
    * 숫자와 순서가 모두 맞은 경우: 스트라이크 (strike)
    * 맞춘 숫자가 없으면 아웃 (out)
    * 게임은 3 스트라이크가 되면 종료되며 시도 횟수를 보여준다.

    - 다음의 두 가지 함수를 정의하여 구현한다.
    * randomNumber(): 0~9 사이의 중복되지 않은 정수 3개를 반환
    * inputNumber(): 키보드로 0~9 사이의 정수를 입력 받아 반환하는 함수 (ValueError 예외처리)

 

 

풀이

# 함수정의
def randomNumber(i):
    import random
    pool = [0,1,2,3,4,5,6,7,8,9]
    return random.sample(pool, i)
    
def inputNumber(turn):
    while True:
        try:
            num = int(input(f'{turn}번째 값: '))
            if not 0<= num <= 9:
                raise ValueError(f'{num}은 범위에서 벗어난 값입니다. 다시 입력하세요.')
            return num
        except:
            print('숫자만 입력하세요.')
    
    

# 제목 출력
print('-'*9, 'Baseball Game', '-'*9)
print('각각의 입력 범위는 0~9입니다.')
print('---------------------------------')

# random 값 생성
ans = randomNumber(3)

count = 1
while True:
    turn = 1
    # user에게 input 받기
    input_list=[]
    while True: 
        try:
            num = inputNumber(turn)
            if num not in input_list:
                input_list.append(num)
                turn += 1
            else:
                print(f'{num}은 이미 입력한 값입니다. 다시 입력하세요.')
                continue
            if len(input_list) == 3: break
                
        except ValueError as e:
            print(e)
            continue
    print('---------------------------------')        
    print(f'입력한 값은: {input_list}입니다!')
    
    strike = 0
    ball = 0
    out = 0
    
 
    # 결과값 연산
    for v in input_list:
        if v in ans:
            if input_list.index(v) == ans.index(v):
                strike += 1
            else:
                ball += 1
        else:
            out += 1

    print('-------------- 결과 -------------')
    print(f'count ({count}): 입력 결과는 {strike} strike, {ball} ball, {out} out 입니다.')
    print('==================================\n')
    
    
    if strike == 3:
        print(f'{count}번 만에 성공!')
        break
        
    count += 1

 

 

교수님 풀이

import random

def randomNumbers():
    return random.sample(range(10), 3)

def inputNumber():
    while True:
        try: 
            n = int(input(message))
            if 0 <= n <= 9:
                return n
            else:
                print('0~9 사이의 정수만 입력하세요.')
        except ValueError as e:
            print('0~9 사이의 정수만 입력하세요.')

count = 0

ranNums = randomNumbers()
print(randomNums)    # 정답 확인용

# 제목출력 (생략)

while True:
    strike = 0
    ball = 0
    count += 1
    inputNums = []

    message_list = ['첫 번째 값: ', '두 번쨰 값: ', '세 번째 값: ']
    i = 0    # inputNumber message 인덱스
    while i <= 2:
        n = inputNumber(message_list[i])
        if n not in inputNums:
            inputNums.append(n)
            i+=1
        else:
            print(f'{n}은 이미 입력한 값입니다. 다시 입력하세요.')

    for i, randNum in enumerate(randNums):
        for j, inputNum in enumerate(inputNums:
            if randNum == inputNum and i == j:
                strike += 1
            elif randNum == inputNum:
                ball += 1

    print(f'count({count}: 입력 결과는 {strike}Strike, {ball}Ball 입니다.)')

    if strike == 3:
        print(f'축하합니다! {count}번 만에 성공!')
        break

 

 


Review

1. randomNumber() 함수

randomNumber() 함수를 만들기 위해서 세 가지 방법을 생각했다.

1) 생성한 숫자의 집합을 set으로 변환한 다음 len(set)의 길이가 3이 되면 반환하는 방법

2) 생성한 숫자의 집합을 for 문으로 중복되는 숫자가 없으면 반환하는 방법

3) 0~9 까지의 정수 집합을 생성해서 random.sample() 함수를 사용하는 방법

1번 방법을 테스트 해봤더니 연산이 너무 오래걸려서 이 방법은 drop 시켰다.

2번 방법은 for 문으로 코드가 길어질 것 같아서 (개인적으로 선호 x) 3번 방법을 택했다.

 

2. inputNumer() 함수

inputNumber() 함수를 작성하는데서 난관에 마주쳤다 🤯 

처음엔 i를 매개변수로 받아서 i 횟수만큼 반복해서 돌리는 반복문을 만들어야 하는줄 알고 아래처럼 코드를 작성했다.

그러니까 ValueError이 발생했을 때 다시 값을 입력받지 않고 종료되버렸다! 😭😭

그런데 출제자의 의도는 횟수와 상관없이 키보드로 입력받은 값이 유효한 값인지 확인하는 함수였고.....(정상값은 리턴하고 나머지는 예외처리하는 함수...)....그래서 아래와 같이 코드를 수정했다.

완성본 ta-dah-! 🥳

핵심!!! inputNumber()은  값을 유효성을 검사하는 함수

 

 

다른 풀이 (교수님 풀이)를 보고 코드를 반추해 보고 참고할 만한 포인트를 뽑아봤다.

1.  i 로 메세지 리스트의 메세지 반환

2.  strike와 ball 만 연산

3.  elif 구문 사용

 

 

 

끗!