<<<<<<< HEAD
# AI-SnakeGame
基于A*寻路算法的AI贪吃蛇的贪心与哈密尔顿实现
=======
# 需求
Python3.9+(64-bit)with pygame and heaqp installed.
# 可执行操作
- 在setting.py文件中可修改蛇的初始速度,蛇的速度单位,地图的长宽等
- 在run.py文件中可选择hamilton或者greedy两种解决方法之一来运行贪吃蛇ai
- 在游戏开始后按 $\uparrow$ 和 $\downarrow$ 来调整蛇的速度大小
## 选题描述
用python实现贪吃蛇ai。游戏的目的是尽可能多的吃到食物且尽可能快的占满地图中的所有格子,在游戏进行的过程中蛇的头不能撞到地图边缘或者蛇的身体。
## 设计方案
在如何保证自身安全并尽可能快的吃满地图的问题上,这次的课程设计采用了两种解决方法,分别为greedy solver和hamilton solver。
### greedy solver
step1:计算蛇头到食物的最短路径,如果存在则到step2,如果不存在则到step4
step2:如果吃到食物后蛇身占满地图,则返回蛇头到食物的最短路径,如果吃到食物后蛇身没有占满地图,则到step3
step3:创造一个模拟蛇,将让模拟蛇沿最短路径吃到食物后,搜索蛇头到蛇尾的最短路径,如果蛇头到蛇尾的最短路径存在,则返回蛇头到食物的最短路径,如果不存在,则到step4
step4:搜索蛇头到蛇尾的最长路径,如果存在,则返回蛇头到蛇尾的最长路径,如果不存在,则到step5
step5:让蛇头尽量远离食物移动
### hamilton solver
在地图上构建一个哈密尔顿回路,使蛇沿着哈密尔顿回路遍历地图上的每一个点即可,且在安全时允许蛇走近路(蛇长度小于等于地图容量的一半时)
## 实现效果
用以下参数来评判不同策略的表现:
1. 完成率:在所有测试中成功吃满整张地图的次数所占的比例。
2. 平均长度(平均分):在所有测试中蛇的平均长度,即平均分。
3. 平均步数:在所有成功吃满整张地图的蛇走过的平均步数
测试结果如下(均为1000次)
**10*10map**:
| Solvers | Completion rate | Average score | Average steps |
| :------: | :-------------: | :-----------: | :-----------: |
| Greedy | 67.1% | 99.242 | 1821.3 |
| Hamilton | 97.8% | 98.996 | 1229.8 |
不难看出,Greedy的完成度明显低于Hamilton,但平均长度却和Hamilton相差无几甚至多出一点,但平均步数明显大于Hamiton。
这是很有意思的现象。具体原因可能是Hamilton无法完成游戏时(陷入死循环)蛇身长度一般还很小,而Greedy只在蛇身长度达到98或96左右时才陷入死循环。
**9*9map**:
| solver | Completion rate | Average score | Average steps |
| :------: | :-------------: | :-----------: | :-----------: |
| Greedy | 91.0% | 80.675 | 1275.9 |
| Hamilton | 0.0% | -- | -- |
需要指出,当地图格数为奇数时,地图上不存在hamilton图,故解决方案hamilton彻底失效。
有意思的是在格数为奇数时,Greedy Solver的表现比格数为偶数时要好得多。
## 功能划分与描述
setting.py文件中存放游戏的参数,包括地图长宽,蛇的初始速度,蛇的速度单位等
greedy_solver.py文件中存放解决方法的类GreedySolver
hamilton_solver.py文件中存放解决方法的类HamiltonSolver
run.py文件用于选择性运行两种ai
以GreedySolver为例:
- 定义GreedySolver类
```py
class GreedySolver:
def __init__(self):
pygame.init()
self.screen = pygame.display.set_mode((setting.WIDTH, setting.HEIGHT))
pygame.display.set_caption('Snake Game')
self.clock = pygame.time.Clock()
self.font = pygame.font.SysFont(None, 48)
self.speed=setting.SNAKE_SPEED
self.reset()
def reset(self):
self.snake_pos = [(setting.GRID_WIDTH // 2, setting.GRID_HEIGHT // 2)]
self.snake_dir = random.choice([(1, 0), (-1, 0), (0, 1), (0, -1)])
self.apple_pos = self.generate_apple()
self.score = 1
self.game_over = False
```
- 生成食物函数
```py
def generate_apple(self):
while True:
x = random.randint(0, setting.GRID_WIDTH - 1)
y = random.randint(0, setting.GRID_HEIGHT - 1)
if (x, y) not in self.snake_pos:
return (x, y)
```
- 获取蛇的下一步可能的位置
```py
def get_neighbors(self, node):
neighbors = []
for dx, dy in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
x = node[-1][0] + dx
y = node[-1][1] + dy
new_node=list(node)
new_node.append((x,y))
del(new_node[0])
if 0 <= x < setting.GRID_WIDTH and 0 <= y < setting.GRID_HEIGHT and (x,y) not in node[1:]:
neighbors.append(new_node)
return neighbors
```
- “启发式函数”(曼哈顿距离)
```py
def heuristic(self, a, node):
return abs(a[0] - node[-1][0]) + abs(a[1] - node[-1][1])
```
- A Star算法搜索最短路径
```py
def shortest_path(self,start_node,goal):
frontier=[(0,start_node)]
came_from={}
cost_so_far={start_node[-1]:0}
final=None
while frontier:
_,current=heapq.heappop(frontier)
if current[-1]==goal:
final=current
break
lis=self.adjacent(current)
if len(came_from)!=0:
for i in range(len(lis)):
if lis[i][-1][0]-current[-1][0]==current[-1][0]-came_from[current[-1]][-1][0]\
and lis[i][-1][1]-current[-1][1]==current[-1][1]-came_from[current[-1]][-1][1]:
lis[0],lis[1]=lis[1],lis[0]
for next_pos in lis:
if next_pos[-1] not in start_node[1:]:
new_cost=cost_so_far[current[-1]]+1
if next_pos[-1] not in cost_so_far or new_cost<cost_so_far[next_pos[-1]]:
cost_so_far[next_pos[-1]]=new_cost
priority=new_cost+self.heuristic(goal,next_pos)
heapq.heappush(frontier,(priority,next_pos))
came_from[next_pos[-1]]=current
path=[]
current=final
if current==None:
return path
while current!=start_node:
path.append(current)
current=came_from[current[-1]]
path.append(start_node)
path.reverse()
return path
```
- 最长路径
```py
def longest_path_to_tail(self,start_node):
tail=start_node[0]
path=[]
current=list(start_node)
path.append(current)
lis=self.get_neighbors(current)
lis.sort(key=lambda node:self.heuristic(tail,node),reverse=True)
for i in range(len(lis)):
if lis[i][-1]==self.apple_pos:
del(lis[i])
break
for next_node in lis:
if len(self.shortest_path(next_node,next_node[0]))>1:
path.append(next_node)
break
return path
```
- greedy的具体实现
```py
def greedy(self,start_node,goal):
path=self.shortest_path(start_node,goal)
if len(path)>1:
new_snake=list(path[-1])
new_snake.insert(0,path[-2][0])
if len(new_snake)==setting.GRID_HEIGHT*setting.GRID_WIDTH:
return path
path_to_tail=self.shortest_path(new_snake,path[-2][0])
if len(path_to_tail)>1:
return path
path_to_tail=self.longest_path_to_tail(self.snake_pos)
if len(path_
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
在setting.py文件中可修改蛇的初始速度,蛇的速度单位,地图的长宽等 在run.py文件中可选择hamilton或者greedy两种解决方法之一来运行贪吃蛇ai 在游戏开始后按上和下来调整蛇的速度大小 用python实现贪吃蛇ai。游戏的目的是尽可能多的吃到食物且尽可能快的占满地图中的所有格子,在游戏进行的过程中蛇的头不能撞到地图边缘或者蛇的身体。 setting.py文件中存放游戏的参数,包括地图长宽,蛇的初始速度,蛇的速度单位等 greedy_solver.py文件中存放解决方法的类GreedySolver hamilton_solver.py文件中存放解决方法的类HamiltonSolver run.py文件用于选择性运行两种ai 用以下参数来评判不同策略的表现: 完成率:在所有测试中成功吃满整张地图的次数所占的比例。 平均长度(平均分):在所有测试中蛇的平均长度,即平均分。 平均步数:在所有成功吃满整张地图的蛇走过的平均步数 在地图上构建一个哈密尔顿回路,使蛇沿着哈密尔顿回路遍历地图上的每一个点即可,且在安全时允许蛇走近路(蛇长度小于等于地图容量的一半时)
资源推荐
资源详情
资源评论
收起资源包目录
AI-SnakeGame-main.zip (13个子文件)
AI-SnakeGame-main
hamilton_solver.py 9KB
LICENSE 34KB
.idea
snake_ai_project.iml 291B
inspectionProfiles
profiles_settings.xml 174B
modules.xml 291B
.gitignore 50B
greedy_solver.py 8KB
setting.py 346B
run.py 273B
__pycache__
hamilton_solver.cpython-39.pyc 7KB
setting.cpython-39.pyc 476B
greedy_solver.cpython-39.pyc 7KB
README.md 12KB
共 13 条
- 1
资源评论
十小大
- 粉丝: 9147
- 资源: 2553
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- SSCMS登录模块需要的JS文件
- JSP网络购物中心毕业设计(源代码+论文).rar
- 白盒测试报告.docx
- 基于LM5117芯片评估开发板硬件参考设计(原理图+PCB)+中英文数据手册资料.zip
- 照片批量重命名软件(文件批量修改图片文件名)
- app.apk
- 人工智能(AI)是计算机科学的一个分支,旨在开发和应用能够模拟、延伸和扩展人类智能的理论、方法和技术,包括机器人、语言识别、图像
- 嵌入式与物联网开发是当今信息技术领域的两大重要分支,它们相互交织,共同推动着智能化时代的进步 嵌入式开发主要关注在嵌入式操作
- 网络安全,这一看似高深莫测的领域,实则与我们每个人的生活息息相关
- 毕业设计基于深度学习的视觉问答系统源码+文档说明+答辩PPT.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功