#Hangman Game
# 딕셔너리(dictionary) : Data type
# - 리스트와 같은 많은 값의 집합이지만 이 값을 얻어낼 때는 정수 인덱스(딕셔너리에서 인덱스는 키(key)라고 한다.)가 아니라,
# 특정 데이터 타입의 인덱스를 쓸 수 있다.(하지만 대부분의 경우 문자열을 사용한다.)
# - 딕셔너리에서는 {}(대괄호)를 사용한다. key : value
# Dictionary = {'hello':'Hello there, how are you?','chat':'How is the weather?'}
# - 딕셔너리에서 값을 얻어올 때는 리스트와 같이 Dictionary[key] 즉[key] 값으로 얻어온다.
# - 딕셔너리 크기 알아보기 len(Dictionary)
# - 딕셔너리와 리스트의 큰 차이점은 딕셔너리는 첫 번째 아이템이라는 것이 없다. 반면, 리스트는 인덱스가 0으로 시작한다.
# - 딕셔너리의 for문
# for i in Dictionary : i는 키 값을 받게된다. value로 접근은 Dictionary[i]로 값을 알아낼 수 있다.
# - 딕셔너리 keys() 메소드 : key 값을 리스트로 출력
# - 딕셔너리 values() 메소드 : value 값을 리스트로 출력
HANGMANPICS = ['''
+---+
| |
|
|
|
|
=========''', '''
+---+
| |
O |
|
|
|
=========''', '''
+---+
| |
O |
| |
|
|
=========''', '''
+---+
| |
O |
/| |
|
|
=========''', '''
+---+
| |
O |
/|\ |
|
|
=========''', '''
+---+
| |
O |
/|\ |
/ |
|
=========''', '''
+---+
| |
O |
/|\ |
/ \ |
|
=========''', '''
+---+
| |
[O |
/|\ |
/ \ |
|
=========''', '''
+---+
| |
[O] |
/|\ |
/ \ |
|
=========''', '''
+---+
| |
[x] |
/|\ |
/ \ |
|
=========''']
# split() 리스트 메소드 : 문자열 데어터 타입에서 사용하는 메소드
# 단어들은 빈칸으로 구분되어 있다. split()메소드는 이 문자열을 시트로 바꾸며, 단어 하나하나 모두 리스트의 아이템으로 삽입된다.
# 문자열에서 빈칸은 문자열들을 각각 나누고 있는 것이다.
words = {'Colors':'red orange yellow gree blue indigo violet white black brown'.split(), 'Shapes':'square triangle rectangle circle ellipse rhombus pentagon hexagon septagon octagon'.split(), 'Fruits':'apple orange lemon lime pear watermelon grape cherry banana mango strawberry tomato'.split(), 'Animals':'bat bear cat crab deer dog donkey duck eagle fish frog goat lion lizard monkey moose mouse owl panda python rat shark sheep tiger turkey whale wolf zebra'.split() }
def getRandomWord(wordDict):
# This function returns a random string from the passed list of strings.
# random.randint()메소드 : 랜덤의 정수를 뽑아낸다.
# random.choice()메소드 : 문자열과 키로 된 딕셔너리를 넘겨주면 임의의 문자열을 반환한다.
wordKey = random.choice(list(wordDict.keys())) wordIndex = random.randint(0, len(wordDict[wordKey]) - 1) # 랜덤 수를 뽑아 그 수를 인덱스로 지정한다.
# len()메소드는 리스트의 길이를 정수로 반환한다.
return [wordKey,wordDict[wordKey][wordIndex]] # 리스트를 반환한다. # wordDict[][] ->2차원 배열로 생각하면 쉽다. key의 index번째 문자열
def displayBoard(HANGMANPICS, missedLetters, correctLetters, secretWord):
print(HANGMANPICS[len(missedLetters)]) # 틀린 횟수 만큼 행맨의 그림을 출력한다. print('Miss Count: '+str(len(missedLetters))+'/'+str(len(HANGMANPICS)-1)) print('Missed letters:', end=' ') # 줄 바 꿈을 자동으로 붙이지 않고, end을 붙인다.
# for문 : 리스트에 대해 반복 수행 시 편한다.
# while문은 조건이 true인 동안에 반복문을 수행하지만,
# for문은 리스트와 문자열 처리시 간단한다. 각 반복(iteration)에 대해 순서대로 가져온다.
# for 변수이름 in 리스트,문자열,range()
for letter in missedLetters: # 유저가 지금까지 틀린 글자를 출력한다.
# range() 메소드
# - range(int @) : 0부터 @미만의 객체를 반환하는데 주로 list(range(@))로 사용해 리스트에 저장한다.
# - range(int @,int #) : @부터 #미만의 객체를 반환한다.
# list() 메소드
# - 전달 받은 객체를 리스트로 반환한다.
blanks = '_' * len(secretWord) # 정답 길이 만큼 _ _ _ 채우기
for i in range(len(secretWord)): # replace blanks with correctly guessed letters
if secretWord[i] in correctLetters: # correctLetters 안에 secretWord[i]가 있는 지 검사 true이면 들어간다.
blanks = blanks[:i] + secretWord[i] + blanks[i+1:]
# i미만까지 blanks / i번째 secretWord / i+1부터 끝까지 blanks
for letter in blanks: # show the secret word with spaces in between each letter
def getGuess(alreadyGuessed):
# 플레이어가 글자를 입력했는지, 유효할 글자 인지 검사 후 반환한다.
# Returns the letter the player entered. This function makes sure the player entered a single letter, and not something else.
while True: # 무한 루프(infinte loop) 돌기 때문에 break문, return문을 만나야 빠져나올수 있다.
guess = input()
guess = guess.lower() # lower()메소드는 문자열을 소문자로 만들어서 반환한다. <-> upper()
# 다중 if문 : if문, elif(=else if)문, else문 구성
if len(guess) != 1: # 입력길이가 1이상일 경우
print('Please enter a single letter.') elif guess in alreadyGuessed: # 이미 입력한 글자일 경우
print('You have already guessed that letter. Choose again.') elif guess not in 'abcdefghijklmnopqrstuvwxyz': # 문자열 a~z까지에 포함이 안되는 경우
print('Please enter a LETTER.') else: # 위에 포함되지 않는다면 글자를 출력한다.
def playAgain():
# This function returns True if the player wants to play again, otherwise it returns False.
print('Do you want to play again? (yes or no)') return input().lower().startswith('y') # startwith('@')메소드 : @로 시작하는 문자열인지 검사하여 boolean으로 반환한다. 맞으면 True
missedLetters = ''
correctLetters = ''
# 다중 대입문
secretKey, secretWord = getRandomWord(words)
#secretWord = getRandomWord(words)
#secretKey = secretWord[0]
#secretWord = secretWord[1]
gameIsDone = False
while True:
print('The secret word is in the set: '+secretKey) displayBoard(HANGMANPICS, missedLetters, correctLetters, secretWord)
# Let the player type in a letter.
guess = getGuess(missedLetters + correctLetters)
if guess in secretWord: # 추측한 글자가 정답과 일치한가?
# 일치하다면
correctLetters = correctLetters + guess
# Check if the player has won , 정답과 모든 글자가 다 맞는지 확인한다.
foundAllLetters = True
for i in range(len(secretWord)):
if secretWord[i] not in correctLetters: # 맞는 글자가 정답에 없다면
foundAllLetters = False
break
if foundAllLetters: # 정답과 일치한다.
print('Yes! The secret word is "' + secretWord + '"! You have won!') gameIsDone = True # 게임 종료
else: # 틀리다면
missedLetters = missedLetters + guess
# Check if player has guessed too many times and lost
if len(missedLetters) == len(HANGMANPICS) - 1: # 플레이어가 제한 횟수를 넘겨서 졌는지 확인한다.
displayBoard(HANGMANPICS, missedLetters, correctLetters, secretWord)
print('You have run out of guesses!\nAfter ' + str(len(missedLetters)) + ' missed guesses and ' + str(len(correctLetters)) + ' correct guesses, the word was "' + secretWord +'"') gameIsDone = True
# Ask the player if they want to play again (but only if the game is done).
if gameIsDone:
if playAgain(): # Play Again == Ture 게임 재시작
missedLetters = ''
correctLetters = ''
gameIsDone = False
secretKey, secretWord = getRandomWord(words)
#secretWord = getRandomWord(words)
#secretKey = secretWord[0]
#secretWord = secretWord[1]
else: # while문 탈출 및 종료
break