前回は、ライフゲームの骨格である、フィールドとセルの状況を調べる、盤面を描画するっていう3つ部分を作りました。
今回は、ライフゲームの次の段階。
世代更新の部分を作っていきます。
世代更新
ライフゲームは、自分と自分の周りのセルの状況(生と死)によって、自分のふるまい(誕生か死亡)が決まります。
おさらいすると
- 過密
- 生きているセルの周りに4つ以上ならそのセルは死亡
- 均衡状態
- 生きているセルの周りのセルが2か3であれば生き延びる
- 過疎
- 生きているセルの周りのセルが1つの場合は、死亡
- 誕生
- 死んでいるセル周りのセルがちょうど3つの時に死んでるセルは生き返る
このルールをもとにプログラミングしていきます。
世代更新の実装
次の世代に行く世代更新をプログラミングしていきます。
fn next_gen(&mut self){
let mut next_cells = self.cells.clone();
for row in 1..self.height+1{
for column in 1..self.width+1{
let idx = self.get_index(row, column);
let cell = self.cells[idx];
let alive_cells = self.get_alive_cells(row, column);
let next_cell = match (cell,alive_cells) {
(Cell::Alive,x) if x < 2 => Cell::Dead,
(Cell::Alive,2) |(Cell::Alive,3) =>Cell::Alive,
(Cell::Alive,x) if x >3 =>Cell::Dead,
(Cell::Dead,3)=>Cell::Alive,
(otherwise,_) =>otherwise
};
next_cells[idx]=next_cell;
}
}
self.cells = next_cells;
}
引数を&mut selfとして、自己の更新をできるようにします。
まず最初にセルの状態の自身のコピーを作ります。
そして、全セルに対して更新していきます。
それをforループで回しています。
パターンマッチングを使って、自身のセルが生きているか死んでいるか、そして、自分以外の周りのセルがいくつ生きているか。これで、次の自分の運命が決まります。
一個一個取り出して更新をかけて終わりです。
実際に動くか確かめてみる
では、実際にちゃんと動くか確かめてみましょう。
検証用にメイン関数を作ります。
fn main() {
let mut i = Field::new();
println!("{}",i.to_string());
i.next_gen();
println!("{}",i.to_string());
i.next_gen();
println!("{}",i.to_string());
}
このコードでは、2回更新を行ってます。
わかりやすく、グライダーを作ります。
let cells = [
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,1,0,0,0,0,0,
0,0,0,0,0,1,0,0,0,0,
0,0,0,1,1,1,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
].into_iter()
.map(|i|{
if i==1{
Cell::Alive
}else{
Cell::Dead
}
}).collect();
今回は10行10列のセルで行います。
実行するとこんな感じです。
・・・・・・・・・・
・・・・〇・・・・・
・・・・・〇・・・・
・・・〇〇〇・・・・
・・・・・・・・・・
・・・・・・・・・・
・・・・・・・・・・
・・・・・・・・・・
・・・・・・・・・・
・・・・・・・・・・
・・・・・・・・・・
・・・・・・・・・・
・・・〇・〇・・・・
・・・・〇〇・・・・
・・・・〇・・・・・
・・・・・・・・・・
・・・・・・・・・・
・・・・・・・・・・
・・・・・・・・・・
・・・・・・・・・・
・・・・・・・・・・
・・・・・・・・・・
・・・・・〇・・・・
・・・〇・〇・・・・
・・・・〇〇・・・・
・・・・・・・・・・
・・・・・・・・・・
・・・・・・・・・・
・・・・・・・・・・
・・・・・・・・・・
ちゃんとグライダーが飛んでますね。
まとめ
これで、ライフゲームの基本的な動き、アルゴリズムは実装できました
この後できることは
たとえば、好きな形を自由に挿入できるようにする、setterを作ったり、ビジュアル表現できるようにwasm使ってみたりbevy使ってみたり、nannou使ってみたり。
いろいろ幅はあります。
予告ではありませんが、一応この後bevyを使った表現をしていこうかなーなんて思ってます。
ライフゲームbevy編が始まるかどうか!?
こうご期待。
参考資料
作るうえで参考にしたサイトや書籍、資料など
書籍
・岡瑞起、池上高志、ドミニク・チェン、青木竜太、丸山典宏『作って動かすALife』 オライリー・ジャパン(2018)
コメント