changed 3 years ago
Linked with GitHub

Python實作課程

第二堂課 : Hangman劊子手

2022 / 4 / 08

Tony


遊戲介紹


Hangman,是一個雙人猜單字遊戲。A想一個字,
B嘗試猜A所想的字中的每一個字母。 要猜的字以一列橫線表示。如果B猜中其中一個字母,A便須於該字母出現的所有位置上寫上該字母。
如果猜的字母沒有於該字中出現,A便會畫吊頸公仔的其中一筆。


用電腦做的話

  • 我們沒辦法畫圖(或是說畫圖偏難)
    所以把畫圖改成生命值
  • 每次猜之前
    都先秀出目前題目狀況和用過的字母

開始寫Code


模板:點我


一、選擇單字
從一長串單字中抽出一個可行的單字
可行:中間沒有特殊符號(Ex. '-'),沒有空格

import random def get_valid_word(words): # words是裝一堆單字的陣列 word = random.choice(words) #從word當中挑一個字出來 while '-' in word and ' ' in word: word = random.choice(words) #回傳大寫的單字,本程式全部都用大寫字母操作 return word.upper()

二、設定基本遊戲環境
我們總共需要四種不同的資料:

  1. word:要猜的字
  2. word_letters:word裡面所有種類的字母
  3. alphabet:全部26個字母
  4. used_letters:猜過的字母

先備工具:set()、string.ascii_uppercase

  • set() : 把一個字串變成集合(set),他不會有重複的字元
  • string.ascii_uppercase:26個英文字母組成的字串
    like this : 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
word = get_valid_word(words) word_letters = set(word) #letters in the word alphabet = set(string.ascii_uppercase) used_letters = set() #what the user has guessed

設定基礎遊戲框架
流程:

  1. 輸入要猜的字母
  2. 如果沒猜過,記錄下來
  3. 如果有猜對,寫進答案區
  4. 反之如果猜過,提醒玩家
  5. 如果輸入錯誤,提醒玩家

重複直到遊戲結束


user_letter = input('Type sth : ') # 1. if user_letter in alphabet - used_letters: # 2. used_letters.add(user_letter) if user_letter in word_letters: # 3. word_letters.remove(user_letter) elif user_letter in used_letters: # 4. print('猜過了') else: # 5. print('輸入錯誤,再輸入一遍')

每次輸入之前要讓玩家知道現在答案的長相 & 猜過哪些字母
'-'.join(['A', 'B', 'C']):把該list/set的內容用左邊的東西隔開顯示 → A-B-C

print('You have used the letters :', ' '.join(used_letters)) # 偵測現在單字裡的字母被猜了幾種,猜過就顯示,沒猜過就用 - 代替 word_list = [letter if letter in used_letters else '-' for letter in word] print('Current word: ', ' '.join(word_list))

遊戲終止條件有兩個:

  1. 答案被猜出來
  2. 生命用完

我們先解決第一項,用迴圈即可

while len(word_letters) > 0 : #還沒猜完 ... #剛剛寫的東西們

三、引入生命機制
傳統Hangman中,每猜錯一次就會畫一筆
這邊我們不畫圖,改用生命值取代,每猜錯一次扣一點,從6點開始扣

lives = 6 # 跟剛剛的資料寫在一起 #修改以下code # 1. while len(word_letters) > 0 and lives > 0: # 2. print('You have', lives, 'lives and you have used these letters:', ' '.join(used_letters)) # 3. if user_letter in alphabet - used_letters: used_letters.add(user_letter) if user_letter in word_letters: word_letters.remove(user_letter) else: #猜錯扣點 lives = lives - 1 print('猜錯了!')

跳出迴圈代表猜完OR沒命了
這時候要判斷情況

if lives == 0: # 沒命,涼去 print('GG. Try again.') else: #還有命,代表猜完了,歐耶! print(f'Congratulations! You have guess the word {word}!')

完整code
沒寫完先不要看


''' Process: 1. Set get_valid_word 2. Set up used_letters, alphabet, word, word_letters 3. Test type sth and can it show the used_letters 4. put everything in the while loop 5. Show word list 6. Put 'lives' into the game ''' import random import string # You can add any words you like # Or from this place : 'https://www.randomlists.com/data/words.json' words = ["alike","basic","abandon","embarrassed","alert","circumstance","aim","object","fundamental","Physics","unusual","aboard","original","attractive","research","expression","abrupt","absent","absorbed","absorbing","abstracted","absurd","abundant","massive","accept","acceptable","accessible","accidental","account","accuracy"] def get_valid_word(words): word = random.choice(words) #random;y chooses sth from that list while '-' in word or ' ' in word: word = random.choice(word) return word.upper() def hangman(): word = get_valid_word(words) word_letters = set(word) #letters in the word alphabet = set(string.ascii_uppercase) # {'B', 'J', 'H', 'P', 'F', 'U', 'S', 'C', 'X', 'Q', 'G', 'I', 'N', 'V', 'T', 'A', 'K', 'R', 'Z', 'M', 'L', 'D', 'E', 'W', 'Y', 'O'} used_letters = set() #what the user has guessed lives = 6 # getting user input while len(word_letters) > 0 and lives > 0: #letters used print('You have ', lives, 'lives left and you have used these letters: ', ' '.join(used_letters)) # What current word is (ex. W - R D) word_list = [letter if letter in used_letters else '-' for letter in word] print('Current word: ', ' '.join(word_list)) user_letter = input('Type something : ').upper() #Detect if the user_letter is used or not if user_letter in alphabet - used_letters: used_letters.add(user_letter) # If the letter is one of the letters we need, remove it from the word_letters(means it's being picked) if user_letter in word_letters: word_letters.remove(user_letter) else: lives = lives - 1 # take away a life if wrong print('Letter is not in words.') # 2. If it's already guessed, report. elif user_letter in used_letters: print('You have already used that character. Please try again.') # 3. If it's not the thing in our game, report. else: print('Invalid character. Please try again.') # gets here when len(word_letters) == 0 OR when lives == 0 if lives == 0: print(f'Sorry, you died. The word is {word}.') else: print(f'Congratulation! You have guess the word {word}!') if __name__ == '__main__': hangman()
Select a repo