ライフゲーム

by ser1zw
♥0 | Line 102 | Modified 2009-12-29 04:41:38 | MIT License
play

ActionScript3 source code

/**
 * Copyright ser1zw ( http://wonderfl.net/user/ser1zw )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/5Ie8
 */

package {
  import flash.display.Sprite;
  import flash.display.Shape;
  import flash.utils.Timer;
  import flash.events.TimerEvent;
  import flash.text.TextField;
  
  public class LifeGame extends Sprite {
    private var table:Vector.<Vector.<Boolean>>; // セルの状態を保持するテーブル
    private var tmpTable:Vector.<Vector.<Boolean>>; // 更新用のテーブル
    private const TABLE_COLS:int = 10;
    private const TABLE_ROWS:int = 10;
    private var field:Shape; // セル表示フィールド
    private const CELL_WIDTH:int = 20;
    private const CELL_HEIGHT:int = 20;
    private var timer:Timer;
    private var tf:TextField; // 経過時間表示用

    public function LifeGame() {
      var i:int, j:int;
      table = new Vector.<Vector.<Boolean>>(TABLE_ROWS);
      for (j = 0; j < TABLE_ROWS; j++) {
      	table[j] = new Vector.<Boolean>(TABLE_COLS);
      	for (i = 0; i < TABLE_COLS; i++) {
      	  table[j][i] = Math.random() < 0.3; // 人口密度の初期値は0.3くらい
      	}
      }
      // 更新用のテーブルは末端を考えやすいように番兵用の領域も確保
      tmpTable = new Vector.<Vector.<Boolean>>(TABLE_ROWS + 2);
      for (j = 0; j < TABLE_ROWS + 2; j++) {
      	tmpTable[j] = new Vector.<Boolean>(TABLE_COLS + 2);
      }

      tf = new TextField();
      tf.width = 200;
      tf.height = 20;
      addChild(tf);

      field = new Shape();
      field.x = 10;
      field.y = tf.y + tf.height;
      drawField();
      addChild(field);

      timer = new Timer(1000);
      timer.addEventListener(TimerEvent.TIMER, onStep);
      timer.start();
    }

    private function onStep(e:TimerEvent):void {
      tf.text = "経過時間: " + timer.currentCount + "秒";
      updateTable();
      drawField();
    }

    private function updateTable():void {
      var i:int, j:int, di:int, dj:int, lives:int;
      // tableの内容をtmpTableにコピー(番兵つき)
      for (j = 0; j < TABLE_ROWS; j++) {
	      tmpTable[j + 1][0] = table[j][TABLE_COLS - 1];
	      tmpTable[j + 1][TABLE_COLS + 1] = table[j][0];
	      for (i = 0; i < TABLE_COLS; i++) {
	        tmpTable[j + 1][i + 1] = table[j][i]
	      }
      }
      for (i = 0; i < TABLE_COLS; i++) {
	      tmpTable[0][i + 1] = table[TABLE_ROWS - 1][i];
	      tmpTable[TABLE_ROWS + 1][i + 1] = table[0][i];
      }
      tmpTable[0][0] = table[TABLE_ROWS - 1][TABLE_COLS - 1];
      tmpTable[0][TABLE_COLS + 1] = table[0][TABLE_COLS - 1];
      tmpTable[TABLE_ROWS + 1][0] = table[TABLE_ROWS - 1][0];
      tmpTable[TABLE_ROWS + 1][TABLE_COLS + 1] = table[0][0];

      // コピーしたtmpTableを使ってtableを更新
      for (j = 0; j < TABLE_ROWS; j++) {
	      for (i = 0; i < TABLE_COLS; i++) {
	        lives = 0;
	        for (dj = -1; dj <= 1; dj++) {
	          for (di = -1; di <= 1; di++) {
	            if (tmpTable[j + 1 + dj][i + 1 + di]) {
		            lives++;
	            }
	          }
	        }
	        table[j][i] = ((!tmpTable[j + 1][i + 1] && lives == 3) || // (i, j)が死亡かつ周囲が3つ生きているか、
	          (tmpTable[j + 1][i + 1] && (lives == 2 || lives == 3))); // (i, j)が生存かつ周囲が2つか3つ生きて入れば生存
	      }
      }
    }
    
    private function drawField():void {
      var i:int, j:int, color:uint;
      field.graphics.clear();
      for (j = 0; j < TABLE_ROWS; j++) {
	      for (i = 0; i < TABLE_COLS; i++) {
	        color = table[j][i] ? 0xff0000 : 0xffffff;
	        field.graphics.beginFill(color);
	        field.graphics.drawRect(CELL_WIDTH * i, CELL_HEIGHT * j, CELL_WIDTH, CELL_HEIGHT);
	        field.graphics.endFill();
	      }
      }
      
      field.graphics.lineStyle(0.1, 0x000000);
      for (j = 0; j < TABLE_ROWS + 1; j++) {
	      field.graphics.moveTo(0, CELL_HEIGHT * j);
	      field.graphics.lineTo(CELL_WIDTH * TABLE_COLS, CELL_HEIGHT * j);
      }
      for (i = 0; i < TABLE_COLS + 1; i++) {
	      field.graphics.moveTo(CELL_WIDTH * i, 0);
	      field.graphics.lineTo(CELL_WIDTH * i, CELL_HEIGHT * TABLE_ROWS);
      }
    }
  }
}