Udemy課程:[100 Days Of Code(Dr. Angela Yu)](https://www.udemy.com/course/100-days-of-code/)
# Day 7 - Beginner - Hangman
###### tags: `python` `Udemy` `100 Days Of Code`
2021.02.03(Wed.)~2021.02.05(Fri.)
## ● 前言 / 心得
這次上課一樣分成了兩次來上課,因為希望每個步驟都能靠自己寫出來,即便寫得不是很好,但我覺得像這樣放慢步調,最大的收穫就是印相很深刻,畢竟都是先有在自己的腦海中跑過好幾遍、自己動手寫的。
那其實我覺得Day 7真的不難,基本上都是之前課堂上上過的內容,唯一遇到的問題就是,假如我在前一個challenge,雖然有寫出來也成功執行,但到了下個challenge,卻會因為我寫的方式不好,而很難新增功能(像第4點Challenge 3的部分),也是看了老師的解答,才知道說為甚麼剛剛必須用那麼複雜的方式解。
最後則是import的部分,最後一點中有附上python的import官方文件可以參考。
## ● 上課筆記
## 其他
[有關python陣列(list)的官方文件](https://developers.google.com/edu/python/lists#for-and-in)
## 0.code
[Day-7-Hangman-1-Start](https://repl.it/@tina0915tw/Day-7-Hangman-1-Start#main.py)
[Day-7-Hangman-2-Start](https://repl.it/@tina0915tw/Day-7-Hangman-2-Start#main.py)
[Day-7-Hangman-3-Start](https://repl.it/@tina0915tw/Day-7-Hangman-3-Start#main.py)
[Day-7-Hangman-4-Start](https://repl.it/@tina0915tw/Day-7-Hangman-4-Start#main.py)
[Day-7-Hangman-5-Start](https://repl.it/@tina0915tw/Day-7-Hangman-5-Start#main.py)
## 1.Hangman 遊戲解釋
* [Hangman(game)-Wikipedia](https://en.wikipedia.org/wiki/Hangman_(game))
* [Hangman 線上玩](https://hangmanwordgame.com/?fca=1&success=0#/)
要做出一個遊戲得先知道他是如何運作的,所以課程一開始的作業便是畫出流程圖。利用[drawio](https://app.diagrams.net/#G1TCVZz9wNoGjeYSbPdbq5vtVAL50h035L)來完成它,這裡直接放上老師畫的:

## 2.Challenge 1:Picking a Random Words and Checking Answers
[Day-7-Hangman-1-Start](https://repl.it/@tina0915tw/Day-7-Hangman-1-Start#main.py)
> 關鍵字:import random / random choice / list ( str ) / lower( ) / for...in...
第一步驟,先試著完成以下內容:「讓電腦隨機從陣列中讀取任一字串(使用者看不到),然後讓使用者輸入去猜一個字母,如果猜對就顯示right,猜錯則顯示wrong。」
* 我的作法:
```python=
#記得用到隨機random要先import random
import random
word_list = ["aardvark", "baboon", "camel"]
# Todo1:從word_list隨機選取一個單字,並將此變數命名為chosen_word
chosen_word = random.choice(word_list)
# Todo2:讓使用者輸入一個字母,並將其轉為小寫,然後將此變數命名為guess
guess = input("Guess a letter : ").lower()
# Todo3:將Todo1中隨機選取的單字,變成陣列
# (因為我們要將那個單字的每個字母抓出來,去一一與使用者的輸入做對照)
letter = list(chosen_word)
# Todo4:用迴圈去抓陣列中每個字母做對照
for i in letter:
if i == guess:
print("Right")
else:
print("Wrong")
```
* 老師作法:
這才發現我多寫了一行,直接把chosen_word下去跑迴圈就好了,我還先把那個單字弄成陣列,根本多此一舉。
```python=
import random
word_list = ["aardvark", "baboon", "camel"]
chosen_word = random.choice(word_list)
guess = input("Guess a letter: ").lower()
for letter in chosen_word:
if letter == guess:
print("Right")
else:
print("Wrong")
```
## 3.Challenge 2:Replacing Blanks with Guesses
[Day-7-Hangman-2-Start](https://repl.it/@tina0915tw/Day-7-Hangman-2-Start#main.py)
> 關鍵字:append( )
接著第二步驟的部分,把底線功能加進去,將對或錯的顯示方式」改成「對的話,把使用者猜對的字母去替代底線」。
* 我的作法:
```python=
import random
word_list = ["aardvark", "baboon", "camel"]
chosen_word = random.choice(word_list)
print(f'Pssst, the solution is {chosen_word}.')
guess = input("Guess a letter: ").lower()
# 先設立一個空的陣列,等著塞東西進去
display = []
for letter in chosen_word:
if letter == guess:
display.append(guess)
else:
display.append("_")
print(display)
```
* 老師作法:
老師的做法有比較複雜些,用了range跑迴圈、還有用length來抓字母的位置。
```python=
import random
word_list = ["aardvark", "baboon", "camel"]
chosen_word = random.choice(word_list)
print(f'Pssst, the solution is {chosen_word}.')
guess = input("Guess a letter: ").lower()
display = []
word_length = len(chosen_word)
for _ in range(word_length):
display += "_"
for position in range(word_length):
letter = chosen_word[position]
if letter == guess:
display[position] = letter
print(display)
```
## 4.Challenge 3:Checking if the Player has Won
[Day-7-Hangman-3-Start](https://repl.it/@tina0915tw/Day-7-Hangman-3-Start#main.py)
> 關鍵字:while loop / [Python 檢視list中是否含有某元素的方法](https://www.itread01.com/article/1530061283.html)(in)
來到第三步驟,要去判斷使用者是否都有填滿,也就是判斷使用者是否贏了。
那到了這關,我才終於知道老師剛剛為甚麼要用len()去做了,因為像我用append的話,每次迴圈後,就會直接在原本陣列後方增加一個新的display陣列,但如果想要使用取代,勢必要知道取代的位置,因此改用len(),就能輕鬆抓取要取代的位置了。
不過知道這點之後,要完成就變得很簡單了!
* 我的作法:
```python=
import random
word_list = ["aardvark", "baboon", "camel"]
chosen_word = random.choice(word_list)
word_length = len(chosen_word)
print(f'Pssst, the solution is {chosen_word}.')
display = []
for _ in range(word_length):
display += "_"
guess = input("Guess a letter: ").lower()
for position in range(word_length):
letter = chosen_word[position]
if letter == guess:
display[position] = letter
print(display)
# 以下為自己寫的部分
while "_" in display:
guess = input("Guess a letter: ").lower()
for position in range(word_length):
letter = chosen_word[position]
if letter == guess:
display[position] = letter
print(display)
print("You win !")
```
* 老師作法:
老師設了一個變數叫end_of_game,,讓它等於True或是False來判斷遊戲是否結束了。
```python=
import random
word_list = ["aardvark", "baboon", "camel"]
chosen_word = random.choice(word_list)
word_length = len(chosen_word)
print(f'Pssst, the solution is {chosen_word}.')
display = []
for _ in range(word_length):
display += "_"
end_of_game = False
while not end_of_game:
guess = input("Guess a letter: ").lower()
for position in range(word_length):
letter = chosen_word[position]
if letter == guess:
display[position] = letter
print(display)
if "_" not in display:
end_of_game = True
print("You win.")
```
## 5.Challenge 4:Keeping Track of the Player's Lives
[Day-7-Hangman-4-Start](https://repl.it/@tina0915tw/Day-7-Hangman-4-Start#main.py)
* 我的作法:
這題跟老師作法差不多,就不多放了。
```python=
import random
stages = ['''
+---+
| |
O |
/|\ |
/ \ |
|
=========
''', '''
+---+
| |
O |
/|\ |
/ |
|
=========
''', '''
+---+
| |
O |
/|\ |
|
|
=========
''', '''
+---+
| |
O |
/| |
|
|
=========''', '''
+---+
| |
O |
| |
|
|
=========
''', '''
+---+
| |
O |
|
|
|
=========
''', '''
+---+
| |
|
|
|
|
=========
''']
end_of_game = False
word_list = ["ardvark", "baboon", "camel"]
chosen_word = random.choice(word_list)
word_length = len(chosen_word)
lives = 6 #先設血條是6
print(f'Pssst, the solution is {chosen_word}.')
display = []
for _ in range(word_length):
display += "_"
while not end_of_game:
guess = input("Guess a letter: ").lower()
for position in range(word_length):
letter = chosen_word[position]
if letter == guess:
display[position] = letter
#當使用者猜得不在隨機選擇的單字中,則讓lives去減掉1
if guess not in chosen_word:
lives -= 1
#當lives減到為0時,則結束遊戲,並顯示為you lose
if lives == 0:
print("You lose.")
end_of_game = True
print(f"{' '.join(display)}")
if "_" not in display:
end_of_game = True
print("You win.")
#印出與lives相應的hangman狀態,圖在stages陣列裡面
print(stages[lives])
```
## 6.Challenge 5:Improving the User Experience
[Day-7-Hangman-5-Start](https://repl.it/@tina0915tw/Day-7-Hangman-5-Start#main.py)
最後的步驟了!
這次有三個檔案,所以就要知道如何[import](https://www.askpython.com/python/python-import-statement)不同的檔案進去。
納因為要改的內容比較雜,所以直接放上老師的作法。
* 老師作法:
```python=
from replit import clear
import random
import hangman_art
import hangman_words
chosen_word = random.choice(hangman_words.word_list)
word_length = len(chosen_word)
end_of_game = False
lives = 6
print(hangman_art.logo)
print(f'Pssst, the solution is {chosen_word}.')
display = []
for _ in range(word_length):
display += "_"
while not end_of_game:
guess = input("Guess a letter: ").lower()
clear()
if guess in display:
print(f"You've already guessed the {guess}.")
for position in range(word_length):
letter = chosen_word[position]
if letter == guess:
display[position] = letter
if guess not in chosen_word:
print(f"You guessed {guess},that's not in the word.You lose a life.")
lives -= 1
if lives == 0:
end_of_game = True
print("You lose.")
print(f"{' '.join(display)}")
if "_" not in display:
end_of_game = True
print("You win.")
print(hangman_art.stages[lives])
```