#Hangman Game
# 다중라인 문자열
# 일반적으로 소스코드에서 문자열을 쓸 때, 문자열은 한 줄에 들어간다.
# 하지만 문자열에서 '''(작은따옴표 3개)를 쓰면 여러 줄에 걸쳐 문자열을 쓸 수 있다.
# 다중라인 문자열에서 줄을 바꾸기 위해 \n을 쓸 필요가 없다. 줄을 바꿀시 자동적으로 줄 바꿈이 된다.
# 상수(Constant Variable) : 프로그램에서 값이 바뀌지 않는 변수, 이름은 대문자로 쓴다.
# 리스트(List) : 데이터 타입, 다른 여러 개의 값을 포함한다.
# 리스트를 쓰면 여러 개의 다른 값을 하나의 변수에 저장할 수 있다.
# 리스트에서 각 아이템에 접근하기 위해서는 [](각 괄호)를 써야 한다.
# []각 괄호 안의 숫자를 인덱스(index)라고 한다. 인덱스의 시작은 0이다.
# 리스트의 아이템의 값을 변경하기 위해 인덱스를 이용해 접근한다.
# 문자열의 연결처럼 리스트도 + 연산자로 리스트 결합(Concatenation)이 가능하다.
# 리스트가 아닌 값을 리스트에 합치려고 하면 append() 메소드를 사용해야 한다.
# in 연산자는 어떤 값이 리스트 안에 있는지 없는지 검사하는 용도다.
# in 연산자는 리스트 뿐만 아니라 문자열에서도 쓸 수 있다.
# 'item값' in 리스트 -> 반환형은 boolean이다.
# del 은 리스트에서 아이템을 삭제할 수 있다.
# del 리스트[인덱스]
# 리스트는 또한 이중 리스트로 만들 수 있다 -> 리스트 = [리스트1,리스트2,리스트3] : 이중 배열로 생각하면 간단하다.
# 리스트의 reverse() 메소드 : 리스트의 아이템 순서를 뒤집어 준다. 앞뒤 전후로 변경된다.
# 리스트의 append('@') 메소드 : 인자로 받은 값을 리스트 맨 뒤에 붙여준다.
# 리스트 자르기(리스트 슬라이스)
# 슬라이스(sliceing) : 리스트에서 중복된 리스트를 또 만드는대 모든 아이템을 가지고 만들 수도 있고, 일부의 아이템을 가지고 만들 수 있다.
# 인덱스를 2개(시작과 끝) 지정하고, 사이에 :을 놓는다.
# [@:] @(인덱스) 부터 가장 끝 아이템 까지 가져온다.
# [:@] 0부터 @(인덱스) 미만 까지 아이템을 가져온다.
# [@:#] @부터 #미만 까지 아이템을 가져온다.
# 메소드는 데이터 타입과 연관된 함수이다. -> 문자열과 리스트는 메소드가 있지만, 정수 데이터 타입은 메소드가 없다.
# 메소드를 가지고 있는 데이터 타입의 값을 객체(Object)라고 한다.
# 메소드(Method)는 함수와 비슷하지만, 항상 값에 붙어 있다.
HANGMANPICS = ['''
+---+
| |
|
|
|
|
=========''', '''
+---+
| |
O |
|
|
|
=========''', '''
+---+
| |
O |
| |
|
|
=========''', '''
+---+
| |
O |
/| |
|
|
=========''', '''
+---+
| |
O |
/|\ |
|
|
=========''', '''
+---+
| |
O |
/|\ |
/ |
|
=========''', '''
+---+
| |
O |
/|\ |
/ \ |
|
=========''']
# split() 리스트 메소드 : 문자열 데어터 타입에서 사용하는 메소드
# 단어들은 빈칸으로 구분되어 있다. split()메소드는 이 문자열을 시트로 바꾸며, 단어 하나하나 모두 리스트의 아이템으로 삽입된다.
# 문자열에서 빈칸은 문자열들을 각각 나누고 있는 것이다.
words = 'ant baboon badger bat bear beaver camel cat clam cobra cougar coyote crow deer dog donkey duck eagle ferret fox frog goat goose hawk lion lizard llama mole monkey moose mouse mule newt otter owl panda parrot pigeon python rabbit ram rat raven rhino salmon seal shark sheep skunk sloth snake spider stork swan tiger toad trout turkey turtle weasel whale wolf wombat zebra'.split()
def getRandomWord(wordList):
# This function returns a random string from the passed list of strings.
wordIndex = random.randint(0, len(wordList) - 1) # 랜덤 수를 뽑아 그 수를 인덱스로 지정한다.
# len()메소드는 리스트의 길이를 정수로 반환한다.
return wordList[wordIndex] # 리스트의 임의의 값을 반환한다.
def displayBoard(HANGMANPICS, missedLetters, correctLetters, secretWord):
print(HANGMANPICS[len(missedLetters)]) # 틀린 횟수 만큼 행맨의 그림을 출력한다.
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 = ''
secretWord = getRandomWord(words)
gameIsDone = False
while True:
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
secretWord = getRandomWord(words)
else: # while문 탈출 및 종료
break