前言
- 1.街霸游戲
- 1.1 KO街霸
- 程式完整原始碼
- 程式的輸出界面
- 1.2 春麗VS巴洛克
- 參考原始碼
- 2.猜謎游戲
- 2.1簡單的猜數字游戲
- 專案要求
- 參考原始碼
- 2.2 進階的猜姓名游戲
- 專案要求
- 參考原始碼
- 2.3基于英文分詞的猜單詞游戲
- 專案要求
- 參考原始碼
- 3.簡潔的小專案
- 3.1 抓取知乎圖片,只用30行代碼
- 3.2 兩個聊天機器人互相聊天
- 3.3 自動寫檢討書
- 3.4 螢屏錄相機,抓屏軟體
- 3.5 制作Gif動圖
前言
初學者要想成功,一句話,大量的實操,大量的練,乍一看我的這個答案似乎有點敷衍,但是這確實是我接觸Python以來,總結出的最有價值的經驗,接下來分享我自己初學時用來練手的經典實戰小專案,適合初學者敲的代碼,

1.街霸游戲
1.1 KO街霸
游戲小劇場
特別調查員春麗突然收到了來自中尉查理的一封郵件,郵件里詳細地說明了神月家族在美國唐人街舉辦的街霸挑戰賽,挑戰的終極boss正是街霸維加,春麗在很小的時候,父親就被維加殘忍地殺害,為報父仇,春麗毅然決然地買好了飛往唐人街的機票,
邪惡的維加正通過催眠術,控制著在擂臺上飲敗的格斗家們在世界各地執行暗殺計劃,
隆遠在印度修行,孤身一人的春麗能在擂臺上挑戰成功嗎?
程式完整原始碼
這是一個針對Python初學者的練手小程式,簡單地模擬春麗與維加的格斗程序,有一定開發經驗的朋友可以對程式進行擴展,比如利用多行程來模擬春麗同時與多人進行格斗,
Python
# 匯入random模塊,執行random模塊中的choice方法來隨機獲取串列中的元素
import random
import time
VEGA_STRATEGIES = ["原地蹲防", "失誤", "回旋攻擊", "失誤", "傷害修正", "回血", "超必殺"]
CHUNLI_KUNFU = ["氣功拳", "旋轉踢", "百裂腳", "霸山天升腳"]
def countdown(seconds=3, message=""):
"""
:param seconds: 倒數的秒數
:param message: 倒計時結束后輸出的提示資訊
:return:
"""
for _ in range(seconds, 0, -1):
_, _ = print(_), time.sleep(1)
else:
print(message)
def generate_prompts(kunfu):
"""
:param kunfu: 街霸格斗選手的格斗招數,為一個串列物件,例如["氣功拳", "旋轉踢"]
:return: 回傳用戶指令輸入的提示資訊,為一個字串物件
"""
prompts = "\n"
for index, value in enumerate(kunfu):
prompts += "<{}>{}".format(index, value)
prompts += "\n輸入<>中的指令來挑戰街霸:__\b\b"
return prompts
def fight():
# 定義整型變數fighter,用來保存街霸維加的血量
vega = 100
# 定義整型變數chunli,用來保存春麗的血量
chunli = 100
blood = 5
prompts = generate_prompts(CHUNLI_KUNFU)
countdown(message="Fight!")
# 執行while回圈,不斷重復執行下面的代碼
while True:
# 春麗或boss其中一人血量為0時就退出戰斗
if vega * chunli == 0:
break
# 執行input函式獲得鍵盤的輸入內容
command = input(prompts)
# 對輸入的字串型別轉換為整型,讀者在輸入時必須輸入有效的數字,否則會拋出例外
try:
command = int(command)
_ = CHUNLI_KUNFU[command]
except (ValueError, IndexError):
print("春麗,這是在戰斗,請輸入正確的戰斗指令!")
continue
print("春麗對街霸使出了{}".format(CHUNLI_KUNFU[command]))
# 使用random模塊中的choice函式,來隨機選擇串列里的值
vega_strategy = random.choice(VEGA_STRATEGIES)
if vega_strategy == "失誤":
print("街霸維加在對戰中反擊失誤!")
else:
print("街霸維加在對戰中對你使用了{}".format(vega_strategy))
if vega_strategy in {"原地蹲防", "回血"}:
if vega_strategy == "回血" and vega < 100:
vega += blood
elif vega_strategy == "失誤":
vega -= blood*2
elif vega_strategy == "傷害修正":
vega -= blood
elif vega_strategy == "超必殺":
chunli -= blood*2
else:
chunli -= blood
chunli = 0 if chunli <=0 else chunli
vega = 0 if vega <=0 else vega
print("\n-*- 春麗現在的血量:{} 維加現在的血量:{} -*-".format(chunli, vega))
time.sleep(3)
if chunli == 0:
print("春麗,你戰敗了!")
else:
print("維加,我今天終于把你打敗,父親泉下有知,可以瞑目了!")
if __name__ == "__main__":
fight()
程式的輸出界面

