效果展示
规则介绍
基于二维元胞自动机的生命游戏可视化实现
规则:蓝色方块代表生命
- 有颜色的方块代表生命,无颜色的方块代表死亡
-
一个细胞周围有八个细胞,对于一个活细胞来说,如果它周围的八个细胞中:
如果只有一个或没有一个是活的,那这个细胞就会死亡
如果其中两个或者三个细胞是活的,那这个细胞就能维持生命
如果超过3个细胞是活着的,那这个细胞就会因为过于拥挤而死亡 - 对于一个死细胞来说,如果这个细胞周围如果有三个细胞存活,该将获得新生。
附:所有规则都可以修改,种群初始密度也可以修改。本实验采用初始化人口随机分布,也可以自定义初始化人口分布以及网格大小得到滑翔机,播种机等复杂美观图形。
源码
''' demoName:life simulation game principle: cellular automata (two dimensional) the rule of the game : 1. colored cell represents life, uncolored cell represents death 2. a cell has eight cells around it, to a live cell: 2.1 if only one or none of them are live, the cell will die 2.2 if two or three of them are live, the cell will sustain life 2.4 if more than three of them are live, the cell will die 3. to a dead cell, if there are three alive around it ,the cell will gain life '''
import
pygame
import
sys
import
math
import
random
import
copy
pygame
.
init
(
)
chess_number
=
60
# 设置棋盘大小
LIVEDENSITY
=
0.3
#生命密度
TICK
=
10
#帧数
BG
=
(
20
,
20
,
20
)
#背景色
LINECOLOR
=
(
52
,
53
,
46
)
#网格色
LIFECOLOR
=
(
31
,
97
,
189
)
#活细胞的颜色
CELL_LENGTH
=
int
(
600
/
chess_number
)
#每个格子的像素大小
LINE_WIDTH
=
4
#线的宽度
START_POSX
=
50
START_POSY
=
50
#239,60,57 红色 79,167,47绿色 188,69,229 紫色
#224,90,9 橙色 252,61,63大红
#188,69,229 紫色 239,60,57 红
#39,202,149 天绿 31,97,189蓝色 22,178,243 天蓝
# 设置背景框大小
size
=
width
,
height
=
2
*
START_POSX
+
chess_number
*
CELL_LENGTH
,
2
*
START_POSY
+
chess_number
*
CELL_LENGTH
# 设置帧率,返回clock 类
clock
=
pygame
.
time
.
Clock
(
)
screen
=
pygame
.
display
.
set_mode
(
size
)
pygame
.
display
.
set_caption
(
"Accelerator made"
)
#画
def
draw
(
livcell
)
:
''' 进行一次绘画操作,可以理解为进行一帧操作所更新的画面 param:操作前活细胞图 return:操作后活细胞图 '''
for
i
in
range
(
chess_number
+
1
)
:
pygame
.
draw
.
line
(
screen
,
LINECOLOR
,
(
START_POSX
,
START_POSY
+
i
*
CELL_LENGTH
)
,
(
START_POSX
+
chess_number
*
CELL_LENGTH
,
START_POSY
+
i
*
CELL_LENGTH
)
,
LINE_WIDTH
)
#横线
pygame
.
draw
.
line
(
screen
,
LINECOLOR
,
(
START_POSX
+
i
*
CELL_LENGTH
,
START_POSY
)
,
(
START_POSX
+
i
*
CELL_LENGTH
,
START_POSY
+
chess_number
*
CELL_LENGTH
)
,
LINE_WIDTH
)
#竖线#
#画活细胞
livcell
=
rule
(
livcell
)
print
(
'drawnew'
,
livcell
)
return
livcell
def
drawcell
(
i
,
j
,
cellkind
)
:
''' 画出一个具体的方块 param:行,列,方块颜色种类 '''
pygame
.
draw
.
rect
(
screen
,
cellkind
,
[
START_POSX
+
CELL_LENGTH
*
j
+
(
LINE_WIDTH
-
1
)
,
START_POSY
+
CELL_LENGTH
*
i
+
(
LINE_WIDTH
-
1
)
,
CELL_LENGTH
-
LINE_WIDTH
,
CELL_LENGTH
-
LINE_WIDTH
]
,
0
)
#终点. Rect(left,top,width,height)
def
creatlife
(
density
)
:
''' 在初始状态下创造生命 param:所要求生成生命细胞的密度 return:初始生命细胞的位置图 '''
livcell
=
[
[
0
]
*
chess_number
for
i
in
range
(
chess_number
)
]
for
i
in
range
(
chess_number
)
:
for
j
in
range
(
chess_number
)
:
pwall
=
random
.
random
(
)
if
pwall
<
density
:
livcell
[
i
]
[
j
]
=
1
return
livcell
def
neighborcell
(
pos
)
:
''' 获得一个细胞周围的细胞位置,并且存入数组 param:细胞的位置 return:这个细胞所有的邻居细胞 '''
neighborList
=
[
]
x
=
pos
[
0
]
y
=
pos
[
1
]
neighborList
=
[
[
x
-
1
,
y
-
1
]
,
[
x
-
1
,
y
]
,
[
x
-
1
,
y
+
1
]
,
[
x
,
y
-
1
]
,
[
x
,
y
+
1
]
,
[
x
+
1
,
y
-
1
]
,
[
x
+
1
,
y
]
,
[
x
+
1
,
y
+
1
]
]
realnList
=
copy
.
deepcopy
(
neighborList
)
for
i
in
neighborList
:
if
i
[
0
]
<
0
or
i
[
0
]
>
chess_number
-
1
or
i
[
1
]
<
0
or
i
[
1
]
>
chess_number
-
1
:
realnList
.
remove
(
i
)
return
realnList
def
rule
(
livcell
)
:
''' 制定生命游戏的游戏规则 param:一次操作前所有活着细胞的位置 return:一次操作后所有活着细胞的位置 '''
newlivcell
=
copy
.
deepcopy
(
livcell
)
print
(
'livcell'
,
livcell
)
for
i
in
range
(
chess_number
)
:
for
j
in
range
(
chess_number
)
:
if
livcell
[
i
]
[
j
]
==
1
:
drawcell
(
i
,
j
,
LIFECOLOR
)
alive
=
0
for
cell
in
neighborcell
(
[
i
,
j
]
)
:
if
livcell
[
cell
[
0
]
]
[
cell
[
1
]
]
==
1
:
alive
+=
1
if
alive
==
0
or
alive
==
1
:
newlivcell
[
i
]
[
j
]
=
0
elif
alive
==
2
or
alive
==
3
:
newlivcell
[
i
]
[
j
]
=
1
else
:
newlivcell
[
i
]
[
j
]
=
0
else
:
alive
=
0
for
cell
in
neighborcell
(
[
i
,
j
]
)
:
if
livcell
[
cell
[
0
]
]
[
cell
[
1
]
]
==
1
:
alive
+=
1
if
alive
==
3
:
newlivcell
[
i
]
[
j
]
=
1
return
newlivcell
def
main
(
)
:
livcell
=
creatlife
(
LIVEDENSITY
)
while
True
:
for
event
in
pygame
.
event
.
get
(
)
:
# 查找关闭窗口事件
if
event
.
type
==
pygame
.
QUIT
:
sys
.
exit
(
)
# 填充背景色
screen
.
fill
(
BG
)
livcell
=
draw
(
livcell
)
# 刷新图s
pygame
.
display
.
flip
(
)
clock
.
tick
(
TICK
)
if
__name__
==
"__main__"
:
main
(
)