20244112 实验四《Python程序设计》实验报告
20244112 2024-2025-4 《Python程序设计》实验四报告
课程:《Python程序设计》
班级: 2441
姓名: 李其鲔
学号:20244112
实验教师:王志强
实验日期:2025年5月13日
必修/选修: 公选课
1.实验内容
Python综合应用:爬虫、数据处理、可视化、机器学习、神经网络、游戏、网络安全等。
(1)编写从社交网络爬取数据,实现可视化舆情监控或者情感分析。
(2)利用公开数据集,开展图像分类、恶意软件检测等
(3)利用Python库,基于OCR技术实现自动化提取图片中数据,并填入excel中。
(4)爬取天气数据,实现自动化微信提醒
(5)利用爬虫,实现自动化下载网站视频、文件等。
(6)编写小游戏:坦克大战、贪吃蛇、扫雷等等
注:在Windows/Linux系统上使用VIM、PDB、IDLE、Pycharm等工具编程实现。
2. 实验过程
(1)在本次实验当中,我准备使用Python程序编写一个小游戏。为了使用程序语言设计出这个小游戏,我需要首先写出游戏规则与流程。
a.游戏使用20张牌,包括6张Queen、6张King、6张Ace和2张Joker,Joker可以作为任何牌使用。
b.每轮游戏开始前,会随机给玩家发放包括Q、K、A、Joker在内的五张牌,电脑自己也同样随机抽取五张牌,但不告诉玩家。同时随机指定一张牌作为主牌,玩家需要根据主牌出牌,并可以撒谎。
c.由电脑选择是否质疑出牌玩家,如果电脑质疑,根据是否质疑成功决定谁进行俄罗斯轮盘赌;如果电脑不质疑,则由电脑出牌,玩家选择是否质疑。
d.盘赌成功则显示不中枪,游戏进入下一轮;盘赌失败则显示中枪,游戏失败。
e.在一个回合内,如果玩家和电脑都没有选择质疑,那么这个回合继续,玩家和电脑上一轮出的手牌这一轮不能再用,然后再按之前的步骤进行,直到有一方的手牌出完,那么另一方进行盘赌。
f.游戏进入下一轮时,重新发放手牌以及重新指定主牌。但是中枪机会不改变,也就是说六次机会用了一次,如此经过六轮则必有一人中枪。
(2)为了在Pycharm中模拟出这样一个使用扑克牌的游戏,我需要先对扑克牌进行定义。创建一个类来表示扑克牌,把牌的点数(Q、K、A、Joker)这个属性封装在类里面。打印牌的点数这个对象时,按照__str__方法里定义的格式输出。

(3)然后对于游戏中所有的手牌牌堆进行定义,包括6张Queen、6张King、6张Ace和2张Joker。用列表存储Card对象,通过random.shuffle实现洗牌,pop()方法抽牌,这样游戏基本的洗牌发牌功能就已经完备。

(4)在游戏的扑克牌以及牌堆已经被定义好了后,现在需要对玩家的一系列行为进行编写。玩家需要能够看到自己每轮的手牌,如何进行出牌,同时还需要对玩家所出的牌进行检验。那么使用列表推导式生成字符串列表,结合str()转换对象,这样来显示每一轮玩家被发到的手牌。第二,用sorted和reverse=True确保索引从大到小删除,避免索引错位,同时记录出牌历史,以免打出的手牌依旧保留。在检查玩家的手牌时,通过len()比较列表长度,快速判断操作合法性,避免无效操作。


(5)在上述的游戏基本配置编写完成后,现在我需要根据所制定的游戏规则进行游戏流程编写。首先,我需要对每一轮游戏的主牌进行定义编写,让程序能够在每轮开始时抽取一张牌面作为主牌。然后,在每轮开始时用方法封装初始化逻辑,通过实例变量传递状态,达到刷新游戏的效果。


(6)在玩家回合,使用循环和条件判断确保玩家输入合法,以输入0-4来代替玩家所要打出的牌。

(7)在电脑回合,通过min()和sample()方法限制出牌数量,使用random语言来决定电脑打出的牌。

(8)在出牌后的质疑阶段,如果是电脑选择是否质疑,那么使用根据打出的牌数来决定是否质疑,同时采用if条件语句来进行编写,通过random.random()生成随机数。如果是玩家选择是否质疑,那么用while循环使玩家输入有效选项。

