def legal_moves(x, y, bd_size):
"""
:param x: x 坐标
:param y: y 坐标
:param bd_size: 格子数
:return: 当前格子下一步的所有合法走棋位置
"""
new_moves = []
# "马走日"的 8 个格子
direction = [(-1, -2), (-1, 2), (-2, -1), (-2, 1),
(1, -2), (1, 2), (2, -1), (2, 1)]
for d in direction:
new_x = x + d[0]
new_y = y + d[1]
# 确认不会走出棋盘
if 0 <= new_x < bd_size and 0 <= new_y < bd_size:
new_moves.append((new_x, new_y))
return new_moves
def knight_graph(bd_size):
"""构建走棋的关系图"""
graph = Graph()
# 遍历每个格子
for row in range(bd_size):
for col in range(bd_size):
node_id = pos_to_node_id(row, col, bd_size)
# 单步合法走棋
new_pos = legal_moves(row, col, bd_size)
print(new_pos)
# 把"所有合法走棋的顶点"和"当前点"形成的边,添加进去
for p in new_pos:
new_id = pos_to_node_id(p[0], p[1], bd_size)
graph.add_edge(node_id, new_id)
return graph
def pos_to_node_id(row, col, bd_size):
"""给每个格子编号"""
return row * bd_size + col
def knight_tour(n, path, u, limit):
"""
:param n: 层次 (步数)
:param path: 路径
:param u: 当前顶点
:param limit: 搜索总深度
:return:
"""
# 标记当前顶点,并加入路径列表
u.set_color('gray')
path.append(u)
# 对所有合法走棋逐一深入
if n < limit:
nbr_list = list(u.get_connections())
# print(nbr_list)
# nbr_list.sort(key=lambda x: x[0])
# print(nbr_list)
i = 0
done = False
# 选择未发现 (white) 的顶点深入
while i < len(nbr_list) and not done:
if nbr_list[i].get_color() == 'white':
# 递归调用,层次 += 1
done = knight_tour(n + 1, path, nbr_list[i], limit)
i += 1
# 若都无法完成预期深度,回溯,试本层下一个顶点
if not done:
path.pop()
u.set_color('white')
else:
done = True
return done