Cooci

Python版本：3.6.4

pygame模块；

# 原理简介

1. 哈密顿图是一个无向图，由哈密顿爵士提出，
2. 由指定的起点前往指定的终点，途中经过所有其他节点且只经过一次。
3. 在图论中是指含有哈密顿回路的图，
4. 闭合的哈密顿路径称作哈密顿回路（Hamiltonian cycle），
5. 含有图中所有顶点的路径称作哈密顿路径
6. （英语：Hamiltonian path，或Traceable path）。
7. 哈密尔顿图的定义：G=(V,E)是一个图，
8. 若G中一条通路通过且仅通过每一个顶点一次，
9. 称这条通路为哈密尔顿通路。
10. 若G中一个圈通过且仅通过每一个顶点一次，称这个圈为哈密尔顿圈。
11. 若一个图存在哈密尔顿圈，就称为哈密尔顿图。

``````'''check boundary'''
def checkboundary(self, pos):
if pos[0] < 0 or pos[1] < 0 or pos[0] >= self.num_cols or pos[1] >= self.num_rows:
return False
return True
'''the shortest'''
wait = OrderedDict()
node, pre = head, (-1, -1)
wait[node] = pre
path = {}
while wait:
node, pre = wait.popitem(last=False)
path[node] = pre
if node == food:
break
if pre in path:
prepre = path[pre]
direction = (pre[0]-prepre[0], pre[1]-prepre[1])
if (direction in self.directions) and (direction != self.directions[0]):
self.directions.remove(direction)
self.directions.insert(0, direction)
for direction in self.directions:
to = (node[0] + direction[0], node[1] + direction[1])
if not self.checkboundary(to):
continue
if to in path or to in wait or to in wall:
continue
wait[to] = node
if node != food:
return None
'''reverse path'''
if not path: return path
path_new = {}
node = food
path_new[path[node]] = node
node = path[node]
return path_new
'''the longest'''
if path is None:
return None
while node != food:
if self.extendpath(path, node, wall+[food]):
continue
node = path[node]
return path
'''extend path'''
def extendpath(self, path, node, wall):
next_ = path[node]
direction_1 = (next_[0]-node[0], next_[1]-node[1])
if direction_1 in [(0, -1), (0, 1)]:
directions = [(-1, 0), (1, 0)]
else:
directions = [(0, -1), (0, 1)]
for d in directions:
src = (node[0]+d[0], node[1]+d[1])
to = (next_[0]+d[0], next_[1]+d[1])
if (src == to) or not (self.checkboundary(src) and self.checkboundary(to)):
continue
if src in path or src in wall or to in path or to in wall:
continue
direction_2 = (to[0]-src[0], to[1]-src[1])
if direction_1 == direction_2:
path[node] = src
path[src] = to
path[to] = next_
return True
return False
'''build a Hamiltonian cycle'''
def buildcircle(self, snake):
path = self.longest(snake.coords[1: -1], snake.coords[0], snake.coords[-1])
if (not path) or (len(path) - 1 != self.num_rows * self.num_cols - len(snake.coords)):
return None
for i in range(1, len(snake.coords)):
path[snake.coords[i]] = snake.coords[i-1]
return path``````

``world = [[0 for i in range(self.num_cols)] for j in range(self.num_rows)]``

``````num = 1
node = snake.coords[-1]
world[node[1]][node[0]] = num
node = self.path[node]
while node != snake.coords[-1]:
num += 1
world[node[1]][node[0]] = num
node = self.path[node]``````

``````# obtain shortcut_path
wall = snake.coords
food = food.coord
food_number = world[food[1]][food[0]]
node, pre = wall[0], (-1, -1)
wait = OrderedDict()
wait[node] = pre
path = {}
while wait:
node, pre = wait.popitem(last=False)
path[node] = pre
if node == food:
break
node_number = world[node[1]][node[0]]
neigh = {}
for direction in self.directions:
to = (node[0]+direction[0], node[1]+direction[1])
if not self.checkboundary(to):
continue
if to in wait or to in wall or to in path:
continue
to_number = world[to[1]][to[0]]
if to_number > node_number and to_number <= food_number:
neigh[node_number] = to
neigh = sorted(neigh.items(), key=itemgetter(0), reverse=True)
for item in neigh:
wait[item[1]] = node
if node != food:
return {}
return self.reverse(path, snake.coords[0], food)``````

That's all，完全源代码详见个人主页简介获取相关文件。

340 声望
28 粉丝
0 条评论