20232416 石泽伟 2023-2024-2 《Python程序设计》实验四报告
课程:《Python程序设计》
班级: 2324班
姓名: 石泽伟
学号: 20232416
实验教师:王志强
实验日期:2024年5月15日
必修/选修: 公选课
1.实验内容
(1)实验整体内容:
Python综合应用:爬虫、数据处理、可视化、机器学习、神经网络、游戏、网络安全等。
(1)编写从社交网络爬取数据,实现可视化舆情监控或者情感分析。
(2)利用公开数据集,开展图像分类、恶意软件检测等
(3)利用Python库,基于OCR技术实现自动化提取图片中数据,并填入excel中。
(4)爬取天气数据,实现自动化微信提醒
(5)利用爬虫,实现自动化下载网站视频、文件等。
(6)编写小游戏:坦克大战、贪吃蛇、扫雷等等
注:在Windows/Linux系统上使用VIM、PDB、IDLE、Pycharm等工具编程实现。
(2)本次实验主要聚焦:
①游戏1:走迷宫。在迷宫中设计一个出口,小球碰到墙壁则失败,走到出口则视为胜利
②游戏2:猜拳游戏。玩家和电脑谁先赢够3局就胜利。
③游戏3:贪吃蛇。碰到墙壁就算输,吃够15颗食物就算胜利。
2.实验过程及结果
游戏1
(1)设计思路分析:
- 游戏目标与规则确定:碰壁失败;从出口出去胜利
- 游戏界面设计:通过pygame库提供的绘图功能,可以实现迷宫的绘制以及小球和出口的显示。
- 游戏逻辑设计:包括初始化游戏变量、处理键盘输入、检测小球与墙壁的碰撞等。
(2)主要内容分析:
- ①初始化pygame以及游戏变量以及设置窗口大小和标题
pygame.init()
screen = pygame.display.set_mode((400, 300))
pygame.display.set_caption("迷宫游戏")
running = True
x, y = 50, 50 # 小球的起始位置
exit_x, exit_y = 300, 220 # 出口位置
speed = 5 # 小球移动速度
radius = 10 # 小球的半径
用于初始化pygame库,确保在使用pygame之前,pygame被正确地初始化并创建了一个宽度为400像素,高度为300像素的窗口,还初始化了各种变量。
- ②墙壁设计以及游戏循环
walls = [pygame.Rect(100, 50, 200, 10), pygame.Rect(100, 200, 200, 10), pygame.Rect(100, 60, 10, 140)]
while running:
游戏会在这个循环中持续运行,直到running变量被设置为False。
- ③操作处理及输入处理
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
keys = pygame.key.get_pressed()
if keys[pygame.K_w]:
y -= speed
if keys[pygame.K_s]:
y += speed
if keys[pygame.K_a]:
x -= speed
if keys[pygame.K_d]:
x += speed
根据按键的情况来移动小球的位置;W键向上移动,S键向下移动,A键向左移动,D键向右移动。
- ④检测
ball = pygame.Rect(x - radius, y - radius, radius * 2, radius * 2)
if ball.collidelist(walls) != -1:
print("游戏失败!")
running = False
if abs(x - exit_x) < radius and abs(y - exit_y) < radius:
print("游戏成功!")
running = False
检测小球是否与墙壁发生碰撞以及检测小球是否到达出口。
- ⑤渲染游戏界面以及退出游戏
screen.fill((0, 0, 0))
for wall in walls:
pygame.draw.rect(screen, (255, 255, 255), wall)
pygame.draw.circle(screen, (255, 0, 0), (x, y), radius)
pygame.draw.circle(screen, (0, 255, 0), (exit_x, exit_y), radius)
pygame.display.flip()
pygame.time.delay(30)
pygame.quit()
sys.exit()
窗口填充为黑色,在游戏结束后调用pygame.quit()将清理pygame模块使用的资源,然后调用sys.exit()退出程序。
(3)源代码
import pygame
import sys
pygame.init()
screen = pygame.display.set_mode((400, 300))
pygame.display.set_caption("迷宫游戏")
# 游戏变量
running = True
x, y = 50, 50 # 小球的起始位置
exit_x, exit_y = 300, 220 # 出口位置
speed = 5 # 小球移动速度
radius = 10 # 小球的半径
# 迷宫的墙壁
walls = [pygame.Rect(100, 50, 200, 10), pygame.Rect(100, 200, 200, 10), pygame.Rect(100, 60, 10, 140)]
# 游戏主循环
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
keys = pygame.key.get_pressed()
if keys[pygame.K_w]:
y -= speed
if keys[pygame.K_s]:
y += speed
if keys[pygame.K_a]:
x -= speed
if keys[pygame.K_d]:
x += speed
ball = pygame.Rect(x - radius, y - radius, radius * 2, radius * 2)
if ball.collidelist(walls) != -1:
print("游戏失败!")
running = False
if abs(x - exit_x) < radius and abs(y - exit_y) < radius:
print("游戏成功!")
running = False
screen.fill((0, 0, 0))
for wall in walls:
pygame.draw.rect(screen, (255, 255, 255), wall)
pygame.draw.circle(screen, (255, 0, 0), (x, y), radius)
pygame.draw.circle(screen, (0, 255, 0), (exit_x, exit_y), radius)
pygame.display.flip()
pygame.time.delay(30)
pygame.quit()
sys.exit()
视频演示:
迷宫游戏1
游戏2
(1)设计思路分析:
- 游戏目标与规则确定:剪刀石头布规则大家肯定都知道了~~
- 游戏界面设计:创建一个简单直观的界面,包括玩家的选择按钮、游戏结果展示区域和得分统计区域。
- 游戏逻辑设计:电脑根据玩家点击按键和游戏规则来判断胜负,任一方胜利三次则结束游戏。
(2)主要内容分析:
- ①导入模块和库
import tkinter as tk
import random
import time
tkinter: 是Python的标准GUI库,用于创建用户界面。
random: Python的随机数生成模块,用于生成随机的电脑选择。
time: Python的时间模块,用于设置随机种子。
- ②定义 start_game() 函数和play() 函数
def start_game():
scores = {'player': 0, 'computer': 0}
random.seed(time.time()) # 设置随机种子为当前时间
def play(user_choice):
if scores['player'] < 3 and scores['computer'] < 3:
# 随机生成电脑的选择
choices = ['石头', '剪刀', '布']
computer_choice = random.choice(choices)
# 确定胜负
result = determine_winner(user_choice, computer_choice)
# 得分跟随
if result == "你赢了!":
scores['player'] += 1
elif result == "你输了!":
scores['computer'] += 1
# 更新结果
result_label.config(text=f"你的选择: {user_choice}\n电脑的选择: {computer_choice}\n结果: {result}")
score_label.config(text=f"玩家得分: {scores['player']} | 电脑得分: {scores['computer']}")
if scores['player'] >= 3:
result_label.config(text="游戏结束,你赢了!")
elif scores['computer'] >= 3:
result_label.config(text="游戏结束,电脑赢了!")
函数内,首先初始化了玩家和电脑的得分为0,并设置了随机种子。根据玩家的选择,生成电脑的选择,然后确定胜负,并更新得分和结果展示标签。
- ③创建 Tkinter 窗口和界面元素
root = tk.Tk()
root.title("石头剪刀布")
# 设置按钮
tk.Button(root, text='石头', command=lambda: play('石头'), width=10).pack(pady=5)
tk.Button(root, text='剪刀', command=lambda: play('剪刀'), width=10).pack(pady=5)
tk.Button(root, text='布', command=lambda: play('布'), width=10).pack(pady=5)
result_label = tk.Label(root, text="请做出你的选择", font=('Arial', 12))
result_label.pack(pady=20)
score_label = tk.Label(root, text="玩家得分: 0 | 电脑得分: 0", font=('Arial', 12))
score_label.pack(pady=10)
root.mainloop()
创建了一个 Tkinter 窗口,添加了三个按钮,分别代表石头、剪刀、布,并绑定了点击事件,点击时调用 play() 函数并传入对应的选择,并且创建了两个标签用于显示游戏结果和得分。
- ④ 启动游戏
if __name__ == "__main__":
start_game()
(3)源代码
import tkinter as tk
import random
import time
def start_game():
# 初始化得分
scores = {'player': 0, 'computer': 0}
random.seed(time.time()) # 设置随机种子为当前时间
def play(user_choice):
if scores['player'] < 3 and scores['computer'] < 3:
# 生成电脑的选择
choices = ['石头', '剪刀', '布']
computer_choice = random.choice(choices)
# 确定胜负
result = determine_winner(user_choice, computer_choice)
# 更新得分
if result == "你赢了!":
scores['player'] += 1
elif result == "你输了!":
scores['computer'] += 1
# 更新结果标签
result_label.config(text=f"你的选择: {user_choice}\n电脑的选择: {computer_choice}\n结果: {result}")
score_label.config(text=f"玩家得分: {scores['player']} | 电脑得分: {scores['computer']}")
# 检查是否有一方赢得了三次
if scores['player'] >= 3:
result_label.config(text="游戏结束,你赢了!")
elif scores['computer'] >= 3:
result_label.config(text="游戏结束,电脑赢了!")
def determine_winner(user, computer):
if user == computer:
return "平局"
elif (user == '石头' and computer == '剪刀') or \
(user == '剪刀' and computer == '布') or \
(user == '布' and computer == '石头'):
return "你赢了!"
else:
return "你输了!"
root = tk.Tk()
root.title("石头剪刀布")
tk.Button(root, text='石头', command=lambda: play('石头'), width=10).pack(pady=5)
tk.Button(root, text='剪刀', command=lambda: play('剪刀'), width=10).pack(pady=5)
tk.Button(root, text='布', command=lambda: play('布'), width=10).pack(pady=5)
result_label = tk.Label(root, text="请做出你的选择", font=('Arial', 12))
result_label.pack(pady=20)
score_label = tk.Label(root, text="玩家得分: 0 | 电脑得分: 0", font=('Arial', 12))
score_label.pack(pady=10)
root.mainloop()
if __name__ == "__main__":
start_game()
视频上传:
剪刀石头布
游戏3
(1)设计思路分析:
- 游戏目标与规则确定:若碰壁则失败,在此之前吃到5个食物就胜利
- 游戏界面设计:使用 tkinter.Canvas 创建,用于显示贪吃蛇、食物以及游戏结束等元素。设置背景色为黑色,以突出显示游戏元素。
- 游戏逻辑设计:电脑根据碰撞以及移动、键盘操控方向改变来对玩家的胜利和失败进行判定。
(2)主要内容分析:
- ①导入模块
import tkinter as tk
import random
- ②SnakeGame 类构造方法 __init
def __init__(self, master):
self.master = master
self.master.title("贪吃蛇游戏")
self.width = 400
self.height = 400
self.cell_size = 20
self.canvas = tk.Canvas(self.master, width=self.width, height=self.height, bg='black')
self.canvas.pack()
self.snake = [(20, 20)]
self.food = self.create_food()
self.direction = 'Right'
self.running = True
self.food_eaten = 0
self.update_game()
self.master.bind("<KeyPress>", self.change_direction)
例如master参数通常是一个 Tkinter 窗口对象,表示游戏窗口的主体以及设置了游戏窗口的标题为 "贪吃蛇游戏"等等。
- ③create_food函数
def create_food(self):
while True:
food = (random.randint(0, (self.width // self.cell_size) - 1) * self.cell_size,
random.randint(0, (self.height // self.cell_size) - 1) * self.cell_size)
if food not in self.snake:
return food
创建食物并且在蛇吃掉食物后消失。
- ④update_game 函数
def update_game(self):
if self.running:
self.move_snake()
self.check_collision()
self.master.after(100, self.update_game)
游戏的主循环,控制游戏的更新。
- ⑤move_snake函数
def move_snake(self):
head_x, head_y = self.snake[-1]
if self.direction == 'Left':
head_x -= self.cell_size
elif self.direction == 'Right':
head_x += self.cell_size
elif self.direction == 'Up':
head_y -= self.cell_size
elif self.direction == 'Down':
head_y += self.cell_size
new_head = (head_x, head_y)
self.snake.append(new_head)
self.canvas.delete("snake")
for x, y in self.snake:
self.canvas.create_rectangle(x, y, x + self.cell_size, y + self.cell_size, fill="green", tags="snake")
self.canvas.delete("food") # 删除旧食物
self.canvas.create_rectangle(self.food[0], self.food[1], self.food[0] + self.cell_size, self.food[1] + self.cell_size, fill="red", tags="food")
更新蛇的坐标。
- ⑥check_collision 函数
def check_collision(self):
head_x, head_y = self.snake[-1]
if head_x < 0 or head_x >= self.width or head_y < 0 or head_y >= self.height or len(self.snake) != len(set(self.snake)):
self.running = False
self.canvas.create_text(self.width // 2, self.height // 2, text="游戏结束", fill="white", font=('Helvetica', 24))
elif (head_x, head_y) == self.food:
self.food_eaten += 1
if self.food_eaten == 5:
self.running = False
self.canvas.create_text(self.width // 2, self.height // 2, text="你赢了!", fill="white", font=('Helvetica', 24))
else:
self.food = self.create_food() # 创建新食物并更新画布
else:
self.snake.pop(0)
用于检查游戏中的碰撞情况,包括是否撞到墙壁、是否吃到食物或者是否吃到自己。
- ⑦change_direction函数
def change_direction(self, event):
dir_map = {'Left': 'Right', 'Right': 'Left', 'Up': 'Down', 'Down': 'Up'}
if (event.keysym in dir_map and dir_map[event.keysym] != self.direction):
self.direction = event.keysym
- ⑧主函数
def main():
root = tk.Tk()
game = SnakeGame(root)
root.mainloop()
程序的入口点,创建了游戏窗口,并启动了游戏循环。
源代码
import tkinter as tk
import random
class SnakeGame:
def __init__(self, master):
self.master = master
self.master.title("贪吃蛇游戏")
self.width = 400
self.height = 400
self.cell_size = 20
self.canvas = tk.Canvas(self.master, width=self.width, height=self.height, bg='black')
self.canvas.pack()
self.snake = [(20, 20)]
self.food = self.create_food()
self.direction = 'Right'
self.running = True
self.food_eaten = 0
self.update_game()
self.master.bind("<KeyPress>", self.change_direction)
def create_food(self):
while True:
food = (random.randint(0, (self.width // self.cell_size) - 1) * self.cell_size,
random.randint(0, (self.height // self.cell_size) - 1) * self.cell_size)
if food not in self.snake:
return food
def update_game(self):
if self.running:
self.move_snake()
self.check_collision()
self.master.after(100, self.update_game)
def move_snake(self):
head_x, head_y = self.snake[-1]
if self.direction == 'Left':
head_x -= self.cell_size
elif self.direction == 'Right':
head_x += self.cell_size
elif self.direction == 'Up':
head_y -= self.cell_size
elif self.direction == 'Down':
head_y += self.cell_size
new_head = (head_x, head_y)
self.snake.append(new_head)
self.canvas.delete("snake")
for x, y in self.snake:
self.canvas.create_rectangle(x, y, x + self.cell_size, y + self.cell_size, fill="green", tags="snake")
self.canvas.delete("food") # 删除旧食物
self.canvas.create_rectangle(self.food[0], self.food[1], self.food[0] + self.cell_size, self.food[1] + self.cell_size, fill="red", tags="food")
def check_collision(self):
head_x, head_y = self.snake[-1]
if head_x < 0 or head_x >= self.width or head_y < 0 or head_y >= self.height or len(self.snake) != len(set(self.snake)):
self.running = False
self.canvas.create_text(self.width // 2, self.height // 2, text="游戏结束", fill="white", font=('Helvetica', 24))
elif (head_x, head_y) == self.food:
self.food_eaten += 1
if self.food_eaten == 5:
self.running = False
self.canvas.create_text(self.width // 2, self.height // 2, text="你赢了!", fill="white", font=('Helvetica', 24))
else:
self.food = self.create_food() # 创建新食物并更新画布
else:
self.snake.pop(0)
def change_direction(self, event):
dir_map = {'Left': 'Right', 'Right': 'Left', 'Up': 'Down', 'Down': 'Up'}
if (event.keysym in dir_map and dir_map[event.keysym] != self.direction):
self.direction = event.keysym
def main():
root = tk.Tk()
game = SnakeGame(root)
root.mainloop()
if __name__ == "__main__":
main()
视频上传:
贪吃蛇
3.实验过程中遇到的问题和解决过程
- 【1】问题:No module named ‘numpy’
- 解决方案:Python库本没有模块“numpy”,因此需要下载这个库
- 下载方法:
- (1)先使用快捷键“Windows+R”打开弹窗并输入“cmd”进入控制台
- (2)输入命令行python -m pip install --upgrade pip
- (3)稍等片刻后,再次输入上述命令行,此时成功卸载并重新安装了pip
- (4)输入安装命令:pip install numpy,稍等片刻后,显示Successfully installed numpy-1.24.4则成功
- 【2】问题:Indent expected
- 解决方案:这种问题实在常见,我在写程序的过程中犯了多次这样的错误,一开始不知道什么原因。后来知道,因此这类错误的通常是代码行缩进错误导致的,只要简单地将这行代码和逻辑等同的代码行使用相同缩进即可。
- 【3】问题:No module named ‘pygame’
- 解决方案:输入指令:pip install pygame,下载pygame模块
- 显示Successfully installed pygame-2.5.2则成功
4.其他(感悟、思考等)
【1】实验四感悟:
经历了一个学期的学习,我学到了很多知识,例如面向对象的三要素封装、继承、多态以及概念包括类和对象等。还有一些Python里面的特有的写法,比如说循环书写以及一些类型查询都十分的方便。我们还学到列表、元组、字典、集合等。还学到了Python的正则表达式以及爬虫这种功能强大的工具。
【2】课程感想体会、意见及建议:
感想体会:报这门课程的最初目的是想要在学习Python语言,提高自己的专业能力和眼界认知,另外的原因的是身边同学都在抢这门课程,我想这样的课程一定很好。不出我所料,Python课上,老师带我们由浅入深学习,还戏谑为“从入学到入狱”,从字符串到爬虫。即使一周一节课,但老师在学习通上传的资料里的文档如此通透明了,让我收获颇丰的同时也成就满满。虽然我又如此多的收获,但是调试代码的过程总是令人崩溃的,看着代码跑起来令我忍俊不禁,古人言“两岸猿声啼不住,轻舟已过万重山”。时光匆匆,不禁令人慨叹!最后感谢老师与课代表的辛勤付出,也祝大家学业有成、蒸蒸日上。
意见与建议:我认为老师可以加入一些奖惩措施,比如说课前回答问题,正确会加分,错误会适当扣分,别的地方都十分完美~~
- 参考资料:(1)https://blog.csdn.net/weixin_46066007/article/details/126003036?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522171688985616800225547415%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=171688985616800225547415&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2alltop_click~default-1-126003036-null-null.142v100pc_search_result_base3&utm_term=No%20module%20named%20numpy&spm=1018.2226.3001.4187
(2)https://metaso.cn/search/8484121336490045440?q=Indent%20expected%E5%9C%A8Python%E4%B8%AD%E4%BB%80%E4%B9%88%E5%8E%9F%E5%9B%A0