from pythonds.graphs import Graph, Vertex

path = []


# posToNodeId将棋盘上的行列位置转换成与顶点编号相似的线性顶点数
def posToNodeId(row, column, board_size):
    return (row * board_size) + column


# 判断走法是否合理
def legalCoord(x, bdsize):
    if x >= 0 and x < bdsize:
        return True
    else:
        return False


# genLegalMoves为辅助函数,创建一个列表,用于记录从这一格开始的所有合理走法。之后所有的合理走法都被转换成图中的边
def genLegalMoves(x, y, bdSize):
    newMoves = []  # 创建一个列表
    moveOffsets = [(-1, -2), (-1, 2), (-2, -1), (-2, -1), (1, -2), (1, 2), (2, -1), (2, 1)]
    for tup in moveOffsets:
        newX = x + tup[0]
        newY = y + tup[1]
        if legalCoord(newX, bdSize) and legalCoord(newY, bdSize):
            newMoves.append((newX, newY))
    return newMoves


# knightGraph 函数遍历整个棋盘
def knightGraph(bdSize):
    ktGraph = Graph()
    for row in range(bdSize):
        for col in range(bdSize):
            nodeId = posToNodeId(row, col, bdSize)
            # 挑选出新的点
            newPositions = genLegalMoves(row, col, bdSize)
            for e in newPositions:
                #
                nid = posToNodeId(e[0], e[1], bdSize)
                # 连接两点
                ktGraph.addEdge(nodeId, nid)
    return ktGraph


# 
def knightTour(n, path, u, limit):
    u.setColor('gray')
    path.append(u)
  #  print("jin")
   # print(u)
    if n < limit:

        nbrList = list(u.getConnections())
        #print(len(nbrList))
        i = 0
        done = False
        while i < len(nbrList) and not done:
            #print(nbrList[i].getColor() == 'white')
            if nbrList[i].getColor() == 'white':
                done = knightTour(n + 1, path, nbrList[i], limit)
            i = i + 1
        if not done:  # 准备回溯
            path.pop()
            u.setColor('white')
    else:
        done = True

    return done


# 主函数
if __name__ == '__main__':
    # 打印
    g = knightGraph(5)  # 创建所有点的有效路径的图

    startVertex = g.getVertex(4)
    knightTour(0, path, startVertex, 24)
    for node in path:
        print(node.getId(), end=' ')
# print(path)