1.2 春麗VS巴洛克

游戲小劇場
雖然美麗的春麗打敗了維加,但邪惡的影羅組織并未就此覆滅,許多年以后,春麗站在A號街區,會突然想起打敗神月卡琳后的那個下午,當時,身軀高大的巴洛克已將面具摘下,道場中的其他四名影子殺手,形如雕塑,酷似木偶…春麗經過這場殘酷的戰斗以后,在背部留下了一道很長的月牙形傷痕,
在本節程式實戰中,通過多行程的方式來模擬春麗一人對抗影羅組織的五名邪惡殺手,
參考原始碼
通過多行程+佇列來模擬春麗1VS5的街霸游戲挑戰賽:
from multiprocessing import Process, Queue
import random
class Fighter:
def __init__(self, name, blood = 100, justice = True, kungfu = None, enemies = 1):
"""
:param name: 表示該fighter的姓名
:param blood: 表示該fighter的血量
:param justice: 布爾型別,表示該fighter是否代表正義的一方
:param kungfu: 表示該fighter的格斗技能
:param enemies: 表示該fighter對抗的敵人數
"""
self.__name = name
self.__blood = blood
self.__justice = justice
self.__kungfu = kungfu
self.__enemies = enemies
def attack(self):
kungfu, harm = None, 0
if self.__blood > 0:
kungfu = random.choice(list(self.__kungfu.keys()))
harm = self.__kungfu[kungfu]
return kungfu, harm
@property
def name(self):
return self.__name
@property
def blood(self):
return self.__blood
@blood.setter
def blood(self, value):
self.__blood = value
@property
def enemies(self):
return self.__enemies
@enemies.setter
def enemies(self, count):
self.__enemies = count
@property
def justice(self):
return self.__justice
def fight(fighter, justice_attacks, injustice_attacks):
"""
:param fighter: Fighter物件
:param justice_attacks: 佇列型別,表示春麗的攻擊
:param injustice_attacks: 佇列型別,表示巴洛克等殺手的攻擊
:return:
"""
while True:
kungfu, harm = fighter.attack()
attack = {"name": fighter.name, "kungfu": kungfu,
"harm": harm, "blood": fighter.blood}
if fighter.justice:
# 通過justice_attacks代表的佇列,向以巴洛克為首的殺手們發起一個攻擊
justice_attacks.put(attack)
if fighter.blood == 0:
break
# 從justice_attacks代表的訊息佇列中,接收對方的一個攻擊
attack = injustice_attacks.get()
# 如果對方攻擊時的blood值為0,表示對方已被擊敗
if attack["blood"] == 0:
# 減去敵人數
fighter.enemies -= 1
if fighter.enemies == 0:
# 敵人已全部被擊敗, 退出戰斗!
break
else:
continue
else:
# 通過justice_attacks代表的佇列,向春麗發起一個攻擊
injustice_attacks.put(attack)
if fighter.blood == 0:
break
# 從justice_attacks佇列中接收春麗發起的攻擊
attack = justice_attacks.get()
# 如果春麗攻擊時的血量為0,說明春麗已經被擊敗
if attack["blood"] == 0:
"""
春麗已經戰敗,通過justice_attacks對列向己方的殺手們進行訊息轉發,
同時退出戰斗
"""
justice_attacks.put({"blood": 0})
break
kungfu, harm = fighter.attack()
"""
如果在回擊的程序中反擊的傷害大于對方的傷害值,
則加上已有的血量值來實作回血的功能,否則將血量減去對應的傷害值
"""
fighter.blood += harm - attack["harm"]
if fighter.blood <= 0:
fighter.blood = 0
elif fighter.blood > 100:
fighter.blood = 100
if fighter.blood > 0:
print("{} 獲得了勝利!!!".format(fighter.name))
if __name__ == "__main__":
# 定義chunli_kungfu來保存春麗的招式及對應的傷害值
chunli_kungfu = {
"失誤": 0,
"原地蹲防": 5,
"龍星落": 10,
"氣功拳": 15,
"旋轉踢": 20,
"百裂腳": 20,
"霸山天升腳": 20,
"超必殺-千翼氣功掌": 25
}
# 定義baroque_kungfu來保存殺手巴洛克的招式及對應的傷害值
baroque_kungfu = {
"失誤": 0,
"傷疤之恨": 15,
"閃光漩渦": 20,
"飛翔巴塞羅那": 20,
"紅色沖擊": 20
}
# 定義來shadow_kungfu保存影子殺手的攻擊策略及對應的傷害值
shadow_kungfu = {
"失誤": 0,
"暗器": 10,
"毒藥": 15,
"炸彈": 20
}
processes = []
fighters = [
Fighter(name="春麗", kungfu=chunli_kungfu, enemies=5),
Fighter(name="巴洛克", kungfu=baroque_kungfu, justice=False),
Fighter(name="影子殺手1", kungfu=shadow_kungfu, justice=False),
Fighter(name="影子殺手2", kungfu=shadow_kungfu, justice=False),
Fighter(name="影子殺手3", kungfu=shadow_kungfu, justice=False),
Fighter(name="影子殺手4", kungfu=shadow_kungfu, justice=False)
]
justice_attacks = Queue()
injustice_attacks = Queue()
for fighter in fighters:
process = Process(target=fight, args=(fighter, justice_attacks, injustice_attacks))
processes.append(process)
[process.start() for process in processes]
[process.join() for process in processes]
2.猜謎游戲