(9)在质疑成功后的盘赌环节,同样使用概率以及if条件语句进行程序编写,用随机数模拟轮盘赌结果,通过input()暂停程序。

(10)最后,用while循环控制多轮游戏,通过条件判断决定游戏胜负,通过print输出游戏信息,从而完成程序编写。

3. 实验代码及运行结果
(1)实验代码
import random
class Card:
"""扑克牌类,表示一张牌"""
def __init__(self, rank):
self.rank = rank # 牌面:Q, K, A, Joker
def __str__(self):
return self.rank
class Deck:
"""牌堆类,管理游戏使用的20张牌"""
def __init__(self):
self.cards = []
# 添加6张Q、6张K、6张A
for _ in range(6):
self.cards.append(Card("Q"))
self.cards.append(Card("K"))
self.cards.append(Card("A"))
# 添加2张Joker
self.cards.append(Card("Joker"))
self.cards.append(Card("Joker"))
random.shuffle(self.cards) # 洗牌
def draw(self, num):
"""从牌堆中抽取指定数量的牌"""
return [self.cards.pop() for _ in range(num)]
def is_empty(self):
"""检查牌堆是否为空"""
return len(self.cards) == 0
class Player:
"""玩家类,管理玩家的手牌和状态"""
def __init__(self, name):
self.name = name
self.hand = []
self.used_cards = [] # 已使用的牌
self.played_history = [] # 出牌历史:[(cards, is_lie), ...]
def receive_cards(self, cards):
"""接收牌"""
self.hand.extend(cards)
def show_hand(self):
"""显示玩家手牌"""
return [str(card) for card in self.hand]
def play_cards(self, indices):
"""打出指定位置的牌"""
played = [self.hand.pop(i) for i in sorted(indices, reverse=True)]
self.used_cards.extend(played)
# 记录出牌历史
actual_main_count = sum(1 for card in played if card.rank == self.main_card.rank or card.rank == "Joker")
is_lie = actual_main_count < len(played)
self.played_history.append((played, is_lie))
return played, is_lie
def has_cards(self, count):
"""检查玩家是否有足够的牌"""
return len(self.hand) >= count
def can_play(self):
"""检查玩家是否还能出牌"""
return len(self.hand) > 0
class Game:
"""游戏主类,管理游戏流程和逻辑"""
def __init__(self):
self.deck = Deck()
self.player = Player("玩家")
self.computer = Player("电脑")
self.current_round = 1
self.bullet_chamber = random.randint(1, 6) # 轮盘赌的子弹位置
self.current_chamber = 1 # 当前轮盘位置
self.main_card = None # 当前主牌
def setup_round(self):
"""设置新一轮游戏"""
print(f"\n★☆★☆★☆ 第{self.current_chamber} 轮 ☆★☆★☆★")
# 重置牌堆和玩家手牌
self.deck = Deck()
self.player.hand = []
self.computer.hand = []
self.player.used_cards = []
self.computer.used_cards = []
self.player.played_history = []
self.computer.played_history = []
# 发牌
player_cards = self.deck.draw(5)
computer_cards = self.deck.draw(5)
self.player.receive_cards(player_cards)
self.computer.receive_cards(computer_cards)
# 随机选择主牌
self.main_card = self.deck.draw(1)[0]
print(f"本轮主牌是: {self.main_card}")
print(f"你的手牌是: {self.player.show_hand()}")
# 设置玩家和电脑的主牌引用
self.player.main_card = self.main_card
self.computer.main_card = self.main_card
def player_turn(self):
"""玩家回合"""
if not self.player.can_play():
return [], False
while True:
try:
# 玩家选择要打出的牌
print("\n请选择要打出的牌的位置 (0-4),用空格分隔(例如:0 2 4)")
for i, card in enumerate(self.player.show_hand()):
print(f"{i}: {card}")
choice = input("输入数字选择牌: ").strip()
if not choice:
print("你必须打出至少一张牌!")
continue
indices = [int(x) for x in choice.split()]
# 检查选择是否有效
if all(0 <= i < len(self.player.hand) for i in indices) and len(set(indices)) == len(indices):
played_cards, is_lie = self.player.play_cards(indices)
print(f"你打出了 {len(played_cards)} 张牌。")
return played_cards, is_lie
else:
print("无效的选择,请重新输入。")
except ValueError:
print("请输入有效的数字。")
def computer_turn(self):
"""电脑回合"""
if not self.computer.can_play():
return [], False
# 电脑随机决定打出1-3张牌
max_cards = min(3, len(self.computer.hand))
if max_cards < 1:
return [], False
card_count = random.randint(1, max_cards)
indices = random.sample(range(len(self.computer.hand)), card_count)
played_cards, is_lie = self.computer.play_cards(indices)
print(f"\n电脑打出了 {card_count} 张牌,声称都是 {self.main_card}。")
return played_cards, is_lie
def computer_decision(self, player_cards_count):
"""电脑决定是否质疑"""
# 电脑根据玩家打出的牌数决定质疑概率
# 牌数越多,质疑概率越高
challenge_probability = 0.3 + (player_cards_count - 1) * 0.15
will_challenge = random.random() < challenge_probability
if will_challenge:
print("\n电脑质疑你。")
return True
else:
print("\n电脑相信了你。")
return False
def player_decision(self):
"""玩家决定是否质疑"""
while True:
choice = input("你要质疑电脑吗?(y/n): ").lower()
if choice == 'y':
print("\n你质疑了电脑。")
return True
elif choice == 'n':
print("\n你相信了电脑。")
return False
else:
print("请输入 y 或 n。")
def russian_roulette(self, player_name):
"""俄罗斯轮盘赌"""
print(f"\n{player_name} 必须进行俄罗斯轮盘赌!")
input("按Enter键转动轮盘...")
print(f"轮盘转动... 停在位置 {self.current_chamber}")
# 检查是否中枪
if self.current_chamber == self.bullet_chamber:
print(f"砰!{player_name} 中枪了!")
return False # 游戏结束
else:
print(f"咔嗒... {player_name} 安全!")
self.current_chamber += 1
return True # 继续游戏
def handle_player_win(self):
"""处理玩家获胜的情况"""
print("\n恭喜!你出完了所有手牌,你胜利了!")
# 电脑可以选择是否质疑
challenge = self.computer_decision(len(self.player.used_cards))
if challenge:
# 检查玩家最后一次出牌是否撒谎
if self.player.played_history and self.player.played_history[-1][1]:
print("电脑质疑正确。")
result = self.russian_roulette(self.player.name)
return result
else:
print("电脑质疑错误。")
result = self.russian_roulette(self.computer.name)
return result
else:
# 电脑不质疑,玩家直接获胜
print("电脑选择不质疑,你赢得本轮胜利!")
result = self.russian_roulette(self.computer.name)
return result
def handle_computer_win(self):
"""处理电脑获胜的情况"""
print("\n电脑出完了所有手牌,你输了。")
# 玩家可以选择是否质疑
challenge = self.player_decision()
if challenge:
# 检查电脑最后一次出牌是否撒谎
if self.computer.played_history and self.computer.played_history[-1][1]:
print("你质疑正确。")
result = self.russian_roulette(self.computer.name)
return result
else:
print("你质疑错误。")
result = self.russian_roulette(self.player.name)
return result
else:
# 玩家不质疑,电脑直接获胜
print("你选择不质疑,电脑赢得本轮胜利。")
result = self.russian_roulette(self.player.name)
return result
def play_round(self):
"""进行一轮游戏"""
self.setup_round()
while True:
# 玩家回合
if self.player.can_play():
player_cards, player_is_lie = self.player_turn()
# 检查玩家是否出完所有牌
if not self.player.can_play():
return self.handle_player_win()
# 电脑决定是否质疑
challenge = self.computer_decision(len(player_cards))
# 处理质疑结果
if challenge:
if player_is_lie:
print("电脑质疑正确。")
result = self.russian_roulette(self.player.name)
return result
else:
print("电脑质疑错误。")
result = self.russian_roulette(self.computer.name)
return result
else:
print("\n你没有手牌可以出了。")
# 电脑回合
if self.computer.can_play():
computer_cards, computer_is_lie = self.computer_turn()
# 检查电脑是否出完所有牌
if not self.computer.can_play():
return self.handle_computer_win()
# 玩家决定是否质疑
player_challenge = self.player_decision()
if player_challenge:
if computer_is_lie:
print("你质疑正确。")
result = self.russian_roulette(self.computer.name)
return result
else:
print("你质疑错误。")
result = self.russian_roulette(self.player.name)
return result
else:
print("\n电脑没有手牌可以出了")
# 如果双方都还有牌,继续下一回合
print(f"\n双方都还有牌,继续回合...")
print(f"你的剩余手牌: {self.player.show_hand()}")
self.current_round += 1
return True # 继续游戏
def play_game(self):
"""开始游戏"""
print("""
☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★
★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆
☆★☆ 欢迎来到Joker's Deception ★☆★
★☆★ copyrigrht:besti ☆★☆
☆★☆ 开发日期:2025年5月13日 ★☆★
★☆★ 学号:20244112 ☆★☆
★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆
☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★
""")
print("游戏规则:")
print("- 共有20张牌: 6张Queen、6张King、6张Ace和2张Joker")
print("- 每轮随机发放5张牌并且指定一张主牌")
print("- 你可以选择打出任意数量的牌,并默认声称这些牌都是主牌")
print("- 电脑会决定是否质疑你")
print("- 如果电脑不质疑,则轮到电脑出牌,你可以选择是否质疑")
print("- 当一方出完所有手牌后,另一方可以选择是否质疑")
print("- 如果质疑正确,出完牌的一方接受轮盘赌")
print("- 如果不质疑或质疑错误,出完牌的一方获胜")
print("- 六轮内必有一方中枪")
# 游戏主循环
while self.current_round <= 6:
if not self.play_round():
print("\n游戏结束!")
return
# 如果六轮都没有中枪(理论上不可能)
print("\n经过六轮激烈对决,双方都幸运地存活了下来!游戏平局!")
# 启动游戏
if __name__ == "__main__":
game = Game()
game.play_game()
4. 全课的总结与课程感想体会、意见和建议
(1)全课总结:课程起始于对Python的初步认识,涵盖Python语法,如变量定义、数据类型(数字、字符串等)。流程控制语句(条件语句if-else、循环语句for和while)的学习,让代码具备逻辑判断和重复执行能力。在数据处理方面,深入讲解序列(列表、元组、集合 )和字符串操作,包括增删改查、切片等。函数章节则介绍函数定义、参数传递、返回值等内容,将代码模块化,提高代码复用性。面向对象部分引入类和对象概念,封装、继承、多态特性使代码结构更清晰。异常处理及程序调试章节,教会识别和处理运行时错误,使用调试工具排查问题,保障程序稳定性。文件及目录操作涉及文件读写、创建删除目录等。使用Python操作数据库,掌握连接数据库、执行SQL语句、数据增删改查,实现数据持久化存储。网络爬虫开发学习网页数据抓取技术,包括 HTTP 请求、解析网页内容。
(2)课程感想体会:通过这段时间的学习,我掌握了Python语言的基础知识和基本编程技能。能够熟练运用Python进行数据处理、编写简单的算法程序,还完成了如剪刀石头布,简易计算器,记事本,猜数字游戏等的实验。这些实验的完成不仅检验了我的学习成果,也让我获得了极大的成就感。课程初始,面对Python的基础语法,如变量定义、数据类型、条件语句和循环语句,我常常感到困惑。但随着课程的推进,通过老师生动的讲解和大量的实例演示,我逐渐理解了这些基础语法的逻辑和应用场景。在学习函数定义与调用时,我开始体会到模块化编程的魅力。在学习过程中,我也遇到了不少困难。例如,在学习正则表达式时,对于复杂的语法规则我有些许迷惑,但在阅读官方文档、翻阅资料书籍、观看教学视频后,我对正则表达式有了相对更深的了解。
(3)对于课程的意见和建议:王志强老师的Python课程生动有趣,为我打开了Python世界的大门。正如课程伊始,王志强老师在白板上所输入的程序代码:print("hello world")
print("人生苦短,我用Python")。虽然Python程序设计课程已经结束,但这并不意味着我的学习之路就此止步。在未来,我希望能够进一步深入学习Python的高级知识,如网络编程、数据库编程、Web开发等。最后,我希望王老师能够给26年课程学习学生多留作业,更好体会Python程序设计的乐趣与魅力。

浙公网安备 33010602011771号