C# C语言中的递归错误#

C# C语言中的递归错误#,c#,recursion,stack-overflow,C#,Recursion,Stack Overflow,我有时会在这段代码中遇到递归错误 谁能告诉我为什么 我想做的只是在井字游戏中自动播放。 没什么特别的。只是学习 private void Auto_play() { try { Random rnd = new Random(); int d = rnd.Next(0, 9); label3.Text = d.ToString(); if (d == 0 &

我有时会在这段代码中遇到递归错误

谁能告诉我为什么

我想做的只是在井字游戏中自动播放。 没什么特别的。只是学习

 private void Auto_play()
    {
        try
        {
            Random rnd = new Random();
            int d = rnd.Next(0, 9);
            label3.Text = d.ToString();

            if (d == 0 && A1.Enabled)
                A1.PerformClick();
            else if (d == 1 && A2.Enabled)
                A2.PerformClick();
            else if (d == 2 && A3.Enabled)
                A3.PerformClick();
            else if (d == 3 && B1.Enabled)
                B1.PerformClick();
            else if (d == 4 && B2.Enabled)
                B2.PerformClick();
            else if (d == 5 && B3.Enabled)
                B3.PerformClick();
            else if (d == 6 && C1.Enabled)
                C1.PerformClick();
            else if (d == 7 && C2.Enabled)
                C2.PerformClick();
            else if (d == 8 && C3.Enabled)
                C3.PerformClick();
            else
                Auto_play();
        }
        catch { }
    }

通过调用您已经使用的相同方法执行递归是一个坏主意,因为您将很快得到堆栈溢出。根据已经加载的内容,您可能会在几百次迭代中崩溃

解决方法是不从方法本身调用该方法。相反,您要跟踪您需要做的工作并循环,直到您没有更多的工作要做。大概是这样的:

Queue<string> queue = new Queue<string>();
queue.Enque(startingValue);

while (queue.Any())
{
    string val = queue.Deque();
    // work with string
    queue.Enque("new string found to do additional work with");
}
private void Auto_play()
{
    try
    {
        bool foundMove = false;

        while (!foundMove)
        {
            foundMove = true;

            Random rnd = new Random();
            int d = rnd.Next(0, 9);
            label3.Text = d.ToString();

            if (d == 0 && A1.Enabled)
                A1.PerformClick();
            else if (d == 1 && A2.Enabled)
                A2.PerformClick();
            else if (d == 2 && A3.Enabled)
                A3.PerformClick();
            else if (d == 3 && B1.Enabled)
                B1.PerformClick();
            else if (d == 4 && B2.Enabled)
                B2.PerformClick();
            else if (d == 5 && B3.Enabled)
                B3.PerformClick();
            else if (d == 6 && C1.Enabled)
                C1.PerformClick();
            else if (d == 7 && C2.Enabled)
                C2.PerformClick();
            else if (d == 8 && C3.Enabled)
                C3.PerformClick();
            else
                foundMove = false;
        }
    }
    catch { }
}
出于兴趣的考虑:
Random
不是很随机的。你甚至可能会发现你一遍又一遍地重放同一个游戏或一组游戏(如果你在某处跟踪它们)。用计算机获得一个真正的随机数是不可能的,但这是一个已经有很多人写过的主题

更新: 正如Nate M.指出的:上面的代码仍然很粗糙,实际上并不完整。由于多种情况,您仍可能陷入无休止的循环:

  • 游戏已结束,调用此方法(即不再有有效的移动位置)
  • 随机呼叫不断给出相同的号码或一组号码
  • 我可能还缺一两个……:)
    你能详述一下你所说的“递归错误”是什么意思吗。你的意思是程序意外停止,还是继续无休止的循环?在x次移动之后,它是一致的,还是完全随机的?如果是崩溃,请尝试捕获异常并读取消息
    catch(exception ex){string err=ex.message;}
    System.Windows.Forms.dll中发生了类型为“System.StackOverflowException”的未处理异常。请确保没有无限循环或递归。对于混乱的输入,我深表歉意。试图弄清楚这个网站:-)大概,你的
    PerformClick()
    并没有在应该结束的时候结束游戏,这意味着这个代码会无限地调用自己。请显示
    PeformClick()
    (或事件处理程序)的代码。我正要说,我认为递归可以完全消除。另一个改进可能是迭代,直到找到一个有效的单元格,然后运行单个过程,并依赖单个随机种子,而不是多个。使用上面列出的代码(尽管不太可能)仍然有无限循环的“可能性”@NateM。我添加了一个更新来说明这种可能性!为了跟进……我在其他地方寻找赢家。我记得一些类似随机冰的东西。基于时间和日期的东西。我再也不会这样了?