2.1簡單的猜數字游戲
專案要求
實作一個簡單的猜數字游戲:程式啟動時獲取一個隨機值,根據用戶的輸入提示大了還是小了,如果用戶輸入的整數與隨機值相等,則退出回圈,
通過random模塊randint方法獲取一個隨機值,通過input函式獲取用戶的輸入,
代碼示例:
# 匯入random模塊
import random
# 獲取從1到100000之間的亂數
random_number = random.randint(1, 1000000)
# 執行input方法獲取用戶的輸入,input的回傳值為字串型別,通過int()將其轉換為整型
guess_number = int(input("Please enter the number:____\b\b\b\b"))
參考原始碼
import time
import random
def get_random_number(start=0, end=10**3):
return random.randint(start, end)
def countdown(seconds=3, message=""):
"""
:param seconds: 倒數的秒數
:param message: 倒計時結束后輸出的提示資訊
:return:
"""
for _ in range(seconds, 0, -1):
_, _ = print(_), time.sleep(1)
else:
print(message)
def serve_forever():
random_number = get_random_number()
countdown(message="猜數字游戲開始,Go!!!")
while True:
try:
guess_number = int(input("請輸入你猜的數字:"+"_"*4+"\b"*4))
except ValueError:
print("請輸入合法的數字!")
continue
if guess_number != random_number:
_ = print("你輸入的數字大了") if guess_number > random_number else print("你輸入的數字小了")
continue
print("恭喜你猜對了!!!")
if input("按鍵盤任意鍵繼續玩猜數字游戲或輸入quit退出游戲:____\b\b\b\b").lower() == "quit":
break
else:
random_number = get_random_number()
print("游戲已被終止,再見!!!")
if __name__ == "__main__":
serve_forever()
程式的輸出界面


2.2 進階的猜姓名游戲
專案要求
定義一個人名集合,例如 {“王祖賢”, “李嘉欣”, “李嘉誠”, “劉德華”, “葉倩文”,“葉倩倩”, “王李丹妮”},如果用戶的輸入前綴匹配第一個字,則提示"不錯,有點接近了",前綴匹配前面兩個字,則提示"厲害,比較接近了",完全匹配則提示"哇塞,你是個猜姓名天才,請收下我的膝蓋",
構造該Trie結構的演算法邏輯很簡單,以第一次構造為例:
將姓名中的第一個字作為鍵插入到指標指向的空字典中,鍵值為一個空字典,然后將指標指向鍵值所對應的空字典,接著將姓名中的第二個字作為鍵插入到指標指向的空字典中,鍵值為一個空字典,同樣需要將指標指向鍵值所對應的空字典,不斷重復這樣的程序,直到遍歷完姓名中的所有字符,
簡化的代碼實體:
name = "王八蛋"
trie = {}
trie[name[0]] = {}
trie[name[0]][name[1]] = {}
trie[name[0]][name[1]][name[2]] = {}
這樣在查找用戶的輸入是否包含某姓名的前綴時,只需要遍歷用戶輸入的字符,然后在構造好的Trie結構中進行查找,
參考原始碼
import time
def countdown(seconds=3, message=""):
"""
:param seconds: 倒數的秒數
:param message: 倒計時結束后輸出的提示資訊
:return:
"""
for _ in range(seconds, 0, -1):
_, _ = print(_), time.sleep(1)
else:
print(message)
def build_lookup_table(data):
"""
:param data: a set of names, e.g: {"王祖賢", "李嘉欣"}
:return: lookup table e.g:{'王': {'祖': {'賢': {}}}, '李': {'嘉': {'欣': {}}}}
"""
lookup_table = {}
for name in data:
lookup_table_ = lookup_table
for char in name:
if char not in lookup_table_:
lookup_table_[char] = {}
lookup_table_ = lookup_table_[char]
return lookup_table
def guess_name():
stars = {"王祖賢", "李嘉欣", "李嘉誠", "劉德華", "葉倩文", "葉倩倩", "王李丹妮"}
# 構造一個查找表
lookup_table = build_lookup_table(stars)
countdown(3, "猜姓名游戲開始,Go!!!")
messages = {0: "不要瞎猜好嗎?", 1: "不錯,有點接近了", 2: "厲害,比較接近了",
66: "哇塞,你是個猜姓名天才,請收下我的膝蓋"}
end = 2
while True:
name = input("請輸入你要猜的姓名:____\b\b\b\b")
if name in stars:
print(messages[66])
if input("按鍵盤任意鍵繼續玩猜數字游戲或輸入quit退出游戲:____\b\b\b\b").lower() == "quit":
break
else:
lookup_table_ = lookup_table
index = 0
for word in name:
if word in lookup_table_:
lookup_table_ = lookup_table_[word]
index = index+1 if index < end else index
else:
break
print(messages[index])
if __name__ == "__main__":
guess_name()
程式的輸出界面


