Home > javascript

javascript Archive

javascriptでライフゲーム

順列都市を読んで

作中にやたらと「エデンの園配置」というキーワードがでていて、ふと気になってwikipediaで調べてみたら

エデンの園配置: Garden of Eden pattern)とは、セル・オートマトンにおいて他のいかなる配置からも到達できない配置を指す。以前の状態が存在しない、つまり最初からそのように配置しない限り出現しないということから、聖書のエデンの園にちなんで命名された。

Moore (1962) によれば、1950年代にジョン・テューキーが命名したもので、これはジョン・ホートン・コンウェイライフゲームを発明するずっと前のことである。

今度はライフゲームというワードが気になり調べてみると、
単純なアルゴリズムで生命の誕生、進化、淘汰などのプロセスを簡易的なモデルで再現できる
ものらしいということなので、jsで書いてみた。

実行(IE以外)

一日中みてても飽きないわー。


(function() {
        Element = {
                remove: function(element) {
                        element.parentNode.removeChild(element);
                },
                create: function(tagName, options) {
                        options = options || {};
                        var element = document.createElement(tagName);
                        var parent;
                        if(options.parent) {
                                        parent = options.parent;
                                        delete options.parent;
                        }
                        if(options.style) {
                                for(var p in options.style)
                                element.style[p] = options.style[p];
                                delete options.style;
                        }
                        for(var p in options) element[p] = options[p];
                        if(parent) parent.appendChild(element);
                        return element;
                }
        };

        //GardenOfEden
        var GOD = {
                GardenX : 120,
                GardenY : 120,
                Garden : [],
                C  : [],
                _C : [],
                Timer : 500,

                init : function(){
                        this.CreateGarden();
                        this.BeginningTimer();
                },
                CreateGarden : function(){
                        var n = 0;
                        for (var y = 0; y <= this.GardenY - 1; y++){
                                for(var x = 0; x <= this.GardenX - 1; x++, n++){
                                        if(this.Shake()){
                                                var Gtype = "birth";
                                                var GColor = this.Image.birth;
                                                this.C[n] = 1;
                                        }else{
                                                var Gtype = "death";
                                                var GColor = this.Image.death;
                                                this.C[n] = 0;
                                        }
                                        this.Garden[n] = Element.create('div', {
                                                parent: document.body,
                                                type  : Gtype,
                                                id : n,
                                                style : {
                                                        position : 'absolute',
                                                        zIndex : 90000,
                                                        backgroundColor: GColor,
                                                        width: this.Image.width,
                                                        height: this.Image.height,
                                                        top:  (y * this.Image.width)+'px',
                                                        left: (x * this.Image.height)+'px'
                                                }
                                        });
                                        this.Garden[n].addEventListener('mousedown', function(event) {
                                                if(this.type === "birth"){
                                                        this.style.backgroundColor = GOD.Image.death;
                                                        this.type = "death";
                                                        GOD.C[this.id] = 0;
                                                }else if(this.type === "death"){
                                                        this.style.backgroundColor = GOD.Image.birth;
                                                        this.type = "birth";
                                                        GOD.C[this.id] = 1;
                                                }
                                        }, false);

                                }
                        }
                },
                Shake : function(){
                        var shake = 10; //persent
                        return (Math.floor((Math.random()*100)) < shake) ? true : false;
                },
                Beginning : function(){
                        var n;
                        this.NextDay();
                        for (n = 0; n < this.GardenY * this.GardenX; n++) this.C[n] = this._C[n];
                },
                BeginningTimer : function(){
                        this.t = setInterval(this._bindFunc(this, this.Beginning), this.Timer);
                },
                NextDay : function(){
                        var n = 0;
                        for (var y = 0; y < this.GardenY; y++) {
                                for (var x = 0; x < this.GardenX; x++, n++) {
                                        this._C[n] = this.Judgment(x, y, n);
                                        if (this.C[n] != this._C[n]) this.DeathOrBirth(n, this._C[n]);
                                }
                        }
                },
                Judgment : function(x, y, n){
                        var i, j, l = 0, _x, _y;
                        if ((x > 0 &amp;&amp; x < this.GardenX - 1) &amp;&amp; (y > 0 &amp;&amp; y < this.GardenY - 1)) {
                                l = this.C[n - this.GardenX - 1] + this.C[n - this.GardenX] + this.C[n - this.GardenX + 1]
                                  + this.C[n                - 1]                            + this.C[n                + 1]
                                  + this.C[n + this.GardenX - 1] + this.C[n + this.GardenX] + this.C[n + this.GardenX + 1]
                                  ;
                        } else {
                                for (i = -1; i < 2; i++) {
                                        for (j = -1; j < 2; j++) {
                                                if (i == 0 &amp;&amp; j == 0) continue;
                                                if (x + j == -1) _x = this.GardenX - 1;
                                                if (x + j == this.GardenX) _x = 0;
                                                if (x + j != -1 &amp;&amp; x + j != this.GardenX) _x = x + j;
                                                if (y + i == -1) _y = this.GardenY - 1;
                                                if (y + i == this.GardenY) _y = 0;
                                                if (y + i != -1 &amp;&amp; y + i != this.GardenY) _y = y + i;
                                                l += this.C[this.GardenX * _y + _x];
                                        }
                                }
                        }

                        if (this.C[n] == 0 &amp;&amp; l == 3)             return 1;
                        if (this.C[n] == 1 &amp;&amp; (l == 2 || l == 3)) return 1;
                        return 0;
                },
                DeathOrBirth : function(n, p){
                        this.Garden[n].style.backgroundColor = (p == 0) ? this.Image.death : this.Image.birth;
                },
                Image : {
                        width : 5,
                        height : 5,
                        death : "#ffffff",
                        birth : "#330033"
                },
                _bindFunc : function (bind, func){
                        return function(){
                                return func.apply(bind, arguments);
                        };
                }
        };

        GOD.init();
})();

