4

我正在上一门使用 C# 的课程,我们的第一个任务是实现 Conway 的生命游戏。我们必须通过读取格式如下的文本文件来做到这一点:

 *
  *
***

          ***

然后我们必须在屏幕上显示接下来的 10 代。我将文件读入字符串数组,然后将其复制到另一个数组。然后我逐个字符地检查它并更改复制的数组以匹配下一代应该是什么。我的问题是我必须计算活邻居的代码不起作用,我不知道为什么。我在屏幕上显示了每个单元格的活邻居数量,其中大约一半是错误的。我知道错误发生在“板”边缘的单元格上,但我不知道如何解决它。

现在,我不想为我写整件事,那有点毫无意义。我只是无法弄清楚我的逻辑在哪里。任何帮助,将不胜感激。另外,我知道我的代码总体上很差。这只是我能弄清楚的唯一方法。对不起。

 class Program
{
    static void Main(string[] args)
    {
        //gets file name from command arguments
        //checks to make sure file exists, exits if file does not exist
        if (!File.Exists(Environment.GetCommandLineArgs()[1])) { System.Environment.Exit(1); }

        //gets file name from command arguments then reads file into array of strings
        string[] gen0 = File.ReadAllLines(Environment.GetCommandLineArgs()[1]);

        string[] gen1 = gen0;
        char alive = '*';
        char dead = ' ';

        //displays first generation
        foreach (string s in gen0)
        {
            Console.WriteLine(s);
        }
        Console.WriteLine("=====================================");
        //counts live neighbors of a cell
        int count = 0;
        for (int i = 0; i < gen0.Length; i++)
        {
            count = 0;
            for (int j = 0; j < gen0[i].Length; j++)
            {
                //check top left neighbor
                if (i > 0 && j > 0 && j < gen0[i-1].Length )
                {
                    if (gen0[i - 1][j - 1] == alive) { count++; }
                }
                //check above neighbor
                if (i > 0 && j < gen0[i-1].Length)
                {
                    if (gen0[i - 1][j] == alive) { count++; }
                }
                //check top right neighbor
                if (i > 0 && j + 1 < gen0[i - 1].Length)
                {
                    if (gen0[i - 1][j + 1] == alive) { count++; }
                }
                //check left neighbor
                if (j > 0)
                {
                    if (gen0[i][j - 1] == alive) { count++; }
                }
                //check right neighbor
                if (j + 1 < gen0[i].Length)
                {
                    if (gen0[i][j + 1] == alive) { count++; }
                }
                //check bottom left neighbor
                if (i + 1 < gen0.Length && j > 0 && j < gen0[i+1].Length)
                {
                    if (gen0[i + 1][j - 1] == alive) { count++; }
                }
                //check below neighbor
                if (i + 1 < gen0.Length && j < gen0[i+1].Length)
                {
                    if (gen0[i + 1][j] == alive) { count++; }
                }
                //check bottom right neighbor
                if (i + 1 < gen0.Length && j + 1 < gen0[i].Length && j + 1 < gen0[i+1].Length)
                {
                    if (gen0[i + 1][j + 1] == alive) { count++; }
                }

                //Console.WriteLine(count); 
                //kills cells
                if (count < 2 || count > 3) 
                {
                    gen1[i] = gen1[i].Remove(j, 1);
                    gen1[i] = gen1[i].Insert(j, dead.ToString()); 
                }
                //births cells
                if (count == 3)
                {
                    gen1[i] = gen1[i].Remove(j, 1);
                    gen1[i] = gen1[i].Insert(j, alive.ToString());
                }
            }
        }
        foreach (string s in gen1)
        {
            Console.WriteLine(s);
        }
    } 
}
4

2 回答 2

2

所以我看到的第一个错误是你实际上并没有为下一次迭代复制电路板。

gen1 = gen0;

上面的代码仅将 gen1 引用分配给与 gen0 相同的对象。因此,当您修改 gen1 时,实际上您也修改了 gen0……导致后面的迭代出现不一致。尝试这个:

gen1 = (string[])gen0.Clone();

第二个错误是int count = 0应该在第二个循环而不是第一个:

for (int i = 0; i< gen0.Length; i++)
{
    // not here
    // int count = 0
    for (int j = 0; j < gen0[i].Length; j++)
    {
        // here
        int count = 0
        ...
    }
...
}

这样,您可以重置每个单元格而不是每一行的计数。

于 2013-09-12T15:55:43.310 回答
2

你的问题很简单——你count在错误的地方重置。把它放在循环中,它(可能)会工作。

关于其余的代码,如果你想让它更容易理解,只需给你的游戏区域一个单元素边框。

您需要填充您读入的文件(上下空白行,左右空白字符),并将循环更改为:

  for (int i = 1; i < gen0.Length - 1; i++)

  for (int j = 1; j < gen0[i].Length - 1; j++)

但是您的中央计数计算可以减少为单个计算:

  count = (gen0[i - 1][j - 1] == alive) ? 1 : 0 +
          (gen0[i - 1][j] == alive) ? 1 : 0 +

          ... etc ...

这应该使代码更清晰,并确保您可能犯的任何其他错误都更容易发现。

于 2013-09-12T15:46:18.927 回答