[Diary/2012/September]

SuperColliderで2次元Cellular Automata / 2012-09-24 (月)

今日

学生がSuperColliderの勉強のとっかかりが欲しいというので,その学生に画面をガチ見されながら2次元Cellular Automata(遷移ルールはGame of Life)をでっち上げるという事態に.
毎度思うんだが,SuperColliderのCollection.do({arg item; ~~function~~})って,itemそのものに代入することができないんだよな.
だから折角doがあるのにfor文で汚く回すことになる.
どうにかなんないかな,これ.

(
~currentCellState = Array2D.new(20, 20);
~nextCellState = Array2D.new(20, 20);


~initCellState = {
	for(0, 19, {arg index_x;
		for(0, 19, {arg index_y;
			~currentCellState.put(index_x, index_y, [0,1].choose);
			~nextCellState.put(index_x, index_y, 0);
		});
	});

	for(0, 19, {arg index_x;
		for(0, 19, {arg index_y;
			~currentCellState.at(index_x, index_y).post;
		});
		" ".postln;
	});
	" ".postln;
};
~initCellState.value;


~stepCellState = {
	for(0, 19, {arg index_x;
		for(0, 19, {arg index_y;
			//近傍8つの合計を計算する
			var sumOfCellState = 0;
			var xMinusOne = 0;
			var yMinusOne = 0;
			var xPlusOne = 0;
			var yPlusOne = 0;

			
			//端っこの時に反対側を参照する
			if((index_x == 0), {xMinusOne = 19}, {xMinusOne = index_x - 1});
			if((index_x == 19), {xPlusOne = 0}, {xPlusOne = index_x + 1});
			if((index_y == 0), {yMinusOne = 19}, {yMinusOne = index_y - 1});
			if((index_y == 19), {yPlusOne = 0}, {yPlusOne = index_y + 1});
			
			sumOfCellState = sumOfCellState + ~currentCellState.at(xMinusOne, yMinusOne);
			sumOfCellState = sumOfCellState + ~currentCellState.at(index_x, yMinusOne);
			sumOfCellState = sumOfCellState + ~currentCellState.at(xPlusOne, yMinusOne);
			sumOfCellState = sumOfCellState + ~currentCellState.at(xMinusOne, index_y);
			sumOfCellState = sumOfCellState + ~currentCellState.at(xPlusOne, index_y);
			sumOfCellState = sumOfCellState + ~currentCellState.at(xMinusOne, yPlusOne);
			sumOfCellState = sumOfCellState + ~currentCellState.at(index_x, yPlusOne);
			sumOfCellState = sumOfCellState + ~currentCellState.at(xPlusOne, yPlusOne);
			
			//sumOfCellState.postln;
			
			if((~currentCellState.at(index_x, index_y) == 0), {
				//現在死んでいるとき
				//誕生の場合を計算する
				if((sumOfCellState == 3),
					{~nextCellState.put(index_x, index_y, 1);},
					{~nextCellState.put(index_x, index_y, 0);}
				);
			},{
				//現在生きているとき
				//生存の場合
				if((sumOfCellState == 2), {~nextCellState.put(index_x, index_y, 1);});
				if((sumOfCellState == 3), {~nextCellState.put(index_x, index_y, 1);});
				//過疎の場合
				if((sumOfCellState <= 1), {~nextCellState.put(index_x, index_y, 0);});
				//過密の場合
				if((sumOfCellState >= 4), {~nextCellState.put(index_x, index_y, 0);});
			});
		});
	});
	
	for(0, 19, {arg index_x;
		for(0, 19, {arg index_y;
			~currentCellState.put(index_x, index_y, ~nextCellState.at(index_x, index_y));
			~currentCellState.at(index_x, index_y).post;
		});
		" ".postln;
	});
	" ".postln;	
};

)



~stepCellState.value;
[ ツッコミの受付は終了しています ]
この記事のリンク元