康威的生命游戏:意想不到的行为

问题描述 投票:0回答:1

我是这个论坛的新手。

我目前正在尝试在 .Net 控制台应用程序中重新创建康威的生命游戏。

我对这个模式进行了硬编码enter image description here,它基本上不会移动,并且在几代人中都保持这种状态;现在我遇到了一个问题,一代人之后一切都会消亡。

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 寻求帮助,但没有多大作用。

c# .net console-application
1个回答
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++; }
                }

第一个问题是您需要检查八个相邻的方块,而不是六个。所以

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

© www.soinside.com 2019 - 2024. All rights reserved.