코딩일지/내일배움캠프 과제

20220907 숫자야구 게임

야언 2022. 9. 7. 16:29

고려해야 할 사항

 

몇 자리 숫자(count)로 할 건지 입력받기 -> 받은 숫자를 이후의 함수에도 적용시켜야하는데?? -> 전역변수화 (global)

count의 조건 3자리수 이상 10자리 수 이하 -> if 문 활용해 오류시 재입력

 

랜덤 변수 뽑아내기(중복차단) -> 중복 차단을 위해 set 자료형을 활용 -> 계속 번호가 정렬되어서 나옴

why?  

set 자료형은 기본적으로 "순서"라는 개념이 존재하지 않는다. 때문에 값을 add 하더라도 랜덤한 순서로 저장되는 것이 아닌, set 자료형의 특성에 맞게 순서가 변경되기 때문.

해결방안 : if 변수 not in 리스트 형식으로 변수중복 차단 

내 답안지 입력 -> count 숫자만큼 답안지 입력, "exit" 입력시 게임종료(exit()), 9를 초과하는 수, 중복되는 수 if문 활용해 오류시 재입력

 

strike / ball 카운트 ->  문제 리스트a와 내 리스트b 비교 (while 반복문, i < count). 변수가 순서까지 같다면(a[i] == b[i]) 스트라이크,  문제 리스트 안에 내 변수가 들어있다면 볼(b[i] in a)

 

정답을 맞춘 경우 (맞추기까지 시도 횟수, 소요시간, 정답을 맞춘 시점의 날짜/시간) 입력 

시도횟수 : tries = 0, tries += 1 

소요시간 : time 임포트하고 시작, 종료 시 시간 설정(start_time = time.time(), end_time = time.time()) 해서 end_time-start_time

시간 및 날짜 : datetime 임포트, 정답입력 시 함수에 datetime.now()

 

print(f"정답입니다! 시도:{tries}회 소요시간:{end_time-start_time:.2f}초 {datetime.now()}")

 

 

 

내 제출

import random
import time
from datetime import datetime

start_time = time.time()  # 시작 시간 세팅

def generate_numbers():  # 난수 생성
    global count  # 몇 자리 수인지를 전역변수로 설정
    numbers = []
    while True:
        count = int(input('몇 자리 숫자로 플레이 할지 입력 : '))
        if count < 3:
            print("3 이상의 값을 입력해주세요")
            continue
        if count > 10:
            print("10 이하의 값을 입력해주세요")
            continue

        while len(numbers) < count:
            num = random.randint(0, 9)  # 랜덤 변수 생성
            if num not in numbers:  # 리스트 안에 없다면
                numbers.append(num)  # 추가하는 식으로 변수중복 차단

        print(f"0과 9 사이의 서로 다른 숫자 {count}개를 랜덤한 순서로 뽑았습니다.\n")
        return numbers  # 함수 generate_numbers() = numbers 정답지 리스트

def take_guess():  # 내 답안지
    print(f"숫자 {count}개를 하나씩 차례대로 입력하세요.")
    i = 0
    new_guess = []
    while i < count:  # count 수까지 반복
        gue_number = input(f"{i + 1}번째 숫자를 입력하세요: ")  
        if gue_number == "exit":
            print("게임을 종료합니다.")
            exit()
        if int(gue_number) > 9:
            print("범위를 벗어나는 숫자입니다. 다시 입력하세요.")
            continue
        if int(gue_number) in new_guess:
            print("중복되는 숫자입니다. 다시 입력하세요. ")
            continue
        else:  # 문제 없으면
            new_guess.append(int(gue_number))  # 답안지 리스트에 적고
            i += 1  # 다음번호로

    return new_guess  # 함수 take_guess() = new_guess 내 답안지


def get_score(guess, solution):  # 답안지를 정답과 비교하기
    strike_count = 0
    ball_count = 0
    i = 0

    while i < count:
        if guess[i] == solution[i]:  # 숫자가 리스트 순서까지 같다면 스트라이크
            strike_count += 1
            i += 1
        elif guess[i] in solution:  # 숫자가 리스트 안에 존재한다면 볼
            ball_count += 1
            i += 1
        else:  # 아니면 뭐 없지
            i += 1

    return strike_count, ball_count  # get_score 함수는 (스트라이크, 볼) 카운트


# 여기서부터 게임 시작!
ANSWER = generate_numbers()  # 내 답안지
tries = 0  # 시도 횟수

while True:
    GUESS = take_guess()  # 내 답안지
    strike, ball = get_score(GUESS, ANSWER)
    print(f"{strike}S {ball}B ")

    if strike == count:  # 정답이라면
        tries += 1  # 시도는 한번 올리고
        end_time = time.time()  # 마무리 시간 재고
        print(f"정답입니다! 시도:{tries}회 소요시간:{end_time-start_time:.2f}초 {datetime.now()}")  # 시도 횟수, 걸린 시간, 맞춘 시점 시간까지 보여주고
        break  # 끝
    else:
        tries += 1  # 시도 횟수 하나 올리고 다시

 

실기

 

몇자리 수인지 정상작동~
에러메세지, exit 종료명령 정상작동 확인!

 

실제로 플레이 해보기!

 

 

느낀 점

 어떤 식으로 작동해야 할 지 구상은 바로바로 떠오르는데 역시나 실제로 돌아가도록 코드를 짜는 일이 바로바로 손에 안잡잡혀서 고생을 좀 많이했다.. 구글링도 실력이라는 튜터님의 조언을 듣고 적극적인 활용으로 뼈대를 끌어와서 살을 바르는 형식으로 작업.

 

도중에 exit 입력 시 후에 이 입력값을 int로 쓰는 함수에 막혔는지 오류가 났는데, 다행히 튜터님의 도움을 받아 if 문은 위에서부터 차례대로 실행되기 때문에, if exit 부분을 가장 위로 올려주는 것으로 해결했다.

또 break로는 종료되지 않고 재입력 창이 떠서 exit() 함수를 쓰는것으로 해결

 

 

크고 작은 오류들도 겪었지만 그래도 만족스럽게 결과물이 나와서 다행이다!

 

 

p.s. 튜터님의 고려할 요소 작성법

 

비슷하다 비슷해
랜덤 숫자 뽑는 다른방법