吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1829|回复: 22
收起左侧

[其他原创] C#写康威的生命游戏

[复制链接]
雪辉 发表于 2023-11-10 11:32
本帖最后由 雪辉 于 2023-11-16 09:35 编辑

最新抖音看到三体人列计算机解说,提到了康威的生命游戏,有点感兴趣,自己来开发一个生命游戏

游戏规则-思路

1、每个细胞有两种状态 - 存活1或死亡0,每个细胞与以自身为中心的周围八格细胞产生互动。
     得出需要创建二维数组记录细胞坐标信息的生死,状态只有0和1,并且需要偏移判断周围8格
2、当前细胞为存活状态1时,当周围细胞存活低于2个时,该细胞变成死亡状态。(模拟生命数量稀少,孤单而死)
    得出  if count < 2 && state == 1 细胞为0
3、当前细胞为存活状态1时,当周围有2个或3个存活细胞时,该细胞保持原样。
    得出  if (count == 2 or count == 3) && state == 1 细胞不变
4、当前细胞为存活状态1时,当周围有超过3个存活细胞时,该细胞变成死亡状态。(模拟生命数量过多,拥挤而死)
    得出  if count > 3 && state == 1 细胞为0
5、当前细胞为死亡状态0时,当周围有3个存活细胞时,该细胞变成存活状态。(模拟繁殖,为啥3人才能?)
    得出  if count == 3 && state == 0 细胞为1

总结下来就是当前活细胞周围存活为2-3个继续存活,否则为死亡
                    当前死细胞周围存活为3个时繁殖
通过二维数组完成细胞的坐标,使用位运算和偏移得出细胞生死。

GameLife.zip (36.71 KB, 下载次数: 24)

头好痒,感觉要长脑子了

难点-真头疼点
1、二维数组有边界,4个边界该如何判断后面的细胞?
目前大概想法,用字典套二位数组,判断边界是否有状态1,如果有则生成新二维数组套入字典,但是又该怎么判断这2个二维数组的连接对应?

