课程:《Python程序设计》
班级: 2422
姓名: 陈俊祎
学号: 20242210
实验教师:王志强
实验日期:2026年6月1日
必修/选修:公选课

  1. 实验内容
    按照实验要求编写了一个能够用python语句执行的贪吃蛇代码小游戏。
    具体实现代码如下所示:
    import pygame
    import random
    import sys
    pygame.init()

WIDTH, HEIGHT = 600, 400
CELL_SIZE = 20
GRID_WIDTH = WIDTH // CELL_SIZE
GRID_HEIGHT = HEIGHT // CELL_SIZE

BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
BLUE = (0, 0, 255)

UP = (0, -1)
DOWN = (0, 1)
LEFT = (-1, 0)
RIGHT = (1, 0)

screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("贪吃蛇 - Python综合实践")
clock = pygame.time.Clock()

try:
font = pygame.font.Font(None, 24)
big_font = pygame.font.Font(None, 48)
except:
font = pygame.font.SysFont('arial', 20)
big_font = pygame.font.SysFont('arial', 40)

def draw_grid():
for x in range(0, WIDTH, CELL_SIZE):
pygame.draw.line(screen, (50, 50, 50), (x, 0), (x, HEIGHT))
for y in range(0, HEIGHT, CELL_SIZE):
pygame.draw.line(screen, (50, 50, 50), (0, y), (WIDTH, y))

def show_text(text, color, x, y, font_obj=font):
surface = font_obj.render(text, True, color)
screen.blit(surface, (x, y))

def generate_food(snake):
while True:
x = random.randint(0, GRID_WIDTH - 1)
y = random.randint(0, GRID_HEIGHT - 1)
if (x, y) not in snake:
return (x, y)

