用 Python 打造经典贪吃蛇游戏:从 0 到 1 实现 AI 自动贪吃蛇

提到童年经典游戏,贪吃蛇绝对占有一席之地。在诺基亚手机时代,这款通过方向键控制蛇身吃食物、不断变长的游戏陪伴了无数人的闲暇时光。今天,我们不仅要用 Python 重现这款经典游戏,还要让蛇拥有 “AI 大脑”,实现自动寻路、躲避障碍和无限成长!

一、贪吃蛇游戏核心原理

贪吃蛇的核心玩法超级简单:

  • 蛇在封闭区域内移动,通过吃食物增长长度
  • 撞到墙壁或自身身体则游戏结束
  • 吃到食物得分增加,蛇身长度 + 1

用 Python 实现贪吃蛇,我们需要解决三个关键问题:

  1. 游戏界面渲染:使用pygame库绘制游戏窗口、蛇身和食物
  2. 运动逻辑控制:处理蛇的移动、转向和增长机制
  3. AI 决策系统:让蛇自主规划路径寻找食物,避免死亡

接下来,我们就一步步拆解这个 Python 贪吃蛇项目的实现过程。

二、环境准备与基础框架搭建

第一需要安装必要的库,我们主要使用pygame进行图形渲染:

bash

pip install pygame

游戏的基础配置类SnakeConf定义了所有常量参数,这是良好编程习惯的体现:

python

class SnakeConf(object):
    # 游戏场地大小(20x20网格)
    HEIGHT, WIDTH = 20, 20
    # 每个网格的像素大小
    LINE_WIDTH = 25
    LINE_MARGIN = 4
    # 实际绘制的网格大小(减去边距)
    LINE_TRUEWIDTH = LINE_WIDTH - 2 * LINE_MARGIN
    # 窗口尺寸计算
    SCREEN_X, SCREEN_Y = LINE_WIDTH * HEIGHT, LINE_WIDTH * WIDTH
    FIELD_SIZE = HEIGHT * WIDTH  # 总网格数

    # 特殊标记值(间隔要足够大)
    FOOD, UNDEFINED = 0, (HEIGHT + 1) * (WIDTH + 1)
    SNAKE = 2 * UNDEFINED

    # 方向常量定义
    LEFT, RIGHT, UP, DOWN = -1, 1, -WIDTH, WIDTH

    # 颜色定义
    BG_COLOR = (255, 255, 255)       # 白色背景
    SNAKE_COLOR = (136, 0, 21)       # 深红色蛇身
    FOOD_COLOR = (20, 220, 39)       # 绿色食物

这些常量让代码更具可读性和可维护性,后续调整游戏参数只需修改这里的值。

三、游戏核心逻辑实现

1. 初始化游戏对象

Snake类的构造函数初始化了游戏的核心数据结构:

  • board:记录游戏场地每个网格的状态
  • snake:存储蛇身每个节点的位置(一维数组表明二维坐标)
  • food:食物的位置坐标
  • 临时变量用于 AI 决策时的虚拟运算

python

def __init__(self):
    # 初始化游戏场地
    self.board = [0] * SnakeConf.FIELD_SIZE
    # 初始化蛇(从(1,1)位置开始,长度为1)
    self.snake = [0] * (SnakeConf.FIELD_SIZE + 1)
    self.snake[0] = 1 * SnakeConf.WIDTH + 1
    self.snake_size = 1
    # 初始食物位置(3,3)
    self.food = 3 * SnakeConf.WIDTH + 3
    # 运动方向数组
    self.mov = [SnakeConf.LEFT, SnakeConf.RIGHT, SnakeConf.UP, SnakeConf.DOWN]

2. 核心游戏机制解析

(1)碰撞检测

is_move_possible方法判断蛇头向某个方向移动是否合法(不会撞墙):

python

def is_move_possible(self, idx, move):
    if move == SnakeConf.LEFT:
        return idx % SnakeConf.WIDTH > 1  # 左边不是墙壁
    elif move == SnakeConf.RIGHT:
        return idx % SnakeConf.WIDTH < (SnakeConf.WIDTH - 2)  # 右边不是墙壁
    elif move == SnakeConf.UP:
        return idx > (2 * SnakeConf.WIDTH - 1)  # 上边不是墙壁
    elif move == SnakeConf.DOWN:
        return idx < (SnakeConf.FIELD_SIZE - 2 * SnakeConf.WIDTH)  # 下边不是墙壁

(2)路径规划算法

游戏的灵魂在于 AI 自动寻路,这里使用广度优先搜索 (BFS) 实现路径规划:

python

def board_refresh(self, pfood, psnake, pboard):
    queue = [pfood]  # 从食物位置开始搜索
    inqueue = [0] * SnakeConf.FIELD_SIZE  # 标记是否已入队
    found = False
    while queue:
        idx = queue.pop(0)
        if inqueue[idx]:
            continue
        inqueue[idx] = 1
        # 探索四个方向
        for move in self.mov:
            if self.is_move_possible(idx, move):
                # 如果找到蛇头,标记成功
                if idx + move == psnake[0]:
                    found = True
                # 更新路径长度
                if pboard[idx+move] < SnakeConf.SNAKE:  # 不是蛇身
                    if pboard[idx + move] > pboard[idx] + 1:
                        pboard[idx + move] = pboard[idx] + 1
                    if not inqueue[idx + move]:
                        queue.append(idx + move)
    return found

