Knights Tour 递归 C# 我做这些事情的方式有问题

Knights Tour recursive C# Im getting something wrong in my way of doing the stuff

class Knight
{
    public static readonly double LegalDistance = Math.Sqrt(5);
    public Stack<Field> Steps { get; set; }

    private static readonly List<Field> board = Board.GameBoard;
    private static List<Field> fields;       

    private static readonly Random random = new Random();
    private static readonly object synLock = new object(); 

    public Knight(Field initial)
    {
        Steps = new Stack<Field>();
        Steps.Push(initial);
    }

    public void Move()
    {
        Field destination = Choose();

        if (destination == null)
        {
            return;
        }

        Console.WriteLine("Moving from " + GetPosition().GetFieldName() + " to " + destination.GetFieldName());
        Steps.Push(destination);
    }

    public Field Back()
    {
        Field from = Steps.Pop();
        Console.WriteLine("Moving back from " + from.GetFieldName() + " to " + GetPosition().GetFieldName());

        return from;
    }

    public Field Choose()
    {
        List<Field> legalMoves = Behaviour();

        legalMoves.RemoveAll(field => Steps.Contains(field, new FieldValueComparer()));

        if (legalMoves.Count == 0)
        {
            return null;
        }

        Field theChoosenOne;

        int index;
        lock (synLock)
        {
            index = random.Next(0, legalMoves.Count);
        }

        theChoosenOne = legalMoves.ElementAt(index);


        return theChoosenOne;
    }

    private List<Field> Behaviour()
    {
        fields = new List<Field>();
        fields.AddRange(board);

        for (int i = fields.Count - 1; i >= 0; i--)
        {
            double actualDistance = fields[i].GetDistance(GetPosition());
            if (!actualDistance.Equals(LegalDistance))
            {
                fields.Remove(fields[i]);
            }
        }

        return fields;
    }
    public List<Field> GetSteps()
    {
        return Steps.ToList();
    }

    public Field GetPosition()
    {
        return Steps.Peek();
    }
}

这就是我做事的方式。问题是,我缺少一些关键功能,因为在给定步数较低时它会回溯到开始,在步数较高时会导致 Whosebug。

这里还有一些其他的函数可以让你明白我想做什么: 计算距离:

public double GetDistance(Field other)
{
       return Math.Sqrt(Math.Pow(other.X - X, 2) + Math.Pow(other.Y - Y, 2));
}

正在寻找路径:

class PathFinder
    {
        public static void FindPath(Knight knight)
        {

            if (knight.Steps.Count != 20)
            {
                knight.Move();

                FindPath(knight);

                knight.Back();
            }
        }
    }

您的路径搜索本质上是随机游走。在大板上,这可能需要一段时间。

关于 Whosebug:请注意,当无处可去时,您不会在 Move() 上推送任何内容。因此,在对 FindPath() 的递归调用中,仍然会有相同的 knight.Steps.Count、相同的位置、相同的 null return Choose()... 等等继续,直到你离开堆栈 space.

明显的解决方法是将 bool return 值添加到 Move() 以指示是否有 任何移动。除非使用随机移动背后有实际原因,否则建议使用更具确定性的搜索算法。