2、目前是通过GDI绘画完成细胞生死显示,所有控件终究是有边界的,该如何解决?
目前大概想法有2个,都是使用pictureBox控件放置细胞,
1、写出pictureBox拖动方法,并生成其他四边的picturebox。(生成其他picturebox套入第一个问题生成新的二维数组,该怎么判断picturebox1和picturebox2的关联呢
2、写出pictureBox伪拖动,实际为拉伸边框操作。(拉伸边框,让二维数组四边扩大一倍,后续的想法到这就断断续续了


无边框解决方案-长脑子中

1、建立个方法,每次更新生死前判断边界是否有状态为1的值
2、给二维数组扩容
3、给画板扩容,上扩容和左扩容需要移动画板位置,实现扩容后视觉位置不变
4、给画板增加拖动效果
5、增加双缓冲,解决绘画卡顿问题
⑴、BUG:有时画板扩容后,移动位置错误
[C#] 纯文本查看 复制代码
        public void GetBoardState()
        {
            int sum_top = 0;
            int sum_bottom = 0;
            int sum_left = 0;
            int sum_rigth = 0;
            for (int i = 0; i < m; i++)
            {
                sum_top += (board[i, 0] & 1);
                sum_bottom += (board[i, n - 1] & 1);
            }
            for (int i = 0; i < n; i++)
            {
                sum_left += (board[0, i] & 1);
                sum_rigth += (board[m - 1, i] & 1);
            }
            if (sum_top > 0 || sum_bottom > 0 || sum_left > 0 || sum_rigth > 0)
            {
                int[,] board_new = (int[,])board.Clone();
                int k = board_new.GetLength(0);
                int g = board_new.GetLength(1);
                if (sum_top > 0)
                    g += base_hnum;
                if (sum_bottom > 0)
                    g += base_hnum;
                if (sum_left > 0)
                    k += base_wnum;
                if (sum_rigth > 0)
                    k += base_wnum;
                board = new int[k, g];
                for (int i = 0; i < m; i++)
                {
                    for (int j = 0; j < n; j++)
                    {
                        if (sum_top > 0 && sum_left > 0)
                            board[i + base_wnum, j + base_hnum] = board_new[i, j];
                        else if (sum_top > 0)
                            board[i, j + base_hnum] = board_new[i, j];
                        else if (sum_left > 0)
                            board[i + base_wnum, j] = board_new[i, j];
                        else
                            board[i, j] = board_new[i, j];
                    }
                }
                m = board.GetLength(0);
                n = board.GetLength(1);
                pictureBox1.Size = new Size(m * base_size + 3, n * base_size + 3);
                int x = pictureBox1.Location.X;
                int y = pictureBox1.Location.Y;
                if (sum_top > 0)
                    y -= board_new.GetLength(1) * base_size;
                if (sum_left > 0)
                    x -= board_new.GetLength(0) * base_size;
                pictureBox1.Location = new Point(x, y);
            }
        }

dh.gif

GameLife无边框.zip

28.36 KB, 下载次数: 10, 下载积分: 吾爱币 -1 CB

完整版

免费评分

参与人数 10吾爱币 +14 热心值 +8 收起 理由
Alwaysmissing + 1 + 1 用心讨论,共获提升!
Dooann + 1 我很赞同!
scapy2WA + 1 + 1 我很赞同!
猫吃 + 1 连题目都看不明白了怎么
Bob5230 + 1 + 1 我很赞同!
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
AToccam + 1 热心回复!
Rockyking + 1 我很赞同!
lookfeiji + 1 + 1 用心讨论,共获提升!
blindcat + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

backaxe 发表于 2023-11-11 09:58
[C#] 纯文本查看 复制代码
using System;
using System.Threading;

class GameOfLife
{
    private const int Width = 10;
    private const int Height = 10;
    private bool[,] grid = new bool[Width, Height];

    public GameOfLife()
    {
        InitializeRandomGrid();
    }

    private void InitializeRandomGrid()
    {
        Random random = new Random();
        for (int x = 0; x < Width; x++)
        {
            for (int y = 0; y < Height; y++)
            {
                grid[x, y] = random.Next(2) == 1;
            }
        }
    }

    public void Run()
    {
        while (true)
        {
            PrintGrid();
            UpdateGrid();
            Thread.Sleep(1000);
        }
    }

    private void PrintGrid()
    {
        Console.Clear();
        for (int y = 0; y < Height; y++)
        {
            for (int x = 0; x < Width; x++)
            {
                Console.Write(grid[x, y] ? "1 " : "0 ");
            }
            Console.WriteLine();
        }
    }

    private void UpdateGrid()
    {
        bool[,] newGrid = new bool[Width, Height];

        for (int x = 0; x < Width; x++)
        {
            for (int y = 0; y < Height; y++)
            {
                int aliveNeighbors = CountAliveNeighbors(x, y);

                if (grid[x, y])
                {
                    newGrid[x, y] = aliveNeighbors == 2 || aliveNeighbors == 3;
                }
                else
                {
                    newGrid[x, y] = aliveNeighbors == 3;
                }
            }
        }

        grid = newGrid;
    }

    private int CountAliveNeighbors(int x, int y)
    {
        int count = 0;

        for (int i = -1; i <= 1; i++)
        {
            for (int j = -1; j <= 1; j++)
            {
                if (i == 0 && j == 0) continue; // Skip the cell itself

                int nx = x + i, ny = y + j;

                // Check the bounds
                if (nx >= 0 && ny >= 0 && nx < Width && ny < Height)
                {
                    if (grid[nx, ny])
                    {
                        count++;
                    }
                }
            }
        }

        return count;
    }

    static void Main(string[] args)
    {
        GameOfLife game = new GameOfLife();
        game.Run();
    }
}
bot4o7 发表于 2023-11-22 14:22
楼主的无边框方案挺好的,但是我感觉还是有边框比较好,不仅容易实现,也符合人类目前的认知。

我个人认为,既然conway生命游戏默认了“生命”指的是细胞,那我们大可以把游戏场景想象为一个星球。这样的话,四个边界就是相连的——因此对于边界元素的处理,你可以轻松地用 取模运算 来做(对于 n x n 大小的星球, (0,0)的细胞,与(n-1,n-1), (0,n-1)这样的细胞相邻)。

仔细想一下,能允许生命无限增殖的空间,也就只有太空吧,那样就有点奇怪了,目前还未发现这种生物呢。
blindcat 发表于 2023-11-10 12:23
lookfeiji 发表于 2023-11-10 12:32
还带程序设计思路的,这个很赞
chukr11 发表于 2023-11-10 12:47
实在看不懂。头皮也很痒
感觉不到风 发表于 2023-11-10 13:25
就是个逻辑 而已  但是距离真实相差十亿八千里 细胞运动速度是随机的
fuermoxi 发表于 2023-11-10 13:34
感谢分享,很有用
雨之幽 发表于 2023-11-10 13:59
谢谢分享
林火火 发表于 2023-11-10 14:40
非常适用的软件 感谢楼主分享
NINE09 发表于 2023-11-10 15:41
非常适用的软件 感谢楼主分享
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 17:40

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表