2.3基于英文分詞的猜單詞游戲
專案要求
① 對某一篇英文文章進行分詞,以獲取一個英語詞典
② 如果用戶輸入的單詞在詞典中,則提示"你是個猜單詞天才,請收下我的膝蓋"
③ 如果用戶的輸入前綴匹配第一個字母,則提示"不錯,有點接近了",前綴匹配前面兩個字母,則提示"厲害,比較接近了"
演算法邏輯如下:
① 定義一個布爾型別的標記變數,初始情況下為True,表示已完成單詞的拆分
② 遍歷英文字串,如果當前字符為分隔符且尚未切分,則開始分詞:將起始位置的索引與分隔符位置之前的所有字符進行拆分
③ 如果當前字符不是分隔符且已拆分,則將標記變數更新為False, 同時更新拆分的起始位置

參考原始碼
import time
def cut(content, language=0):
"""
:param content: 待分詞的英文字串,例如:"when a great dream shows up"
:param language: 0表示對英文進行分詞
:return: 回傳分詞后的詞典,是一個集合型別, 例如:{"an", "and"}
"""
dictionary = set()
length = len(content)
# 定義英文中的分隔符
stop_words = {";", " ", "\n", ".", "!"}
if language == 0:
begin = 0
# 標記變數,初始情況下表示已拆分
is_cutted = True
for index in range(length):
# 如果當前字符為分隔符
if content[index] in stop_words:
# 且未拆分
if not is_cutted:
dictionary.add(content[begin:index])
is_cutted = True
continue
elif is_cutted:
begin = index
is_cutted = False
return dictionary
def build_trie(dictionary):
"""
:param dictionary:英文詞典集合
:return: 單詞查找樹,系字典物件
"""
trie = {"root": {}}
for word in dictionary:
next = trie["root"]
for char in word:
if char not in next:
next[char] = {}
next = next[char]
else:
next[0]=0
return trie
def countdown(seconds=3, message=""):
"""
:param seconds: 倒數的秒數
:param message: 倒計時結束后輸出的提示資訊
:return:
"""
for _ in range(seconds, 0, -1):
_, _ = print(_), time.sleep(1)
else:
print(message)
def guess_words():
content = "when a great dream shows up, grab it!"
dictionary = cut(content)
lookup_table = build_trie(dictionary)
countdown(3, "猜單詞游戲開始,Go!!!")
messages = {0: "不要瞎猜好嗎?", 1: "不錯,有點接近了", 2: "厲害,比較接近了",
66: "哇塞,你是個猜單詞天才,請收下我的膝蓋"}
end = 2
while True:
word = input("請輸入你要猜的單詞:____\b\b\b\b")
if word in dictionary:
print(messages[66])
if input("按鍵盤任意鍵繼續玩猜單詞游戲或輸入quit退出游戲:____\b\b\b\b").lower() == "quit":
break
else:
lookup_table_ = lookup_table["root"]
index = 0
for ch in word:
if ch in lookup_table_:
lookup_table_ = lookup_table_[ch]
index = index+1 if index < end else index
else:
break
print(messages[index])
if __name__ == "__main__":
guess_words()
程式的輸出界面


