基于远程桌面的Python贪吃蛇双智能体实现
实验背景与目标
本实验旨在通过华为云EularOS服务器搭建Python运行环境,实现一个支持人机对战的双智能体贪吃蛇游戏。游戏包含一个由玩家控制的蓝色蛇,以及一个基于坐标决策的AI控制绿色蛇,两者共同竞争食物资源。通过远程X11转发技术,实现在无图形界面的云服务器上可视化运行pygame游戏。
环境部署与配置
在EularOS系统中,系统默认使用Python 2.7,需明确指定Python 3环境。首先确认Python 3与pip3的安装状态:
whereis python3
whereis pip3
python3 -V
pip3 -V
若pip3缺失或版本异常,需手动安装最新版pip:
wget https://files.pythonhosted.org/packages/ae/e8/2340d46ecadb1692a1e455f13f75e596d4eab3d11a57446f08259dee8f02/pip-10.0.1.tar.gz
tar -xzf pip-10.0.1.tar.gz
cd pip-10.0.1
python3 setup.py install
随后安装pygame依赖库:
pip3 install pygame
为支持图形界面远程显示,安装X11转发组件:
yum install xterm xauth -y
编辑SSH配置文件以启用X11转发:
vi /etc/ssh/sshd_config
确保以下行存在且未被注释:
X11Forwarding yes
X11UseLocalhost no
重启SSH服务并退出会话:
systemctl restart sshd
本地电脑需安装Xming(Windows)或XQuartz(macOS),启动后通过PuTTY连接服务器,并在Session → SSH → X11中启用"Enable X11 forwarding"。连接后输入xterm验证窗口能否弹出。
双智能体贪吃蛇实现
游戏逻辑分为两个独立控制模块:玩家通过WASD控制蓝色蛇,AI通过坐标比较自动决策绿色蛇的移动方向。
核心变量定义:
head:玩家蛇头坐标thead:AI蛇头坐标snacks:玩家蛇身列表other:AI蛇身列表foods:食物坐标集合want:当前目标食物which:AI方向选择器(0=x轴,1=y轴)run:AI移动速度(±V)
AI决策逻辑采用"逐轴逼近"策略:
- 优先沿
which轴移动,当蛇头与目标食物在该轴上距离超过食物半径时,朝目标方向匀速移动 - 当距离小于阈值时,切换至另一轴继续逼近
- 该策略避免了复杂的路径规划,仅依靠局部坐标判断实现简单智能
关键代码片段:
if thead[which] < want[which] - R:
run = V
elif thead[which] > want[which] + R:
run = -V
else:
which = 1 - which
thead[which] += run
食物被任一蛇体触及时,立即移除并随机生成新食物。若被AI吃掉,目标食物want更新为剩余食物中的随机一项,确保AI持续追踪有效目标。
蛇身增长机制:每次进食后,在蛇尾后方追加一个新方块,实现长度增长。
完整核心代码
import pygame as pg
from random import randint, choice
# 初始化参数
SCREEN = pg.display.set_mode([800, 600])
pg.display.set_caption('双智能体贪吃蛇')
V = 21 # 移动步长
A = 20 # 方块尺寸
R = 20 # 食物半径
# 玩家蛇
direct = "右"
head = [500, 500]
snacks = [head]
# AI蛇
thead = [200, 300]
other = [thead]
which = 0 # 控制轴向:0为x,1为y
run = V # 当前移动方向
want = (220, 350) # 初始目标食物
# 食物池
foods = [(220, 350), (450, 250), (390, 340), (690, 400)]
going = True
clock = pg.time.Clock()
while going:
SCREEN.fill((255, 255, 255))
# 玩家输入处理
for event in pg.event.get([pg.KEYDOWN, pg.QUIT]):
if event.type == pg.QUIT:
going = False
elif event.key == pg.K_w: direct = "上"
elif event.key == pg.K_s: direct = "下"
elif event.key == pg.K_a: direct = "左"
elif event.key == pg.K_d: direct = "右"
pg.event.clear()
# 玩家蛇移动
if direct == "上": head[1] -= V
elif direct == "下": head[1] += V
elif direct == "左": head[0] -= V
elif direct == "右": head[0] += V
# 边界环绕
if head[0] < 0: head[0] = 800
if head[0] > 800: head[0] = 0
if head[1] < 0: head[1] = 600
if head[1] > 600: head[1] = 0
snacks.insert(0, head.copy())
snacks.pop()
# AI蛇决策与移动
if thead[which] < want[which] - R:
run = V
elif thead[which] > want[which] + R:
run = -V
else:
which = 1 - which
thead[which] += run
other.insert(0, thead.copy())
other.pop()
# 食物绘制与碰撞检测
for food in foods:
pg.draw.circle(SCREEN, (238, 180, 34), food, R)
# 玩家吃到食物
if (food[0]-R-A <= head[0] <= food[0]+R and
food[1]-R-A <= head[1] <= food[1]+R):
foods.remove(food)
snacks.append([head[0]-A, head[1]])
if food == want:
want = choice(foods)
# AI吃到食物
elif (food[0]-R-A <= thead[0] <= food[0]+R and
food[1]-R-A <= thead[1] <= food[1]+R):
foods.remove(food)
other.append([thead[0]-A, thead[1]])
if food == want:
want = choice(foods)
# 补充食物数量
if len(foods) < 4:
foods.append((randint(0, 750), randint(0, 550)))
# 绘制蛇体
for segment in snacks[1:]:
pg.draw.rect(SCREEN, (100, 200, 200), (segment[0], segment[1], A, A))
pg.draw.rect(SCREEN, (0, 255, 255), (head[0], head[1], A, A))
for segment in other[1:]:
pg.draw.rect(SCREEN, (0, 238, 118), (segment[0], segment[1], A, A))
pg.draw.rect(SCREEN, (0, 139, 69), (thead[0], thead[1], A, A))
pg.display.update()
clock.tick(20)
pg.quit()
问题与解决方案
问题1:Python版本混淆
EularOS默认调用Python 2.7,导致pip与库安装错位。解决方案:始终使用python3和pip3指令,避免使用python或pip。
问题2:无图形界面报错
pygame启动时提示"Unable to open display"。通过配置X11转发并启用Xming解决,确保SSH连接中勾选"Enable X11 forwarding"。
问题3:AI路径震荡
初期AI在边界处反复切换方向。通过引入which轴切换机制,强制交替控制x/y轴,有效稳定了移动轨迹。
实验总结
本实验不仅完成了云服务器环境搭建与远程图形化运行的完整流程,更通过极简AI逻辑实现了双智能体交互。AI不依赖复杂算法,仅靠坐标差值与轴向轮换,便能实现高效觅食行为,体现了"简单机制产生复杂行为"的计算思维。在实践过程中,深刻体会到Python在教育与原型开发中的强大适应性——无需复杂框架,即可构建可交互的可视化系统。同时,远程开发的调试过程极大提升了对Linux系统与网络协议的理解深度。
