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)