3.簡潔的小專案
(偷懶上線)
3.1 抓取知乎圖片,只用30行代碼
from selenium import webdriver
import time
import urllib.request
driver = webdriver.Chrome()
driver.maximize_window()
driver.get("https://www.zhihu.com/question/29134042")
i = 0
while i < 10:
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
time.sleep(2)
try:
driver.find_element_by_css_selector('button.QuestionMainAction').click()
print("page" + str(i))
time.sleep(1)
except:
break
result_raw = driver.page_source
content_list = re.findall("img src=\"(.+?)\" ", str(result_raw))
n = 0
while n < len(content_list):
i = time.time()
local = (r"%s.jpg" % (i))
urllib.request.urlretrieve(content_list[n], local)
print("編號:" + str(i))
n = n + 1
3.2 兩個聊天機器人互相聊天
from time import sleep
import requests
s = input("請主人輸入話題:")
while True:
resp = requests.post("http://www.tuling123.com/openapi/api",data={"key":"4fede3c4384846b9a7d0456a5e1e2943", "info": s, })
resp = resp.json()
sleep(1)
print('小魚:', resp['text'])
s = resp['text']
resp = requests.get("http://api.qingyunke.com/api.php", {'key': 'free', 'appid':0, 'msg': s})
resp.encoding = 'utf8'
resp = resp.json()
sleep(1)
print('菲菲:', resp['content'])
#網上還有一個據說智商比較高的小i機器人,用爬蟲的功能來實作一下:
import urllib.request
import re
while True:
x = input("主人:")
x = urllib.parse.quote(x)
link = urllib.request.urlopen(
"http://nlp.xiaoi.com/robot/webrobot?&callback=__webrobot_processMsg&data=%7B%22sessionId%22%3A%22ff725c236e5245a3ac825b2dd88a7501%22%2C%22robotId%22%3A%22webbot%22%2C%22userId%22%3A%227cd29df3450745fbbdcf1a462e6c58e6%22%2C%22body%22%3A%7B%22content%22%3A%22" + x + "%22%7D%2C%22type%22%3A%22txt%22%7D")
html_doc = link.read().decode()
reply_list = re.findall(r'\"content\":\"(.+?)\\r\\n\"', html_doc)
print("小i:" + reply_list[-1])

3.3 自動寫檢討書
import random
import xlrd
ExcelFile = xlrd.open_workbook(r'test.xlsx')
sheet = ExcelFile.sheet_by_name('Sheet1')
i = []
x = input("請輸入具體事件:")
y = int(input("老師要求的字數:"))
while len(str(i)) < y * 1.2:
s = random.randint(1, 60)
rows = sheet.row_values(s)
i.append(*rows)
print(" "*8+"檢討書"+"\n"+"老師:")
print("我不應該" + str(x)+",", *i)
print("再次請老師原諒!")
'''
以下是樣稿:
請輸入具體事件:抽煙
老師要求的字數:200
檢討書
老師:
我不應該抽煙, 學校一開學就三令五申,一再強調校規校紀,提醒學生不要違反校規,可我卻沒有把學校和老師的話放在心上,沒有重視老師說的話,沒有重視學校頒布的重要事項,當成了耳旁風,這些都是不應該的,同時也真誠地希望老師能繼續關心和支持我,并卻對我的問題酌情處理, 無論在學習還是在別的方面我都會用校規來嚴格要求自己,我會把握這次機會, 但事實證明,僅僅是熱情投入、刻苦努力、鉆研學業是不夠的,還要有清醒的政治頭腦、大局意識和紀律觀念,否則就會在學習上迷失方向,使國家和學校受損失,
再次請老師原諒!
'''
3.4 螢屏錄相機,抓屏軟體
from time import sleep
from PIL import ImageGrab
m = int(input("請輸入想抓屏幾分鐘:"))
m = m * 60
n = 1
while n < m:
sleep(0.02)
im = ImageGrab.grab()
local = (r"%s.jpg" % (n))
im.save(local, 'jpeg')
n = n + 1

3.5 制作Gif動圖
from PIL import Image
im = Image.open("1.jpg")
images = []
images.append(Image.open('2.jpg'))
images.append(Image.open('3.jpg'))
im.save('gif.gif', save_all=True, append_images=images, loop=1, duration=1, comment=b"aa

分享到這結束了,感謝觀看哦,最后說一句,要想成功就要多去練多去敲,重中之重,
更多Python精彩內容與資源分享可以看我主頁簡介,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/290183.html
標籤:其他
