LoginSignup
10

More than 5 years have passed since last update.

ProcessingでLife Game(簡易版)

Posted at

概要

ライフゲームの簡易シミュレーション。サイズは10x10としているが、サイズパラメータを変更することで全体サイズの変更が可能。

ルール

  • 黒のセルは生存、白のセルは死滅
  • 周りの8個のセルに対して以下のルールに従い時間発展
    • 生存しているセルが2つの場合は現状維持
    • 生存しているセルが3つの場合は生成
    • それ以外は死滅
  • 境界条件は周期的境界条件

実行方法

1.Processingの作業ディレクトリを作成
2.下記ソースコードをディレクトリ名と同じファイル名.pdeとして保存
3.初期条件に分布を0,1で指定(0:消滅 1:生存)
4.Processing上で実行

参考

ソースコード

// Processingによる簡易版ライフゲーム(サイズ10x10) 

// 定数
public class Cnst{
  public static final int XSIZE = 160;               // 画面サイズ(縦)
  public static final int YSIZE = 160;               // 画面サイズ(横)
  public static final int PXSIZE = 16;               // セルサイズ
  public static final int XN = YSIZE / PXSIZE;       // セル数(横)
  public static final int YN = XSIZE / PXSIZE;;      // セル数(縦)
  public static final int BGCOLOR = 255;             // 背景色
  public static final int FR = 1;                    // フレームレート(Hz)
  public static final int SW = 0;                    // セルの枠線の太さ
}

// セルオートマトンクラス
public class CA{
  // インスタンス変数
  int[][] s;

  // コンストラクタ
  CA(){
    this.s = new int[Cnst.XN][Cnst.YN];
    this.s = setInitConfig();
  }

  // 拡張剰余
  private int mod(int i,int n){
    if(i >= 0){return i % n; }
    else{return (i + n) % n; }  // 任意の範囲には対応していない
  }

  // 初期条件(この例ではダイハードパターンを指定)
  private int[][] setInitConfig(){
    int[][] a = {
      {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,1,0,0},
      {0,1,1,0,0,0,0,0,0,0},
      {0,0,1,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}
    };
    return a;
  }

  // 周期的境界条件で周りのセルと相互作用
  public void generate(){
    int[][] t = new int[Cnst.XN][Cnst.YN];
    for(int i = 0;i < Cnst.XN;i++){
      for(int j = 0;j < Cnst.YN;j++){
        int ip = mod(i - 1,Cnst.XN);
        int in = mod(i + 1,Cnst.XN);
        int jp = mod(j - 1,Cnst.YN);
        int jn = mod(j + 1,Cnst.YN);

        int k = this.s[ip][jp] + this.s[ip][j] + this.s[ip][jn] 
          + this.s[i][jp] + this.s[i][jn] 
          + this.s[in][jp] + this.s[in][j] + this.s[in][jn];
        t[i][j] = rule(k,s[i][j]);
      }
    }
    this.s = t;
  }

  // 選別関数 
  // kの値による分岐は、(1 - Math.signum(abs(cond - k))) * formula で記述可能
  // この例では、
  //   k = 2 状態を維持(sを返す)
  //   k = 3 生成(1を返す)
  //   それ以外 消滅(0を返す)
  // を表しており、1行では
  //   (1 - (int)Math.signum(abs(2 - k))) * s + (1 - (int)Math.signum(abs(3 - k))) * 1
  // と表せる。
  private int rule(int k,int s){
    if(k == 2){return s;}
    else if(k == 3){return 1;}
    else{return 0;}
  }

  // 描画
  public void expr(){
    for(int i = 0;i < Cnst.XN;i++){
      for(int j = 0;j < Cnst.YN;j++){
        fill(((1 - this.s[i][j]) * 255));
        strokeWeight(Cnst.SW);
        rect(Cnst.PXSIZE * i,Cnst.PXSIZE * j,Cnst.PXSIZE,Cnst.PXSIZE);
      }
    }
  }

}

// 変数
CA ca;

// セットアップ
void setup(){
   size(Cnst.YSIZE,Cnst.XSIZE);
   frameRate(Cnst.FR);
   ca = new CA();
}

// 描画
void draw(){
  background(Cnst.BGCOLOR);
  ca.expr();
  ca.generate();                                         // 周期的境界条件のもとでの相互作用
}

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10