规则(来自百度百科,康威生命游戏词条)
游戏开始时,每个细胞随机地设定为“生”或“死”之一的某个状态。然后,根据某种规则,计算出下一代每个细胞的状态,画出下一代细胞的生死分布图。
应该规定什么样的迭代规则呢?需要一个简单的,但又反映生命之间既协同又竞争的生存定律。为简单起见,最基本的考虑是假设每一个细胞都遵循完全一样的生存定律;再进一步,把细胞之间的相互影响只限制在最靠近该细胞的8个邻居中。
也就是说,每个细胞迭代后的状态由该细胞及周围8个细胞状态所决定。作了这些限制后,仍然还有很多方法来规定“生存定律”的具体细节。例如,在康威的生命游戏中,规定了如下生存定律。
(1)当前细胞为死亡状态时,当周围有3个存活细胞时,则迭代后该细胞变成存活状态(模拟繁殖);若原先为生,则保持不变。
(2)当前细胞为存活状态时,当周围的邻居细胞低于两个(不包含两个)存活时,该细胞变成死亡状态(模拟生命数量稀少)。
(3)当前细胞为存活状态时,当周围有两个或3个存活细胞时,该细胞保持原样。
(4)当前细胞为存活状态时,当周围有3个以上的存活细胞时,该细胞变成死亡状态(模拟生命数量过多)。
控制台实现的关键接口
设置控制台游标的函数:public static void SetCursorPosition (int left, int top); 其中left参数是列,top参数是行。
设置控制台背景色的属性:public static ConsoleColor BackgroundColor { get; set; } 黑色用来表示生存的细胞,白色用来表示死亡的细胞。
代码实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
using System; using System.Threading; namespace CellularAutomata { class Program { private static int gridRowCol = 32; private static Cell[,] grid = new Cell[gridRowCol, gridRowCol]; private static int sleepMs = 33; private static int initAlivePossibility = 4; // 4 means 1/4 static void Main( string [] args) { try { Init(); // Main loop while ( true ) { Update(); Thread.Sleep(sleepMs); } } catch (Exception e) { Console.WriteLine(e); Console.ReadKey(); } } private static void Init() { // Set Console Size Console.BufferHeight = 256; Console.BufferWidth = 256; Console.WindowWidth = 256; Console.WindowHeight = 80; Random random = new Random(); for ( int i = 0; i < grid.GetLength(0); i++) { for ( int j = 0; j < grid.GetLength(1); j++) { grid[i, j] = new Cell(); int value = random.Next(0, initAlivePossibility); if (value == 0) { grid[i, j].Value = true ; } else { grid[i, j].Value = false ; } } } } private static void Update() { for ( int i = 0; i < grid.GetLength(0); i++) { for ( int j = 0; j < grid.GetLength(1); j++) { int aliveCount = NeighborAliveCount(i, j); if (grid[i, j].Value) // Alive { if (aliveCount < 2 || aliveCount > 3) { grid[i, j].Value = false ; } } else // Death { if (aliveCount == 3) { grid[i, j].Value = true ; } } if (grid[i, j].Value) { SetAlive(i, j); } else { SetDeath(i, j); } } } } private static int NeighborAliveCount( int i, int j) { int count = 0; for ( int m = i - 1; m <= i + 1; m++) { for ( int n = j - 1; n <= j + 1; n++) { if (m == i && n == j) continue ; if (m < 0 || m >= grid.GetLength(0)) continue ; if (n < 0 || n >= grid.GetLength(1)) continue ; if (grid[m, n].Value) count++; } } return count; } private static void SetAlive( int i, int j) { string aliveStr = " " ; Console.SetCursorPosition(j * aliveStr.Length, i); Console.BackgroundColor = ConsoleColor.Black; Console.Write(aliveStr); } private static void SetDeath( int i, int j) { string deathStr = " " ; Console.SetCursorPosition(j * deathStr.Length, i); Console.BackgroundColor = ConsoleColor.White; Console.Write(deathStr); } } public class Cell { public bool Value { get ; set ; } } } |
完整代码:https://github.com/jingjiangtao/CellularAutomata
Cell类是细胞类,其中有一个bool属性Value,true表示存活,false表示死亡。将细胞单独写成类而不是一个bool值是为了后续可能的扩展。
grid变量是一个二维数组,代表格子,大小可以通过gridRowCol设置,默认32,不宜太大。
sleepMs变量是循环之间的间隔时间,单位是毫秒,默认33ms.
initAlivePossibility变量决定格子中的细胞初始化时存活的概率,计算方式为 1/initAlivePossibility,如initAlivePossibility=4,表示初始化时每个细胞的存活概率是1/4.
Main()函数中先初始化了格子中的细胞和控制台大小。设置控制台大小这一步可能会抛出越界异常,如果出现的话需要修改这个值。 接着是主循环,每次循环的间隔是sleepMs。
Update()就是实现规则的函数。
NeighborAliveCount()函数获取指定细胞的相邻细胞存活数。
SetAlive()函数和SetDeath()函数设置控制台上的显示。
如有错误,欢迎指正,谢谢!
以上就是c# 实现康威生命游戏(细胞自动机)的示例的详细内容,更多关于c# 实现康威生命游戏的资料请关注服务器之家其它相关文章!
原文链接:https://www.cnblogs.com/jingjiangtao/p/14439868.html