康威的生命游戏逻辑错误
本文关键字:错误 游戏 生命 康威 | 更新日期: 2023-09-27 18:31:02
我正在学习一个使用 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);
}
}
}
您的问题非常简单 - 您将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 ...
这应该使代码更清晰,并确保您可能犯的任何其他错误都更容易发现。
所以我看到的第一个错误是你实际上并没有为下一次迭代复制电路板。
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
...
}
...
}
这样,您可以重置每个单元格而不是每行的计数。