プログラマーなら誰しも一度はハマるライフゲーム。知ってる人も知らない人も見てってくださいな。
1.ライフゲームとは
ライフゲームはよく「最も単純な人工生命」とか言われる。まぁ見方によっては間違っていないけれど,どちらかと言うとパズルみたいなもの。
基本的には細胞(セル・Cell)の生き死にを,ルールに従って決める。ルールは大まかにいうと,
・寂しいと死んじゃう(周囲に生きているセルが無いと死ぬ)
・暑苦しいと死んじゃう(周囲にセルが多すぎると死ぬ)
・環境が良ければ子供が生まれる(周囲に生きているセルがそこそこあれば生まれる)
という感じ。もう少し詳しく言うと。
・自分が生きていて,周り8マスに生きているセルが2か3なら生きられる。
・自分が死んでいてい,周り8マスに生きているセルが3つなら生まれる。
・上記以外の場合は死ぬ。
というもの。実際の例で示す。
緑色の部分が生きているセル。上の図の赤く囲った部分のセルは,周囲に4つ生きているセルがあるので「暑苦しく」て死ぬ(黒くなる)。
逆に,生まれるケースはこんな感じ。
この図では自分が死んでいていて(黒くて),周りに生きているセルが3つなので生まれます(緑になる)。
とこんな感じになるが,実際に見てみればわかると思います。
追記
ライフゲームに関する動画で非常に面白い動画があったので貼っておきます。
2.ソースコード
上の文章を読まずにソースコードコピペするのが割りと賢い判断かもね。
boolean[][] board; /* 現在の状態を保存する変数 */
boolean[][] temp_board; /* 次の状態を保存する変数 */
int N = 64; /* 一辺の数 */
void setup() {
size(512, 512);
/* ボードの作成 */
board = new boolean[N][N];
temp_board = new boolean[N][N];
for (int i = 0; i < N * N; i++ )
board[i/N][i%N] = int(random(2)) == 0 ;
frameRate(10);
}
void draw() {
background(0);
/* 四角形の幅を決める */
int w = width/N;
/* 生き死にを決める */
step();
/* マウスで状態を変える */
edit_board();
/* 色を指定 */
fill(0, 255, 0);
stroke(0, 255, 0);
for (int i = 0; i < N; i++ ) {
for (int j = 0; j < N; j++ ) {
/* board[i][j]がtrueすなわち生きている場合描画 */
if ( board[i][j] )
rect(i*w, j*w, w, w);
}
}
}
/* 生き死にを決める関数 */
void step() {
/* temp_boardにとりあえずその後の状態を保存 */
for (int i = 0; i < N; i++ )
for (int j = 0; j < N; j++ )
temp_board[i][j] = is_alive(i, j);
/* ボードをコピー */
for (int i = 0; i < N; i++ )
for (int j = 0; j < N; j++ )
board[i][j] = temp_board[i][j];
}
boolean is_alive(int x, int y) {
int count = 0;
/* 周囲8マスを見る */
for (int i = -1; i <= 1; i++ )
for (int j = -1; j <= 1; j++ )
if ( in_range(x+i, y+j) )
if ( i != 0 || j != 0 )
if ( board[x+i][y+j] )
count++;
if ( board[x][y] && ( count == 2 || count == 3 ) )
return true;/* 生きていて周りに友達がいるから生き残れる */
else if ( board[x][y] == false && count == 3 )
return true;/* それなりに人がいるから新しい子供が生まれる */
else
return false;/* それ以外は生き残れない */
}
boolean in_range(int x, int y) {
if ( x < 0 || x >= N || y < 0 || y >= N )
return false;
return true;
}
void edit_board() {
int x = mouseX * N / width;
int y = mouseY * N / height;
if ( in_range(x, y) )
board[x][y] = !board[x][y];
}