[python] 숫자야구 문제풀이

May·2022년 6월 29일
0

python_기초

목록 보기
11/11

숫자야구

computer_number = randint(0,9)
user_number = []  # 사용자가 입력하는 숫자. 자리별로 해야돼서 난 리스트로 만들것
print("0과 9 사이의 서로 다른 숫자 3개를 랜덤한 순서로 뽑았습니다.")
# 2번부터 다시 반복이니 위 문장은 반복문에 들어갈 필요 없음

print("숫자 3개를 하나씩 차례대로 입력하세요.")
user_number.append(input("1번째 숫자를 입력하세요: "))
user_number.append(input("2번째 숫자를 입력하세요: "))
user_number.append(input("3번째 숫자를 입력하세요: "))
# 사용자에게 입력받는 조건 중복되는 숫자 x 범위에서 벗어나는 숫자 입력하면 다시 입력받기

프로젝트 보고 어떤 함수를 써야하고 어떻게 진행해야 할지 대략적으로 적어봤다

1. 숫자 3개 뽑기

from random import randint

def generate_numbers():
    numbers = []
    while len(numbers) < 3:  # 어제 배운 모범답안 활용
        computer_number = randint(0, 9)
        if computer_number not in numbers:  # 이것도! 3개 숫자가 중복되지 않게!!
            numbers.append(computer_number)

    print("0과 9 사이의 서로 다른 숫자 3개를 랜덤한 순서로 뽑았습니다.\n")
    return numbers

print(generate_numbers())

결과

09 사이의 서로 다른 숫자 3개를 랜덤한 순서로 뽑았습니다.

[9, 4, 3]

생각보다... 금방금방 풀어나갔다
어제 로또로 고생 좀 했더니 활용할 수 있는 코드가 많았다

2. 숫자 예측하기

def take_guess():
    print("숫자 3개를 하나씩 차례대로 입력하세요.")
    new_guess = []
    # 1, 2, 3 들어가는걸 반복문으로 해도 될 것 같다는 생각이 듬
    # 어쨌든 입력받는 숫자마다 ① 0~9까지 범위 안에 드는지 확인해야 하고,
    #                      ② 중복되는지 검사도 해야하니까
    
    i = 1

    while i < 4:
        user_input = int(input(f"{i}번째 숫자를 입력하세요: "))
        if (user_input in range(0,10)) and (user_input not in new_guess): # 범위 내 확인, 중복 확인
            new_guess.append(user_input)  # 둘 다 참이어야 입력받을 값 리스트에 저장해줌
        elif user_input not in range(0,10):  # 만약 범위 벗어나면
            print("범위를 벗어나는 숫자입니다. 다시 입력하세요.")
            continue
        elif user_input in new_guess:
            print("중복되는 숫자입니다. 다시 입력하세요.")
            continue
        
        i += 1

    return new_guess

print(take_guess())

결과

결과는 아주 만족스러웠다
continue도 잘 활용했고
제일 뿌듯한 점은 in range(0,10) range를 잘 활용했다는 점이다!!!!!! 내가 생각해냈다니.... 감격 ㅠㅠ

하지만.... 아직 너무 많이 복잡한 내 코드....
모범답안에서는

    while len(new_guess) < 3:  
    👍 i 대신 리스트 갯수로... 어차피 아래에서 리스트값은 채워지니 
    자동적으로 수는 늘어날것...!!
    
        new_num = int(input("{}번째 숫자를 입력하세요: ".format(len(new_guess) + 1)))

	
        if new_num < 0 or new_num > 9:
            print("범위를 벗어나는 숫자입니다. 다시 입력하세요.")
        elif new_num in new_guess:
            print("중복되는 숫자입니다. 다시 입력하세요.")
        else:
            new_guess.append(new_num)
            
     👍 참 기발하다.... 위에 조건이 다 false면 
     마지막 else에 추가하는 코드를 넣다니 ㅠㅠㅠㅠㅠㅠ 
     엄청 간단하게 작성 가능했구만.... ㅠㅠ 반성
    

3. 점수 계산

이제 스트라이크, 볼 갯수를 계산해야 한다
스트라잌, 볼 한꺼번에 하려고 하기보단 하나씩 차근차근 시도했다

👇 볼만 했을때 👇

def get_score(guesses, solution):
    # guesses : 유저가 뽑은 번호 3개, solution : 컴퓨터가 뽑은 랜덤값

    # 볼 수 출력해보자.
    # 숫자의 값은 일치하지만 위치가 틀렸으면 B입니다.
    # -> 사용자가 입력한 숫자 하나씩 랜덤숫자와 비교하기 (in 활용하면 될듯)
    ball_count = 0
    for i in range(len(guesses) - 1):
        if guesses[i] in solution:
            ball_count += 1

    return ball_count


b = get_score([2, 7, 4], [2, 4, 7])

print(b)  # 볼 수 출력

👇 스트라이크만 했을 때 👇

