大家好,又见面了,我是你们的朋友全栈君。
前言
前言
初学者要想成功,一句话,大量的实操,大量的练,乍一看我的这个答案似乎有点敷衍,但是这确实是我接触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精彩内容与资源分享可以看我主页简介。
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/142177.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...