JavaScript 模拟一维康威宇宙(2020年8月21日)


制作背景

大一结束了,疫情还没有结束,暑假在家里呆着,学习了html,css,还有一点点的JavaScript,以前写过一个python版本的一维康威宇宙的程序,现在想到既然js这么方便,可视化渲染很轻松就能做到,为什么不用js来写一个呢?已经有了python基础的我感觉直接用js来写应该也不会太难,先用python的思路做,js对应不会的就直接从网上搜就可以,于是我就做了一个。(未参考任何其他相关康威宇宙的程序代码,纯自己写的)

相关介绍

康威宇宙其实是二维的,我简化成了一维。对于原版康威宇宙,可以看 https://zhuanlan.zhihu.com/p/45026142

这个一维的康威宇宙就是:在一个一维的宇宙中,有一堆细胞排列在这个宇宙所在的直线上,有点细胞是活细胞,有的细胞是死细胞。每过一个时刻,整个宇宙就会变化一次。怎么变化呢?规则是这样的:

就是遍历判断每一个细胞,每个细胞会根据周围四个细胞的状态来改变自己接下来的状态,(周围四个细胞是指:自己左边的左边,左边,右边,右边的右边,一共四个邻居细胞),这样下来,宇宙中的每一个死细胞可能会变成活细胞,每一个活细胞也可能会变成死细胞。具体判断规则是这样的:

对于活细胞:如果周围四个细胞的活细胞数量在 [1, 2] 内,那么该活细胞在下一时刻继续存活,否则因为拥挤或者孤独而死亡。

对于死细胞:如果周围四个细胞的活细胞数量在 [2, 3] 内,那么该死细胞在下一时刻复活,否则继续保持死亡状态。

遍历的顺序不影响结果

效果截图

康威宇宙1111

康威宇宙1223

康威宇宙3211

源代码

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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
<!doctype html>
<!--
康威宇宙一维版 js网页版
2020年8月21日
by littlefean
-->
<html>

<head>
<meta charset="utf-8">
<title>一维版康威宇宙</title>
<style>
body {
background: rgba(23, 27, 44, 1.00);
}

a {
color: azure;
}

p {
font-size: 20px;
color: aliceblue;
}

#BLOCK_LIVE {
width: 10px;
height: 10px;
float: left;
background: rgba(214, 158, 158, 1.00);
margin: 0px;
}

#BLOCK_DEATH {
width: 10px;
height: 10px;
float: left;
background: rgba(95, 6, 8, 1.00);
margin: 0px;
}

#LINE {
height: 10px;
margin: 0px;
float: top;
}

h1 {
color: aliceblue;
text-align: center;
}
</style>
</head>

<body>
<h1>一维版康威生命游戏</h1>
<p>规则介绍:</p>
<p>相关链接:</p>
<a href="https://zhuanlan.zhihu.com/p/45026142">康威生命游戏——孤独会致命,拥挤也一样</a>
<p>图片展示:</p>
<div id="BLOCK"></div>
<script>


//定义常量
var AIR = "<div id=/"BLOCK_LIVE/"></div>";
var WIDTH = 60;
var CELL = "<div id=/"BLOCK_DEATH/"></div>";
//宇宙规则
var live_min = 1
var live_max = 2
var birth_min = 2
var birth_max = 3
//数组,表示一行
var line = new Array();
/**
* 输入整数a,b,返回[a, b]范围内的随机整数
*/
function randint(a, b) {
var rand = parseInt(Math.random() * (b + 1 - a) + a);
return rand;
}
//输入一个数组array和整数length,此函数在array内添加length个[0, 1]之间的随机整数
function randLine(array, length) {
for (var i = 0; i < length; i++) {
array.push(randint(0, 1))
}
return array;
}

//传入一个数组array,根据宇宙规则进行迭代,并返回迭代后的数组,宇宙的规则详见开头注释
function nextArray(array) {
var VIEW_R = 2;
var afterArray = new Array();
//遍历每一个位置
for (var i = 0; i < array.length; i++) {
var leftIndex = Math.max(0, i - VIEW_R);
var rightIndex = Math.min(array.length - 1, i + VIEW_R);
var neighborCount = 0;
for (var j = leftIndex; j <= rightIndex; j++) {
if (array[j] == 1 && j != i) {
neighborCount++;
}
}
//如果这段本身是死的
if (array[i] == 0) {
//判定是否需要诞生
if (birth_min <= neighborCount && neighborCount <= birth_max) {
afterArray.push(1)
}
else {
afterArray.push(0)
}
}
//如果这个细胞本身是活着的
else if (array[i] == 1) {
//判定是否存活
if (live_min <= neighborCount && neighborCount <= live_max) {
afterArray.push(1)
}
else {
afterArray.push(0)
}
}

}
return afterArray;
}
//传入数组array,该函数将数组渲染到浏览器界面上
function printLine(array) {
document.write("<div id=/"LINE/">")
for (var i = 0; i < array.length; i++) {
switch (array[i]) {
case 0:
document.write(AIR);
break;
case 1:
document.write(CELL);
break;
}
}
document.write("</div>");
}

//传入数组array,整数step,根据相关规则迭代tep次array数组。
function iterateArray(array, step) {
arrayA = array;
printLine(arrayA)
for (var i = 0; i < step; i++) {
arrayB = nextArray(arrayA);
printLine(arrayB);
arrayA = arrayB;
}
}

//执行代码:
var cellArray = randLine(line, WIDTH);
iterateArray(cellArray, 300);

</script>
</body>

</html>

额外发现

修改上面程序中的这四个数据,会改变宇宙的规则。下面的发现是 2020年2月25日 做python的对应的程序的时候发现的。

1
2
3
4
var live_min = 1
var live_max = 2
var birth_min = 2
var birth_max = 3

当前宇宙的规则是 1223 把每一时刻的状态从上到下打印在屏幕上,就会呈现大片大片的谢尔宾斯基三角形的样子,但是如果把四个变量依次修改成以下四个数,就会有不同的呈现效果。(初始状态是随机的,死细胞和活细胞出现的概率均为50%)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
1223:谢尔宾斯基三角形
1111:稀碎的谢尔宾斯基三角 + 大块竖向条
1212:内部穿插竖向条的谢尔宾斯基三角 + 大块竖向条
1314:压扁的谢尔宾斯基三角
1313:像履带一样整齐的纹理
2323:车印子
0000:被竖线切断的横线
0101:横向线
0202:横向线穿插像网
1413:几条黑竖线
1414:全白
2424:全白
1234:几条白竖线
1211:含有细微动态的二维码
1222:含有锯齿状动态的二维码
2311:二维码 + 花式轮胎印
2322:二维码 + 自行车印
1233:若干白竖线
1244:含有细微动态的很多白竖线
2222:白色各种自行车印
3434:顶端流下来一点白油,剩下全黑
3333:顶端流下来一点点白油,剩下全黑
4444:顶端流下来一点点点白油,剩下全黑

反思

今天已经是 2020年11月1日了,发现 相关在屏幕上打印的操作可以用appendChild来实现。展示的效果其实还是可以再改进的。还有程序的结构。