本帖最后由 雪辉 于 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);
}
}
|