我是这个论坛的新手。
我目前正在尝试在 .Net 控制台应用程序中重新创建康威的生命游戏。
我对这个模式进行了硬编码,它基本上不会移动,并且在几代人中都保持这种状态;现在我遇到了一个问题,一代人之后一切都会消亡。
using System.Linq.Expressions;
using System.Security.Cryptography.X509Certificates;
internal class Program
{
private static Cell[,] cells;
private const int MAX = 6;
public static void Main()
{
var rand = new Random();
cells = new Cell[MAX, MAX];
for (int row = 0; row < cells.GetLength(0); row++)
{
for (int collum = 0; collum < cells.GetLength(1); collum++)
{
// cells[row,collum] = new Cell((rand.Next(0,3) == 1) ? '#' : '0');
cells[row, collum] = new Cell('0');
}
}
cells[1, 0] = new Cell('#');
cells[0, 1] = new Cell('#');
cells[2, 1] = new Cell('#');
cells[1, 2] = new Cell('#');
updateConsole();
Thread.Sleep(1000);
while (true)
{
Thread.Sleep(1000);
nextGeneration();
}
}
static void updateConsole()
{
Console.Clear();
for (int y = 0; y < cells.GetLength(1); y++)
{
for (int x = 0; x < cells.GetLength(0); x++)
{
if (cells[x, y].state == '#') Console.ForegroundColor = ConsoleColor.DarkYellow;
else Console.ForegroundColor = ConsoleColor.DarkBlue;
Console.Write(cells[x, y].state + " ");
}
Console.Write("\n");
}
}
static void nextGeneration()
{
for (int _x = 0; _x < MAX; _x++) for (int _y = 0; _y < MAX; _y++) cells[_x, _y].lastState = cells[_x, _y].state;
for (int y = 0; y < cells.GetLength(1); y++)
{
for (int x = 0; x < cells.GetLength(0); x++)
{
//cells[x, y].lastState = cells[x, y].state;
int alive = 0;
int dx = 0, dy = 0;
for (int i = 0; i < 6; i++)
{
dx = (int)Math.Round(Math.Cos(i * 45)) + x;
dy = (int)Math.Round(Math.Sin(i * 45)) + y;
if ((dx >= 0) && (dx < MAX) && (dy >= 0) && (dy < MAX)) { if (cells[dx, dy].lastState == '#') alive++; }
}
if (cells[x, y].state == '0')
{
if (alive == 3) cells[x, y].state = '#';
}
if (cells[x, y].lastState == '#')
{
if (alive == 2 || alive == 3) { cells[x, y].state = '#'; }
else { cells[x, y].state = '0'; }
}
//Console.WriteLine("x:" +x +" y:" +y + " = alive:" + alive);
}
updateConsole();
}
}
class Cell
{
public Cell(char _state)
{
this.state = _state;
this.lastState = _state;
}
public char state { get; set; }
public char lastState { get; set; }
}
}
// 0 = Dead
// # = alive
我试图确保方向不会被不必要地计算两次,并通过调试检查是否正确计算了活着的邻居;到目前为止,没有问题。之后我看看我是否正确执行了游戏规则;好像是这样。
我向 ChatGPT 和 Google Gemini 寻求帮助,但没有多大作用。
您的代码有两处不正确。两者都在本节中:
for (int i = 0; i < 6; i++)
{
dx = (int)Math.Round(Math.Cos(i * 45)) + x;
dy = (int)Math.Round(Math.Sin(i * 45)) + y;
if ((dx >= 0) && (dx < MAX) && (dy >= 0) && (dy < MAX)) { if (cells[dx, dy].lastState == '#') alive++; }
}
第一个问题是您需要检查八个相邻的方块,而不是六个。所以
6
循环中的 for
需要是 8
。
其次,
Math.Cos
和Math.Sin
都以弧度而不是角度为单位。 45° 与 π/4 弧度相同。将通话中对 45
和 Math.Cos
的使用替换为 Math.Sin
。我对您的代码进行了这些更改,并且它按预期工作。
虽然上述更改有效,但对我来说,使用三角函数来完成这样的事情似乎有点奇怪。一个更简单的解决方案是让
Math.PI / 4
从
dx
到 x - 1
循环运行,对于 x + 1
与 dy
类似,并跳过 y
和 dx == x
:的情况
dy == y