0

我正在与这个难题作斗争,我有一个类似于康威生活的小型递归程序。它有一组以 10x10 的网格排列的章鱼,每个章鱼的能级从 0 到 9。在解决这个难题的每一步中:

  • 每条章鱼的能量等级增加1
  • 如果章鱼的能量水平超过 9,它就会闪烁,即它的每个邻居都会获得一个能量增量。此增量可能导致邻居也闪烁。
  • 任何闪光的章鱼都会将其能量重置为零。

Octopus[,] _octoGrid根据拼图输入,我有一个二维数组,其中填充了不同能量水平的章鱼。我的Octopus课看起来像这样:

private class Octopus
{
    public int Y { get; }

    public int X { get; }

    public int Energy { get; set; }

    public bool HasFlashed { get; set; } = false;

    public Octopus(int y, int x, int energy)
    {
        Y = y;
        X = x;
        Energy = energy;
    }

    public static IEnumerable<Octopus> NeighbouringOctopuses(Octopus[,] array, int row, int column)
    {
        int rows = array.GetLength(0);
        int columns = array.GetLength(1);

        for (int y = row - 1; y <= row + 1; y++)
            for (int x = column - 1; x <= column + 1; x++)
                if (x >= 0 && y >= 0 && x < columns && y < rows && !(y == row && x == column))
                {
                    var oct = array[y, x];
                    yield return array[y, x];
                }
    }

    public override string ToString()
    {
        return $"{Y},{X}: {Energy}";
    }

    internal void CheckForFlash()
    {
        Energy++;
        if (Energy > 9 && !HasFlashed) Flash();
    }

    internal void Flash()
    {
        var neighbours = NeighbouringOctopuses(_octoGrid, Y, X);
        foreach (var neighbour in neighbours)
            neighbour.CheckForFlash();

        HasFlashed = true;
        Energy = 0;
        _flashCount += 1;
    }
}

我驱动“游戏”步骤的主循环如下所示:

for (int i = 0; i < 100; i++)
{
    for (int y = 0; y < _octoGrid.GetLength(0); y++)
    {
        for (int x = 0; x < _octoGrid.GetLength(1); x++)
        {
            var octo = _octoGrid[y, x];
            octo.CheckForFlash();
        }
    }
}

在运行之前,网格中没有九个能级,经过一次迭代,所有能级递增,有几个九,意味着在下一次迭代中,有几只章鱼会闪烁。由于无限递归和堆栈溢出错误,闪烁的下一次迭代永远不会完成。

我很确定我错过了visited递归到的每个相邻章鱼的某种标志或某些东西,但是添加一个像这样的简单标志阻止了溢出,但阻止了谜题输出,即 100 次迭代后的能量水平,从是正确的。我在递归中做错了什么?

4

0 回答 0