这个方法会计算场地中每个位置到食物的最短路径长度,为 AI 决策提供依据。

(3)AI 决策逻辑

AI 蛇的决策流程超级智能:

  1. 优先选择到食物的最短路径
  2. 检查路径是否安全(确保蛇头到蛇尾有通路)
  3. 危险时选择跟随蛇尾的策略
  4. 极端情况下随机选择可行方向

python

# 选择最短安全路径
def choose_shortest_safe_move(self, psnake, pboard):
    best_move = SnakeConf.ERR
    min_dist = SnakeConf.UNDEFINED
    for move in self.mov:
        if self.is_move_possible(psnake[0], move) and pboard[psnake[0] + move] < min_dist:
            min_dist = pboard[psnake[0] + move]
            best_move = move
    return best_move

# 跟随蛇尾策略(避免死循环)
def follow_tail(self):
    # 虚拟操作:将蛇尾视为食物计算路径
    self.tmpboard[self.tmpsnake[self.tmpsnake_size - 1]] = SnakeConf.FOOD
    self.tmpboard[self.food] = SnakeConf.SNAKE
    self.board_refresh(self.tmpsnake[self.tmpsnake_size - 1], self.tmpsnake, self.tmpboard)
    return self.choose_longest_safe_move(self.tmpsnake, self.tmpboard)

3. 游戏渲染与主循环

draw_snake方法负责在屏幕上绘制蛇身,使用矩形拼接实现连续的蛇身效果:

python

def draw_snake(self, screen):
    # 绘制蛇头
    left = (self.snake[0] // SnakeConf.WIDTH) * SnakeConf.LINE_WIDTH + 2
    top = (self.snake[0] % SnakeConf.WIDTH) * SnakeConf.LINE_WIDTH + 2
    rect = pygame.Rect(left, top, SnakeConf.LINE_TRUEWIDTH, SnakeConf.LINE_TRUEWIDTH)
    pygame.draw.rect(screen, SnakeConf.SNAKE_COLOR, rect, 0)
    
    # 绘制蛇身(连接相邻节点)
    for i in range(1, self.snake_size):
        # 计算前后节点位置并绘制连接矩形
        # ...省略具体坐标计算代码...
        pygame.draw.rect(screen, SnakeConf.SNAKE_COLOR, rect, 0)

主循环控制游戏的运行流程,处理用户输入、更新游戏状态并渲染画面:

python

def main(self):
    pygame.init()
    screen = pygame.display.set_mode((SnakeConf.SCREEN_X, SnakeConf.SCREEN_Y))
    clock = pygame.time.Clock()
    isdead = False
    pause = False
    
    while True:
        # 处理事件(退出、暂停等)
        # ...
        
        # 游戏逻辑更新
        if not pause and not isdead:
            # AI决策与移动
            # ...
        
        # 绘制游戏元素
        screen.fill(SnakeConf.BG_COLOR)
        self.draw_snake(screen)
        # 绘制食物和分数
        # ...
        
        pygame.display.update()
        clock.tick(100)  # 控制游戏速度

四、游戏特色与扩展方向

这个 Python 贪吃蛇游戏有许多亮点:

  • 全自动化 AI:无需手动操作,蛇会自主寻路吃食物
  • 智能避障:通过 BFS 算法和蛇尾跟随策略避免死亡
  • 可视化界面:清晰的图形渲染,支持暂停和单步调试
  • 分数系统:实时显示当前得分(蛇的长度)

你可以尝试这些扩展方向:

  1. 增加难度级别(随分数提高速度)
  2. 添加特殊食物(限时加速、长度翻倍等)
  3. 实现双人对战模式
  4. 加入音效和动画效果
  5. 优化 AI 算法,提高蛇的生存能力

五、完整代码与运行指南

将文中代码整合后,只需运行以下命令即可启动游戏:

bash

python snake_game.py

游戏操作说明:

  • 空格键:暂停 / 继续游戏
  • 右方向键:单步执行(暂停时有效)
  • 关闭窗口:退出游戏

当蛇撞到墙壁或自身时,会显示 “YOU DEAD!” 提示,按空格键可重新开始。

六、总结

通过这个贪吃蛇项目,我们不仅重温了经典游戏的乐趣,还学习了:

  • Pygame 图形库的基础使用
  • 广度优先搜索在路径规划中的应用
  • 游戏 AI 的基本决策逻辑
  • 面向对象编程的实践技巧

这个自动贪吃蛇的实现展示了 Python 在游戏开发中的强劲能力,即使是看似简单的游戏,也能蕴含丰富的算法思想。希望这个项目能激发你对 Python 编程和游戏开发的兴趣,不妨尝试修改代码,创造属于你的特色贪吃蛇吧!

© 版权声明

相关文章

暂无评论

none
暂无评论...