
import random
import re
def Word_Guessing_Game():
quiz = random.choice(word)
print('해당 단어는',len(quiz),'자리입니다.')
print("-"*40)
lives = 9
indices_all=[]
while lives != 0:
one = input("알파벳 하나를 선택해주세요: ")
if one in quiz:
indices = [match.start() for match in re.finditer(one, quiz)]
print("해당 알파벳은",indices,"자리에 있습니다.")
indices_all.extend(indices)
indices_all=list(set(indices_all))
else:
lives=lives-1
print("해당 알파벳이 단어에 포함되어 있지 않습니다.")
print("목숨이",lives,"개 남았습니다.")
if lives==0:
print("YOU LOSE! \U0001F635")
print("-"*40)
if len(indices_all) == len(quiz):
print("단어의 모든 자리를 알아냈습니다!")
print("YOU WIN! \U0001F929")
break
Word_Guessing_Game()


코드 풀이
import random
import re
def Word_Guessing_Game():
quiz = random.choice(word)
print('해당 단어는',len(quiz),'자리 입니다.')
print("-"*40)
random과 re 모듈 사용해 줄거기때문에 import 해주었고 Word_Guessing_Game()이라는 함수를 만들거다.
참고로 word는 단어를 모아둔 리스트로 따로 지정해주었다.
word에서 아무 단어나 하나 뽑아서 quiz로 저장한 뒤, 단어 길이를 알려주었다.
밑에는 실행될 때 구분하기 편하기 위해서 구분선을 넣어주었다.
lives = 9
indices_all=[]
while lives != 0:
one = input("알파벳 하나를 선택해주세요: ")
if one in quiz:
indices = [match.start() for match in re.finditer(one, quiz)]
print("해당 알파벳은",indices,"자리에 있습니다.")
indices_all.extend(indices)
indices_all=list(set(indices_all))
#print(indices_all)
#print(len(indices_all))
목숨이 총 9개 이므로 lives=9로 설정하고, indices_all=[] 이라는 빈 리스트도 하나 만들어 주었다.
이제 while lives !=0 으로 해두어서 lives==0이 될 때 까지 while문을 돌릴거다.
사용자가 선택하는 알파벳을 one 으로 받아준뒤 그 알파벳이 quiz에 포함되는지 아닌지 if else문으로 나누었다.
quiz에 포함되는 알파벳이라면 if 문으로 들어간다.
여기서 처음에는 .find()함수를 사용했다가 find는 처음 나타나는 자리 1개밖에 안알려줘서 다른 방법을 찾아 열심히 구글링 했다. "apple"같은 단어일 경우 "p"를 넣으면 1,2가 나와야 하는데 find를 사용하면 1만 나온다.ㅜㅠ
그래서 찾은 해결책이 re 모듈을 가져와 정규 표현식을 사용하는 것이었다.
re.finditer(one, quiz)는 정규 표현식을 사용하여 quiz 문자열에서 one 문자가 나타나는 모든 위치를 찾고,
match.start()로 해당 위치의 시작 인덱스를 반환한다.
따라서 indices라는 리스트에 quiz속 one이 나타나는 모든 위치를 찾아 추가하는 것이다.
그래서 해당 알파벳이 어디 위치에 있는지 print로 알려주었다.
indices_all은 사용자가 영어단어의 모든 자리를 알아내었는지 확인하기 위해 만들었다.
indies로 자리를 찾고 그걸 indices_all안에 누적해서 저장한다. 모든 자리를 찾아내었으면 indices_all의 길이와 quiz의 길이가 동일할테니 그걸 이용했다.
다만 저 코드에서 indices는 결과가 리스트로 나와서 처음에 .append()를 사용했더니 리스트 안에 리스트가 있는 형태였다.
그래서 .extend()를 사용하여 리스트끼리 하나로 합쳐주는 함수를 사용하였다.
그 다음 문제점은 같은 알파벳을 또 입력하였을때, 숫자가 중복해서 합쳐진다는 점이었다.
a를 넣고 까먹었다가 또 a를 넣었는데 리스트 요소가 늘어나 정답이라고 하면 안되니까.
그래서 set의 원소는 중복되지 않는걸 이용하여 indices_all을 set인 집합의 형태로 바꾸어주고 다시 리스트로 바꿨다.
#print(indices_all) #print(len(indices_all))은 잘되고 있는지 확인한 것
else:
lives=lives-1
print("해당 알파벳이 단어에 포함되어있지않습니다.")
print("목숨이",lives,"개 남았습니다.")
if lives==0:
print("YOU LOSE! \U0001F635")
print("-"*40)
이번엔 one이 quiz에 포함되어 있지 않는 else문이다. 이 경우에는 사용자가 틀린 것이기 때문에 목숨을 1개 깎는다.
그래서 lives=lives-1로 해주었고, 참고로 여기서 lives로 다시 정의해 주지 않으면 lives는 계속 9이다.
print로 틀렸다는 사실과 남은 목숨을 알려준다.
사실 여기서 else문 안의 if문은 추가하지 않아도 lives==0이 되면 while문이 끝나기 때문에 상관은 없다.
하지만 나는 목숨이 끝났으면 졌다는 사실을 알려주고 싶어서 if lives==0으로 조건을 한번 더 넣어준 뒤 멘트를 넣어주었다. 저 "\U0001F635"는 저번에 말한 유니코드인데 이모지도 가능하길래 한번 넣어봤다.
https://unicode.org/emoji/charts/full-emoji-list.html
(파이썬 이모지 리스트)
if len(indices_all) == len(quiz):
print("단어의 모든 자리를 알아냈습니다!")
print("YOU WIN! \U0001F929")
break
마지막으로 위의 if else문을 한번 지났으면 그때의 indices_all과 quiz의 길이를 비교하는 조건문을 지나가게했다.
만약 길이가 같지 않다면 다시 while 반복문을 돌게 되는 것이고, 길이가 같다면 모든 자리의 알파벳을 알아냈다는 뜻이므로 이겼다고 칭찬해준 뒤, break로 while문을 벗어난다.
-끝-
나중에 내가 다시 봤을 때 이해가도록 내 생각의 흐름을 그대로 적었더니 풀이 되게 설명충 같이 길어졌네.
사전캠프 막 시작했을 때 이 문제를 한번 봤을때는 저걸 어떻게 풀지 걱정이었는데, 다시 파이썬 공부하고 막상 풀어보니까 생각보다는 금방 풀었다. 처음 봤을 땐 하루종일 잡고 있을 줄 알았는데 1시간 반 정도? 걸린거 같다.
다 풀고 나니 좀 뿌듯하다. 확실히 코딩 문제는 풀고 나면 쾌감이있다. 도파민 충전되는 느낌ㅋㅋ
이제 다음은 sql 문제이던데, sql은 처음해봐서 잘 할수 있을지 모르겠네ㅜ
'문제풀이 > 스파르타 - 파이썬 문제' 카테고리의 다른 글
[Python] 데이터 전처리 & 시각화 | 실습문제(Matplotlib) (1) | 2024.07.24 |
---|---|
[Python] 데이터 전처리 & 시각화 | 실습 문제(Pandas) (0) | 2024.07.22 |
[Python] 파이썬 기초 | 과제 (0) | 2024.07.10 |
[Python 과제] Lv2. 스파르타 자판기 (0) | 2024.05.27 |
[Python 과제] Lv1. 랜덤 닉네임 생성기 (0) | 2024.05.24 |