def game_loop():
snake = [(GRID_WIDTH // 2, GRID_HEIGHT // 2),
(GRID_WIDTH // 2 - 1, GRID_HEIGHT // 2),
(GRID_WIDTH // 2 - 2, GRID_HEIGHT // 2)]
direction = RIGHT
next_direction = RIGHT
food = generate_food(snake)
score = 0
highest_score = 0
speed = 10
game_over = False

while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if game_over:
return
if event.key == pygame.K_UP and direction != DOWN:
next_direction = UP
elif event.key == pygame.K_DOWN and direction != UP:
next_direction = DOWN
elif event.key == pygame.K_LEFT and direction != RIGHT:
next_direction = LEFT
elif event.key == pygame.K_RIGHT and direction != LEFT:
next_direction = RIGHT

if game_over:
screen.fill(BLACK)
show_text("GAME OVER", RED, WIDTH//2 - 80, HEIGHT//2 - 40, big_font)
show_text(f"Your Score: {score}", WHITE, WIDTH//2 - 70, HEIGHT//2, big_font)
show_text("Press any key to restart", WHITE, WIDTH//2 - 150, HEIGHT//2 + 50)
pygame.display.flip()
continue

direction = next_direction
head_x, head_y = snake[0]
new_head = (head_x + direction[0], head_y + direction[1])

if (new_head[0] < 0 or new_head[0] >= GRID_WIDTH or
new_head[1] < 0 or new_head[1] >= GRID_HEIGHT or
new_head in snake):
game_over = True
if score > highest_score:
highest_score = score
continue

ate_food = (new_head == food)
if ate_food:
score += 1
speed = min(10 + (score // 5) * 2, 30)
food = generate_food(snake)
snake.insert(0, new_head)
else:
snake.insert(0, new_head)
snake.pop()

screen.fill(BLACK)
draw_grid()
fx, fy = food
pygame.draw.rect(screen, RED, (fxCELL_SIZE, fyCELL_SIZE, CELL_SIZE, CELL_SIZE))
for i, (sx, sy) in enumerate(snake):
color = GREEN if i == 0 else BLUE
pygame.draw.rect(screen, color, (sxCELL_SIZE, syCELL_SIZE, CELL_SIZE, CELL_SIZE))
show_text(f"Score: {score}", WHITE, 10, 5)
show_text(f"Highest: {highest_score}", WHITE, 10, 30)
show_text(f"Speed: {speed}", WHITE, 10, 55)
pygame.display.flip()

clock.tick(speed)

if name == "main":
while True:
game_loop()
发现能够正常运行,说明源代码无错误。
2. 实验要求
(1)在Windows/Linux系统上使用VIM、PDB、IDLE、Pycharm等工具编程实现;
(2)程序能运行,功能丰富(至少5个功能);
本程序实现7项功能,满足要求:
键盘控制蛇的移动(上/下/左/右)
随机生成食物,蛇头碰到食物则得分增加且蛇身长度增长
实时显示当前得分
碰撞检测
游戏结束后按任意键重新开始
随着得分增加,蛇移动速度逐渐加快
显示本轮最高分
3. 运行结果
下面是游戏开始时的界面:
image
蛇的头撞到边界后显示游戏失败 按任意按键重新开始游戏的界面:
ff0e77ff72c6055fa07e0c59e851fd35
经过检验:蛇的长度可以随着吃豆豆的数量增长,游戏没有出现错误,一切顺利运行。

4.代码优缺点分析
优点:
结构比较清晰,玩起来不会卡顿,满足娱乐要求,制作成功后有时候我无聊自己也会玩。
缺点:
关闭程序后最高分就会被重置,没有那种永久记录的感觉,没有暂停的功能,在考虑怎么才能加上一个,提升使用体验感,没有经典的“噔噔噔噔噔....”贪吃蛇音效,总感觉差点什么,应该搞一个插件会更好一点。
5.改进方向:
增加最高分持久化;
添加音效:使用 pygame.mixer 模块为吃食物、游戏结束添加简单音效;
增加暂停功能:监听K_p按键,设置paused状态,暂停时冻结游戏逻辑并显示提示;
丰富视觉表现:为蛇身添加渐变颜色、食物添加闪烁效果或不同分值食物,这样可以优化游戏体验。

  1. 实验过程中遇到的问题和解决过程
    问题 1:初次运行代码时出现 ModuleNotFoundError: No module named 'pygame'
    解决:在命令行中执行pip install pygame安装依赖库,之后程序正常运行。

问题 2:蛇的移动出现“反向直接死亡”bug
解决:在事件处理中增加了方向合法性判断,例如向右移动时禁止立即反向(if event.key == pygame.K_LEFT and direction != RIGHT),保证蛇不能180度掉头。

问题 3:游戏结束后按任意键重新开始,但最高分未能正确保留
解决:将 highest_score 变量提升到 game_loop 函数内部,并在游戏结束时用 score 与之比较;同时在主循环外使用 while True 反复调用 game_loop(),使得每次重新开始能保留上一轮的 highest_score。

问题 4:字体初始化在某些环境下失败导致程序崩溃
解决:使用 try-except 捕获异常,回退到 pygame.font.SysFont('arial', 20) 确保程序总能找到可用字体。

7.课程总结与感想
在高中的时候我通过信息技术课对python这个编程语言有了初步的认识,很可惜当时选课没能选那个课,不过庆幸在大学通过本课程的学习,我从一个略微有C语言基础的学生,成长为能够独立使用 Python 完成图形化小游戏开发的初学者,这是一种奇妙的感觉,仿佛朝花夕拾。
在本次贪吃蛇游戏实验中,我将课程中学到的 pygame 图形编程、事件驱动模型、随机数生成、列表操等知识融会贯通。实现过程中,我深刻体会到 “边做边学” 的高效性:遇到方向锁死、碰撞检测精度等问题时,通过调用大模型、调试代码最终解决,这种成就感非常爽。
此外,我也认识到代码的可读性和可维护性同样重要——将功能拆分为独立函数、添加注释、合理命名变量,这些习惯应当继续加以培养。

  1. 知识点总结
    Python语言概述与开发环境
    Python 与 C 语言区别
    开发工具:IDLE、PyCharm
    版本管理:Gitee
    实验报告:博客园

基本语法
缩进表示代码块
大小写敏感
注释(#、""")
变量无需声明类型

变量与基本数据类型
数字:int、float、complex
字符串:str(切片、f-string)
布尔:True/False
类型转换:int()、float()、str()
运算符:算术、比较、逻辑

条件与循环
if-elif-else
for、while
break、continue

序列类型
列表(list):可变
元组(tuple):不可变
字典(dict):键值对
集合(set):无序、去重

字符串与正则表达式
字符串方法:strip()、split()、join()、replace()、find()、upper()/lower()
re 模块:search()、match()、sub()、findall()
元字符:.、*、+、?、[]、()、{}

函数与面向对象
函数:def、参数(位置/关键字/默认)、return、lambda
面向对象:封装(class、init)、继承、多态

异常处理
try-except-else-finally
常见异常:ValueError、IOError

文件操作
open() 模式:r、w、a、b
方法:read()、write()、seek()、close()
上下文管理器:with open() as f

网络爬虫基础
robots.txt 协议
库:requests、urllib
HTTP 请求(GET/POST)

  1. 课程建议
    感觉挺好,没什么想建议的,就是希望以后可以把python弄成主课,也不是不行。

11.参考资料
Pygame 官方文档
课程课件及课堂示例代码