This page looks best with JavaScript enabled

康威的生命游戏(Rust + WebAssembly)

 ·  ☕ 2 min read

很早之前就知道有一个有趣的东西叫 conway’s game of life (康威的人生游戏),前段时间我用 Rust 实现了一遍,并且尝试将原作者提出的 2d版本改成3d版;还尝试了 Rust WebAssembly,在网页上欣赏生命游戏。

生命游戏简介

康威的生命游戏是英国数学家 John Horton Conway 在 1970 年提出的一种元胞自动机, 这也是元胞自动机最好的例子。这是一个零玩家的游戏,游戏中的每个细胞都有两种状态,一种是活的,另一种是死的。

规则

  1. 每个细胞有两种状态 - 存活或死亡,每个细胞与以自身为中心的周围八格细胞产生互动(如图,黑色为存活,白色为死亡)
  2. 当前细胞为存活状态时,当周围的存活细胞低于 2 个时(不包含 2 个),该细胞变成死亡状态。(模拟生命数量稀少)
  3. 当前细胞为存活状态时,当周围有 2 个或 3 个存活细胞时,该细胞保持原样。
  4. 当前细胞为存活状态时,当周围有超过 3 个存活细胞时,该细胞变成死亡状态。(模拟生命数量过多)
  5. 当前细胞为死亡状态时,当周围有 3 个存活细胞时,该细胞变成存活状态。(模拟繁殖)

对应的代码实现为:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#[wasm_bindgen]
#[derive(PartialEq)]
pub enum Live {
    Alive,
    Dead,
}

#[wasm_bindgen]
pub struct Cell {
    live: Live,
    birth_day: u64,
}

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
  let mut live: Live;
  let neighbors = self.get_board(prev_i).alive_neighbors_count(w, h);
  match neighbors {
      0..=1 => {
          live = Live::Dead;
      }
      3 => {
          live = Live::Alive;
      }
      4..=u8::MAX => {
          live = Live::Dead;
      }
      _ => {
          if self.get_board(prev_i).is_alive(w, h) {
              live = Live::Alive;
          } else {
              live = Live::Dead;
          }
      }
  }

我在上述 5 条规则的基础上,增加了一条规则: 6. 如果当前细胞为死亡状态时,则有机会被复活。(模拟随机繁殖)

1
2
3
4
5
6
7
  if live == Live::Dead
      && timenow
          % (CHECKERBOARD_SIZE + (w + 1) * (h + 1) + 9873 + neighbors as usize) as u64
          == 0 {
      live = Live::Alive;
  }

附加规则

你也可以去增删更多的规则, 比如

  • 当前细胞的死活不仅与父代有关,还与祖父代有关,甚至是和祖祖父代扯上关系。
  • 你甚至还可以改变 2d 的世界版图,将它改成边缘连续的环状世界, 比如:球面, 柱面。

过段时间就可以看到,地图上就会出现一些稳定状态的细胞, 比如形状像方块,像木桶,叉子,船等等。
还有一些震荡状态的细胞,他们经历几次生命循环(>=2 次)后,会回到祖先的状态。
还有一些会一边移动同时一边震荡的细胞。

这是我加上了规则 6 的模拟生命游戏(和该博客背景一样,使用 WebAssembly 完成的):
Conway’s game of life. build by Rust and Rust WebAssembly

reference

Play John Conway’s Game of Life
3D Translation in Computer Graphics
Conway’s Game of Life - Wikipedia
LifeWiki

Share on

EXEC
WRITTEN BY
EXEC
Evil EXEC