vds apiを使ってブラウザに喋らせる

vds - voice delivery systemというWeb合成音声配信システムがあることを聞きつけ早速サンプルを作ってみました。

vdsでは有償版と無償版が提供されていて、無償版では

  • 1ヶ月に音声合成できる文字数:5万文字
  • 音声エンジン:男性音、女性音

という条件で利用できます。
今回もhello worldを喋らせるだけではつまらないので、
一行で笑せたらシリーズを喋らせてみました。

今回もTween.jsを利用しました。

一行で笑わせたらを喋ってもらうサンプル
ソースはこちら

var vdsp;
var vds;
var sp = "<?php echo $line[$rand] ?>";
window.onload=function(){
	try{
		vdsp = new VoiceDeliveryPlayer("vdsp");
		vds = new VoiceDelivery(vdsp, "vds");
		vds.setRate(0);
		vds.setCast("TakashiJPm");
	}catch(e) {
		alert("Cannot Create Object");
	}
		ttween();
}
function ttween(){
	var ele = document.getElementById("tout");
	ele.style.cursor = "hand";
	ele.style.cursor = "pointer";
	ele.onclick = function(){
		window.location.reload();
	};
	ele.innerHTML = sp;
	var cTween = new ColorTween(ele.style,
								'color',
								Tween.regularEaseInOut,
								'222222',
								'82ae46',
								3);
	cTween.onMotionFinished = function(){
		this.onMotionFinished = vds.speak(sp);
	};
	cTween.start();
}

今回はhtmlをphpで出力して、その度に読み上げる単語を変えています。
ちょっと表示と読み上げのタイミングがあってないですが、ここまでで挫折。。。

使えるAPIの関数はこちら
有償版になると、音声読み上げ完了を受け取れるコールバック関数が使えるようです。

※音声読み上げは、本来サイトのアクセシビリティを高めるために利用します。

ホーム > javascript

Search
Feeds
 

SiteMap - Return to page top