前言#
放下 Python 已經半年了,在期中考試之後,很快就要涉及算法初步了,我覺得通過 Python 的思維,對算法的學習有十分顯著的幫助,便花費幾小時寫了這個 KillAliens 小遊戲。
其中最重要的兩個部分,分別是 分數的持續讀寫並運算
和 隨機事件的生成
這兩個部分,接下來我將詳細講述如何實現整個 KillAliens 小遊戲以及這兩個部分的實現過程。
基於
此 KillAilens 小遊戲,靈感來源於我很久之前寫的簡單的 擊殺外星人.py
這個只有不到 30 行的 簡單文字表達 遊戲,在 KillAilens 裡,記分系統是 擊殺外星人.py
沒有的,同時使用了字典,使用鍵值對實現每個種類的 Ailen 對應一個屬於自己的分數。
擊殺外星人.py
可以在我的 Python 學習倉庫內找到。
補充#
這個小遊戲 初次寫於 2022/5/14 在經過研究後,2022/5/19 修改了算法,提高了線程性能,舊代碼在倉庫中名稱為 KillAliens.py
或 KillAliens_NoComment.py
,新代碼在倉庫中名稱為 KillAliens_V2.py
或 KillAliens_NoComment_V2.py
輸出預覽#
你的名字:
Magneto
你好 Magneto ,接下來讓我為你介紹遊戲中有的 Alien 以及其對應的分數!
擊殺 Big Alien 可以獲得 10 分
擊殺 Middle Alien 可以獲得 5 分
擊殺 A Alien 可以獲得 2 分
擊殺 Small Alien 可以獲得 1 分
當前你的分數是 0 分
如果你想退出遊戲,請輸入 'quit' ,退出遊戲,或輸入其它任意值開始(繼續)遊戲。
開始
請輸入你想要擊殺的 Alien 的 名稱 擊殺成功後,可獲得指定分數
名稱:Big Alien
對應分數:10
名稱:Middle Alien
對應分數:5
名稱:A Alien
對應分數:2
名稱:Small Alien
對應分數:1
請注意,你有概率無法擊殺 Alien 並且會因此結束遊戲,並且對應分數越高,擊殺機率越小。
請輸入對應名稱:
Small Alien
你選擇了 Small Alien
恭喜你 Magneto ,擊殺成功,獲得 1 分
當前總分: 1 分
當前你的分數是 1 分
如果你想退出遊戲,請輸入 'quit' ,退出遊戲,或輸入其它任意值開始(繼續)遊戲。
繼續
請輸入你想要擊殺的 Alien 的 名稱 擊殺成功後,可獲得指定分數
名稱:Big Alien
對應分數:10
名稱:Middle Alien
對應分數:5
名稱:A Alien
對應分數:2
名稱:Small Alien
對應分數:1
請注意,你有概率無法擊殺 Alien 並且會因此結束遊戲,並且對應分數越高,擊殺機率越小。
請輸入對應名稱:
Small Alien
你選擇了 Small Alien
恭喜你 Magneto ,擊殺成功,獲得 1 分
當前總分: 2 分
當前你的分數是 2 分
如果你想退出遊戲,請輸入 'quit' ,退出遊戲,或輸入其它任意值開始(繼續)遊戲。
繼續
請輸入你想要擊殺的 Alien 的 名稱 擊殺成功後,可獲得指定分數
名稱:Big Alien
對應分數:10
名稱:Middle Alien
對應分數:5
名稱:A Alien
對應分數:2
名稱:Small Alien
對應分數:1
請注意,你有概率無法擊殺 Alien 並且會因此結束遊戲,並且對應分數越高,擊殺機率越小。
請輸入對應名稱:
Big Alien
你選擇了 Big Alien
很遺憾 Magneto ,你嘗試擊殺 Big Alien 失敗了,分數清零,退出遊戲。
進程已結束,退出代碼0
代碼預覽#
############################
### Date 2022 May 14 ###
### Author Magneto ###
### Name KillAliens <——>
### Facility Windows 11 ###
### Language Python ###
############################
import random
import time
aliens_name_and_mark = {
'Big Alien': 10,
'Middle Alien': 5,
'A Alien': 2,
'Small Alien': 1
}
Data = {'The_name': '', 'The_marks': 0}
state_one = ['1', '2', '3', '4', '5']
print("歡迎來到 KillAliens 小遊戲,字典已經初始化完成\n接下來請輸入內容\n")
Data['The_name'] = input("你的名字:\n\t")
print(f"你好 \033[94m{Data['The_name']}\033[0m ,接下來讓我為你介紹遊戲中有的 Alien 以及其對應的分數!\n")
time.sleep(1)
for name, marks in aliens_name_and_mark.items():
print(f"\t擊殺 {name} 可以獲得 {marks} 分")
time.sleep(1)
while True:
print(f"\n當前你的分數是 \033[35m{Data['The_marks']}\033[0m 分")
exit_the_game = input("\n如果你想退出遊戲,請輸入 'quit' ,退出遊戲,或輸入其它任意值開始(繼續)遊戲。\n\t")
if exit_the_game == 'quit':
break
print("請輸入你想要擊殺的 Alien 的 \033[94m 名稱 \033[0m 擊殺成功後,可獲得指定分數")
for name, marks in aliens_name_and_mark.items():
print(f"\t名稱:{name}\n\t\t對應分數:{marks}")
print("請注意,你有概率無法擊殺 Alien 並且會因此結束遊戲,並且對應分數越高,擊殺機率越小。")
time.sleep(1)
ChoiseAliens = input("請輸入對應名稱:\n\t")
if ChoiseAliens == 'Small Alien':
state_two = ['1', '2', '3', '4', '5', '6', '7', '8']
The_Random = random.choice(state_two)
print("你選擇了 Small Alien")
if The_Random in state_one:
print(f"恭喜你 \033[94m{Data['The_name']}\033[0m ,擊殺成功,獲得 1 分")
Data['The_marks'] += aliens_name_and_mark['Small Alien']
print(f"當前總分:\033[35m{Data['The_marks']}\033[0m 分\n\n\n")
else:
print(f"很遺憾 \033[94m {Data['The_name']} \033[0m ,你嘗試擊殺 Small Alien 失敗了,分數清零,退出遊戲。")
break
elif ChoiseAliens == 'A Alien':
state_two = ['1', '2', '3', '6', '7', '8']
The_Random = random.choice(state_two)
print("你選擇了 A Alien")
if The_Random in state_one:
print(f"恭喜你 \033[94m{Data['The_name']}\033[0m ,擊殺成功,獲得 2 分")
Data['The_marks'] += aliens_name_and_mark['A Alien']
print(f"當前總分:\033[35m{Data['The_marks']}\033[0m 分\n\n\n")
else:
print(f"很遺憾 \033[94m{Data['The_name']}\033[0m ,你嘗試擊殺 A Alien 失敗了,分數清零,退出遊戲。")
break
elif ChoiseAliens == 'Middle Alien':
state_two = ['1', '2', '6', '7', '8']
The_Random = random.choice(state_two)
print("你選擇了 Middle Alien")
if The_Random in state_one:
print(f"恭喜你 \033[94m {Data['The_name']} \033[0m ,擊殺成功,獲得 5 分")
Data['The_marks'] += aliens_name_and_mark['Middle Alien']
print(f"當前總分:\033[35m{Data['The_marks']}\033[0m 分\n\n\n")
else:
print(f"很遺憾 \033[94m{Data['The_name']}\033[0m ,你嘗試擊殺 Middle Alien 失敗了,分數清零,退出遊戲。")
break
elif ChoiseAliens == 'Big Alien':
state_two = ['1', '6', '7', '8']
The_Random = random.choice(state_two)
print("你選擇了 Big Alien")
if The_Random in state_one:
print(f"恭喜你 \033[94m{Data['The_name']}\033[0m ,擊殺成功,獲得 10 分")
Data['The_marks'] += aliens_name_and_mark['Big Alien']
print(f"當前總分:\033[35m{Data['The_marks']}\033[0m 分\n\n\n")
else:
print(f"很遺憾 \033[94m{Data['The_name']}\033[0m ,你嘗試擊殺 Big Alien 失敗了,分數清零,退出遊戲。")
break
else:
print("您需要輸入對應的\033[94m名稱\033[0m,而不是其它內容。")
代碼分析#
分析說明#
本文的代碼分析,主要是講所使用的主要語法,不會具體分析每行代碼的作用,這需要自行理解。
註釋#
在 Python
中,註釋用 井號
即 #
進行標識。井號後的內容將會被 Python 解釋器
忽略,在本文內附上的代碼是沒有功能性註釋的,只有作者註釋。
模塊引入
代碼 第 9-10 行
分別引入了 random
模塊和 time
模塊。
import random
import time
這兩個模塊的作用分別是隨機處理、使 Python 線程休眠指定時間。
random
的用法曾在 Python 學習日記 – 坐標移動 #random 模塊 中講過,這裡就不再多說。
time
的作用技術使 Python 線程休眠指定時間,而這個時間是按照秒為單位的,讓我們嘗試一下吧:
name = input("你的名字:")
time.sleep(1)
print(f"你好{name}")
這是運行結果
你的名字:Magneto
你好Magneto
上述代碼的第一行在 Python 線程開始運行後,立馬執行,詢問名字,在得到用戶輸入的值後,執行第二行的代碼,Python 解釋器在第二行得到指令,要求休眠 1 秒 進而休眠,在 Python 線程休眠了 1 秒 後,才繼續執行第三行的代碼,輸出名字。
字典 和 for 語句#
在 Python 中,字典是使用 {} 花括號括起來的內容,其中包括兩個內容,分別是鍵 (key) 和值 (value),我們稱之為鍵值對,每一個鍵對應一個值,在 KillAliens 中,第 12-17 行
是一個字典,第 18 行
是一個字典,這兩個字典書寫格式不同,但都是字典,沒有任何區別,第 12-17 行
的書寫格式是為了解決美觀問題,即我們在 Python 中被要求規範書寫代碼,這是一個良好的習慣。
使用字典,是為了方便 for 語句的輸出,讓我們寫一個 字典 和 for 語句的輸出試試吧:
name_and_money = {
'Mark': '10',
'Tom': '20',
}
for name, money in name_and_money.items():
print(f"{name} 有 {money} 元。")
為了方便觀看學習,我將每個鍵值對分開寫了。運行結果:
Mark 有 10 元。
Tome 有 20 元。
for 語句中,有嚴格的順序對應,name
對應鍵,money
對應值,而 items()
是為了循環輸出,直到字典沒有更多的鍵值對可以打印才跳出循環。
而在 for 語句內的 print
可以使用上述對鍵值對的命名,也就是可以使用 name 和 money 對應字典內的鍵和值,進行讀取。
除了 for 語句外,字典也可以被直接讀和寫,但這僅針對值的讀和寫。
讓我們先看讀取
# 首先定義字典
name_and_money = {
'Mark': '10',
'Tom': '20',
}
# 讓我們讀取字典
print(f"他有{name_and_money['Mark']}元")
在 print
中使用 { }
,代表讀取特定區域的內容,而在其中加入 [ ]
,是為了讀取特定區域內的某項特定值。
在上述代碼中,使用 {name_and_money['Mark']}
讀取了 name_and_money
字典中 Mark
這個鍵所對應的值 10 。讓我們來看看輸出結果
他有10元
現在讓我們看看寫入
# 首先定義字典
name_and_money = {
'Mark': 10,
'Tom': 20,
}
# 讓我們讀取原本的字典
print(f"他原來有{name_and_money['Mark']}元")
# 數字+1,即進行運算
name_and_money['Mark'] += 1
# 讓我們讀取新的的字典
print(f"但他現在有{name_and_money['Mark']}元")
讓我們看看輸出結果
他原來有10元
但他現在有11元
值得注意的是,與讀取部分不同,我沒有給這個值帶 引號 ' ' 這是因為,帶上引號就代表了這是一個字串符,需要我們轉換它為浮點數才能繼續進行運算,而不帶引號,就代表了這是一個純粹的數字,可以直接運算了。
當然,這是運算寫入,也可以直接寫入
# 首先定義字典
name_and_boyfriend = {
'Mark': 'Williams',
'Tom': 'Brown',
}
# 讓我們讀取原本的字典
print(f"他的前男友是{name_and_boyfriend['Mark']}")
# 覆蓋值
name_and_boyfriend['Mark'] = 'Wilson'
# 讓我們讀取新的的字典
print(f"他現男友是{name_and_boyfriend['Mark']}")
我們在這裡舉了一個男朋友的例子,直接覆蓋替換了鍵所對的值。
他的前男友是Williams
他現男友是Wilson
這裡覆蓋使用的是字串符,數字也是同樣的道理。
值得注意的是,如此覆蓋的修改是永久性的。
讓我們看看這意味著什麼
# 首先定義字典
name_and_boyfriend = {
'Mark': 'Williams',
'Tom': 'Brown',
}
# for 語句循環
for name, boyfriend in name_and_boyfriend.items():
print(f'{name}曾經的男朋友是{boyfriend}')
# 讓我們讀取原本的字典
print(f"他的前男友是{name_and_boyfriend['Mark']}")
# 覆蓋值
name_and_boyfriend['Mark'] = 'Wilson'
# 讓我們讀取新的的字典
print(f"他現男友是{name_and_boyfriend['Mark']}")
# for 語句循環
for name, boyfriend in name_and_boyfriend.items():
print(f'{name}現在的男朋友是{boyfriend}')
輸出結果
Mark曾經的男朋友是Williams
Tom曾經的男朋友是Brown
他的前男友是Williams
他現男友是Wilson
Tom 作為對照組,是沒有變過的,他的男朋友一直是 Brown,而 Mark 在更改後,for 語句讀取字典也同樣讀取的是修改後的值。
if-elif-else 進階#
KillAlines 中,使用了 if 語句的進階,在 if 語句中,嵌套 if 語句,並且使用了 in 語法,讓我們使用 KillAlines 節選的代碼,進行修改後講解吧。
# 引入 random 隨機模塊
import random
# 對照數字
state_one = ['1', '2', '3', '4', '5']
# 輸入對應的名字,這裡寫的是下面 if 語句所對的名稱
ChoiseAliens = input("請輸入對應名稱:\n\t")
# if 語句判斷,如果 ChoiseAliens 的值是 Small Alien 則執行 if 語句內的內容
if ChoiseAliens == 'Small Alien':
# 實驗組,移交 The_Random 進行隨機處理。
state_two = ['1', '2', '3', '4', '5', '6', '7', '8']
The_Random = random.choice(state_two)
print("你選擇了 Small Alien")
# 嵌套 if 語句,所生成的隨機數如果在對照組中,則返回下值
if The_Random in state_one:
print(f"恭喜你,擊殺成功,獲得 1 分")
# 嵌套 if 語句,子語句,所生成的隨機數如果不在對照組中,則返回下值
else:
print(f"很遺憾,你嘗試擊殺 Small Alien 失敗了")
# if 語句,子語句判斷,如果 ChoiseAliens 的值是 A Alien 則執行
elif ChoiseAliens == 'A Alien':
# 實驗組,移交 The_Random 進行隨機處理。
state_two = ['1', '2', '3', '6', '7', '8']
The_Random = random.choice(state_two)
print("你選擇了 A Alien")
# 嵌套 if 語句,所生成的隨機數如果在對照組中,則返回下值
if The_Random in state_one:
print(f"恭喜你 ,擊殺成功,獲得 2 分")
else:
# 嵌套 if 語句,子語句,所生成的隨機數如果不在對照組中,則返回下值
print(f"很遺憾 ,你嘗試擊殺 A Alien 失敗了")
# if 語句,子語句判斷,如果都輸入內容都不在if和elif中,則返回下值
else:
print("您需要輸入的是指定名稱而不是其它內容。")
為了展示不同的結果,我進行了多次運行。
# 第一次
請輸入對應名稱:
Small Alien
你選擇了 Small Alien
恭喜你,擊殺成功,獲得 1 分
# 第二次運行
請輸入對應名稱:
A Alien
你選擇了 A Alien
很遺憾 ,你嘗試擊殺 A Alien 失敗了
# 第三次運行
請輸入對應名稱:
Magneto
您需要輸入的是指定名稱而不是其它內容。
第一次運行,我們走了 if
的判斷,隨機挑選的一個數,在對照組 state_one
中,所以我們返回了成功,第二次運行,我們走了 elif
判斷,隨機挑選的一個數,不在對照組 state_one
中,所以我們返回了失敗,第三次運行,我們輸入了 Magneto,if
和 elif
判斷都不符合規則,移交 else
處理,返回了提示。
在 KillAliens 中,這樣有效避免了輸入不存在的內容,導致程序報錯。
While 循環#
While 循環在 KillAliens 中,僅僅進行了簡單使用,不進行過多講解,可以查看 Python3 循環語句 | 菜鳥教程 進行學習。
尾聲#
KillAlines 是我寫的一個較為複雜的程序,算是一個簡單的文字小遊戲,僅通過 Python 完成的記分系統、判斷系統、擊殺系統,都是很完善且較為簡單的,但這些數據僅存在線程當中,仍然有很大
此文由 Mix Space 同步更新至 xLog
原始鏈接為 https://fmcf.cc/posts/technology/Python_Notes_4