Processing.jsを使ってサイトに載せてみるテスト。
ルール決定→20世代まで世代交代→ルール変更→20世代まで…のループ。
個人的には見てるだけで満足感を得られる。
検証してないけど、乱数とかシード決めてないけど毎回同じなんだろうか?
ソースコードはProcessingのサイトのやつに手を加えたものです。
だからコメントとかめちゃくちゃ。
// size of cells int cellSize = 5; // How likely for a cell to be alive at start (in percentage) float probabilityOfAliveAtStart = 15; // Variables for timer int interval = 150; int lastRecordedTime = 0; //generation int LimitGeneration = 20; int GenerationCounter = 1; //Initialize form int InitForm; // Colors for active/inactive cells color alive = color(255, 255, 255); color dead = color(0, 0, 0); // Array of cells int[][] cells; // Buffer to record the state of the cells and use this while changing the others in the interations int[][] cellsBuffer; //rules int ruleNum = 9; int[] rules; // Pause boolean pause = false; void setup() { size (700, 450); // Instantiate arrays cells = new int[width/cellSize+2][height/cellSize+2]; cellsBuffer = new int[width/cellSize+2][height/cellSize+2]; InitRule(); RuleSet2();// This stroke will draw the background grid // stroke(48); noSmooth(); noStroke(); // Initialization of cells InitCellSettings(); background(0); // Fill in black in case cells don't cover all the windows } void draw() { //Draw grid for (int x=1; x<=width/cellSize; x++) { for (int y=1; y<=height/cellSize; y++) { if (cells[x][y]==1) { fill(alive); // If alive } else { fill(dead); // If dead } rect ((x-1)*cellSize, (y-1)*cellSize, cellSize, cellSize); } } // Iterate if timer ticks if (millis()-lastRecordedTime>interval) { if (!pause) { iteration(); lastRecordedTime = millis(); GenerationCounter++; if (GenerationCounter == LimitGeneration) { RuleSet2(); InitCellSettings(); GenerationCounter = 0; } } } } void iteration() { // When the clock ticks for (int x=1; x<width/cellSize+1; x++) { for (int y=1; y<height/cellSize+1; y++) { cellsBuffer[x][y] = 0; } } for (int x=1; x<width/cellSize+1; x++) { for (int y=1; y<height/cellSize+1; y++) { if (cells[x][y] == 1) { cellsBuffer[x-1][y-1]++; cellsBuffer[x-1][y]++; cellsBuffer[x-1][y+1]++; cellsBuffer[x][y-1]++; cellsBuffer[x][y+1]++; cellsBuffer[x+1][y-1]++; cellsBuffer[x+1][y]++; cellsBuffer[x+1][y+1]++; } } } for (int x=1; x<width/cellSize+1; x++) { for (int y=1; y<height/cellSize+1; y++) { int v = StateValue(cellsBuffer[x][y]); if (v != -1) { cells[x][y] = v; } } } } // End of function void keyPressed() { if (key=='r' || key == 'R') { // Restart: reinitialization of cells InitCellSettings(); } if (key==' ') { // On/off of pause pause = !pause; } if (key=='c' || key == 'C') { // Clear all for (int x=0; x<width/cellSize; x++) { for (int y=0; y<height/cellSize; y++) { cells[x][y] = 0; } } } } //Initialize void InitCellSettings() { for (int x=1; x<width/cellSize+1; x++) { for (int y=1; y<height/cellSize+1; y++) { cells[x][y] = 0; } } preset8(); } //next state int StateValue(int v) { int rv = 0; rv = rules[v]; return rv; } //initialize rules void InitRule() { rules = new int[ruleNum]; for (int i= 1; i < ruleNum; i++) { rules[i] = -1; } } //////////////// //set next rules void RuleSet() { int sum = 0; for (int i= 0; i < ruleNum; i++) { sum += rules[i]; } rules[0]++; for (int i= 0; i < ruleNum-1; i++) { if (rules[i] == 2) { rules[i] = -1; rules[i+1]++; } } if (sum == ruleNum) { pause = !pause; InitRule(); } } void RuleSet2() { for (int i= 0; i < ruleNum; i++) { int r = int(random(3)); if(r == 0) rules[i] = -1; else if(r == 1) rules[i] = 0; else rules[i] = 1; } } /////////////// //111 //101 //111 void preset8() { InitForm = 8; int xs = (width/cellSize+2)/2; int ys = (height/cellSize+2)/2; cells[xs-1][ys-1] = 1; cells[xs][ys-1] = 1; cells[xs+1][ys-1] = 1; cells[xs-1][ys] = 1; cells[xs+1][ys] = 1; cells[xs-1][ys+1] = 1; cells[xs][ys+1] = 1; cells[xs+1][ys+1] = 1; }