고려해야 할 사항
몇 자리 숫자(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 입력 시 후에 이 입력값을 int로 쓰는 함수에 막혔는지 오류가 났는데, 다행히 튜터님의 도움을 받아 if 문은 위에서부터 차례대로 실행되기 때문에, if exit 부분을 가장 위로 올려주는 것으로 해결했다.
또 break로는 종료되지 않고 재입력 창이 떠서 exit() 함수를 쓰는것으로 해결
크고 작은 오류들도 겪었지만 그래도 만족스럽게 결과물이 나와서 다행이다!
p.s. 튜터님의 고려할 요소 작성법