def get_score(guesses, solution):
    # guesses : 유저가 뽑은 번호 3개, solution : 컴퓨터가 뽑은 랜덤값

    # 스트라이크 수 출력해보자.
    # 숫자의 값과 위치가 모두 일치하면 S입니다.
    # -> 랜덤숫자의 인덱스값과 사용자가 입력한 숫자의 인덱스 값이 맞는지 확인
    strike = 0
    for i in range(len(guesses) - 1):
        if guesses[i] == solution[i]:
            strike += 1

    return strike

s = get_score([2, 7, 4], [2, 4, 7])
print(s)  # 스트라이크 수 출력

두 코드를 합치려고 elif를 써봤는데 계속 오답이 나왔다
그래서 분리해서 for문 두개로 작성해봤다

👇 for 2개로 스트라이크, 볼 합쳤을 때 👇

def get_score(guesses, solution):
    # guesses : 유저가 뽑은 번호 3개, solution : 컴퓨터가 뽑은 랜덤값

    strike_count = 0
    ball_count = 0
    
    for i in range(len(guesses) - 1):
        if guesses[i] == solution[i]:
            strike_count += 1
    for i in range(len(guesses) - 1):
        if guesses[i] in solution:
            ball_count += 1
            
    return strike_count, ball_count

s, b = get_score([2, 7, 4], [2, 4, 7])
print(s)  # 스트라이크 수 출력
print(b)

for 두 개 쓰면 결과는 잘 나오는데... 왜 elif 쓸 때는 안나올까 또 고민을 해봤다

range를 건드려봤는데 다른 답이 나왔다
range의 범위가 살짝 헷갈려서 공부한 거 다시 봤더니
-1을 해주면 안됐다
🤬🤬🤬🤬

def get_score(guesses, solution):
    # guesses : 유저가 뽑은 번호 3개, solution : 컴퓨터가 뽑은 랜덤값

    # 스트라이크 수 출력해보자.
    # 숫자의 값과 위치가 모두 일치하면 S입니다.
    # -> 랜덤숫자의 인덱스값과 사용자가 입력한 숫자의 인덱스 값이 맞는지 확인
    strike_count = 0
    ball_count = 0

    for i in range(len(guesses)): # 0, 1, 2 (range,..함수 다시...🤬)
        if guesses[i] == solution[i]:
            strike_count += 1
        elif guesses[i] in solution:
            ball_count += 1

    return strike_count, ball_count

range 범위를 수정하니 elif로 볼 코드 합치니까 잘 실행됐다!
모범답안과도 크게 다르지 않았다!!! 🥰

4. 합치기

ANSWER = generate_numbers()
tries = 0

while 1:
    tries += 1
    s, b = get_score(take_guess(), ANSWER)
    print(f"{s}S {b}B\n")
    if s == 3:
        print(f"축하합니다. {tries}번 만에 숫자 3개의 값과 위치를 모두 맞추셨습니다.")
        break
    else:
        s, b = get_score(take_guess(), ANSWER)
        print(f"{s}S {b}B\n")
        continue

while을 써야할지, for을 써야할지... 근데 조건이 없어서 그냥 무한반복문 사용했다

입력받고 해당 입력값에 얼마나 s가 나왔고 b가 나왔고~ 하는 코드가 매번 출력이 안돼서
print(f"{s}S {b}B\n") 을 3s가 안될 때(else 밑 실행문)도 넣어줬다

3S가 됐는데도 종료되지 않고 다시 입력받길래 else에 있는 s,b 받는걸 없애고 continue만 남겼다

그러니 잘 출력이 됐다!

ANSWER = generate_numbers()
tries = 0
print(ANSWER)
while 1:
    tries += 1
    s, b = get_score(take_guess(), ANSWER)
    print(f"{s}S {b}B\n")
    if s == 3:
        print(f"축하합니다. {tries}번 만에 숫자 3개의 값과 위치를 모두 맞추셨습니다.")
        break
    else:
        continue

모범답안과 비교해봤을 때

ANSWER = generate_numbers()
tries = 0

while True:
    user_guess = take_guess()  # 👍 난 get_score에다가 바로 take_guess를 넣어줬지만 
    						   #    변수처리를 또 해주었다. 아마 보기 쉽게 하신 것 같다
    s, b = get_score(user_guess, ANSWER)

    print("{}S {}B\n".format(s, b))
    tries += 1

    if s == 3:
        break   # 👍 난 아래에 else문을 또 썼지만
                # 모범답안에는 없었다. else는 굳이 필요하지 않았던 코드!

print("축하합니다. {}번 만에 세 숫자의 값과 위치를 모두 맞추셨습니다.".format(tries))

이 숫자야구 문제를 마지막으로 python 기초 코스가 끝났다

정말 뿌듯하고,,, 오랜시간 공부했다
처음엔 print함수 배울 때 이걸 언제 다 배우나 싶었는데...
많이 성장했다
블로그에 공부한 걸 다시 적으면서 복기하고, 다음 문제를 풀 때 복기했던 내용을 활용하면서
실력이 조금이나마 늘어간다는 느낌을 받았다

너무 뿌듯하다!!!!!
python 중급 코스도 빨리 수료해버리자!!!!

profile
ฅ˘◡˘ฅ

0개의 댓글