snake/ai.py
Billts_noo 4738b5c4ff 上传文件至 /
搓了一个充满bug的算法框架
2024-08-14 12:30:17 +08:00

84 lines
3.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from data_structure import Tree
class Ai:
def __init__(self):
self.path = []
def start(self,snake,apple,settings):
openlist = []
closelist = []
starting_point = snake.coords[0]
ending_point = apple.coords
def calculate_f():
"""计算openlist各格子的f值"""
for cell in openlist:
g = abs(cell['x'] - starting_point['x']) + abs(cell['y'] - starting_point['y'])
h = abs(cell['x'] - ending_point['x']) + abs(cell['y'] - ending_point['y'])
f = g + h
cell['f'] = f
def is_wall():
# 碰到左右墙壁
if (cell['x'] == -1 or cell['x'] == settings.cell_w):
return True
# 碰到上下墙壁
if (cell['y'] == -1 or cell['y'] == settings.cell_h):
return True
# 碰到自己
if (cell in snake.coords[1:]):
return True
return False
#记得做openlist用尽、苹果在蛇里面的解决办法
while ending_point not in openlist:
if not openlist:
openlist.append(starting_point)
path_tree = Tree(starting_point)
#查找Openlist中F最小的格子并弹入Closelist
#《这里也有问题 假设下面出现的列表同步更改的错误解决了》
#《那么本来就被计算过的格子不需要再次计算 但这里依然算了》
calculate_f()
min_f = min(f['f'] for f in openlist)
for cell in openlist:
if cell['f'] == min_f:
closelist.append(cell)
openlist.remove(cell)
break
#《这里有问题 不应该for 应该只检查刚丢进closelist的那一个》
#《检查过的格子又检查一遍 也是openlist有重复格子的根本原因》
for close_cell in closelist:
near_cells = [{'x': close_cell['x'], 'y': close_cell['y'] + 1}, #获取旁边的格子上右下左
{'x': close_cell['x'] + 1, 'y': close_cell['y']},
{'x': close_cell['x'], 'y': close_cell['y'] - 1},
{'x': close_cell['x'] - 1, 'y': close_cell['y']}]
#不考虑蛇的身体或墙壁
for cell in near_cells:
if is_wall():
near_cells.remove(cell)
#排除F键值对的影响
#《为什么使用切片后copy的更改还是能影响到原openlist
#《搞得我openlist的f值全弹出了》
openlist_copy = openlist[:]
for cell_copy in openlist_copy:
cell_copy.pop('f',None)
#找出不在openlist的格子并加进openlist
#《filter疑似用错 没有筛选功能 openlist依然有重复格子》
not_in_list = filter(lambda x: x != (cell_copy for cell_copy in openlist_copy), near_cells)
openlist.extend(not_in_list)
#《这里再用一次filter查教程后是因为filter只能迭代一次》
#《filter好jb难用 我是因为看它性能消耗少才用的QAQ 换一个吧》
not_in_list = filter(lambda x: x != (cell_copy for cell_copy in openlist_copy), near_cells)
#《这里的添加节点能运行但是加不进去 只有一开始的父节点加得进去》
for not_in_cell in not_in_list:
path_tree.add_child(path_tree.find(close_cell),not_in_cell)
ending_nodes = path_tree.find(ending_point)
for node in ending_nodes.get_ancestors()[::-1]:
self.path.append(node)
self.iterator = snake.create_iterator(self.path)