※RxJSのドキュメント読んで理解する度に更新してくかも
便乗した。
https://twitter.com/kumiromilk/status/707437861881180160
http://qiita.com/shunsugai@github/items/971a15461de29563bf90
RxJSのドキュメントをみてやっつけでやった。RxJS触るの初めてなので多分よくわかってない。
パターンわかってるからbufferWithCount
使えば簡単なのだけど、それよりも途中でSubscribeやめる方法がよくわからんかったのでcompleted
みたいな変数を作ってしまい負けた気分。念のため無限ループにはしてない。(一回ミスってjsfiddle固まった)
var zundoko = ["ズン", "ドコ"];
var completed = false;
var zundokoSource = Rx.Observable.generate(
0,
function(i) { return i < 10000 && !completed; },
function(i) { return i + 1;},
function() { return zundoko[Math.floor(Math.random() * 2 )]}
);
zundokoSource.bufferWithCount(5, 1).subscribe(
function(kotodama) {
if(kotodama.join(",") === "ズン,ズン,ズン,ズン,ドコ") {
console.log("キ・ヨ・シ!!");
completed = true;
}
}
);
リズム版
ズンズンズンズンドコにはリズムがある。ただ単純にズンドコが並べば良いわけではなく、一つ目のズンと二つ目のズンの間は少し長めに、それ以降のズンとドコの間は短めの間がある。
その"間"自体もstreamのデータとして扱い、
ズン 1500ms ズン 750ms ズン 750ms ズン 750ms ドコ
となったときだけ「キ・ヨ・シ」するようにした。1500とか750は別に曲から正確に測ったわけではなく、だいたいである。
実際1500msなり750ms待つこともあり、なかなか「キ・ヨ・シ」を発動できない。
generateWithRelativeTimeを使ったversion
var zundoko = ["ズン", "ドコ"];
var intervals = [1500,750];
var dom = document.getElementById('zundoko');
var completed = false;
var zundokoSource = Rx.Observable.generateWithRelativeTime(
0,
function() { return !completed; },
function() {},
function() {
var token = zundoko[Math.floor(Math.random() * 2 )];
var p = document.createElement("p");
p.innerHTML = token;
dom.appendChild(p);
return token;
},
function() {
return intervals[Math.floor(Math.random() * 2)];
}
).timeInterval();
var subscription = zundokoSource.bufferWithCount(5, 1).subscribe(
function(buffer) {
var zundoko = [];
var intervals = [];
buffer.forEach(function(word) {
zundoko.push(word.value);
// intervalは関数で指定しか時間ぴったりではなく
// 数msecずれるので丸め込む
intervals.push(Math.floor(word.interval / 10));
})
console.log(zundoko);
console.log(intervals.slice(1));
if(zundoko.join(",") === "ズン,ズン,ズン,ズン,ドコ" &&
intervals.slice(1).join(",") === "150,75,75,75") {
completed = true;
}
},
function(error) {
console.log("error");
},
function() {
var p = document.createElement("p");
p.innerHTML = "<strong>キ・ヨ・シ!!</srtong>";
dom.appendChild(p);
}
);
create使ったversion
var zundoko = ["ズン", "ドコ"];
var intervals = [1500,750];
var zundokoSource = Rx.Observable.create(function(observer) {
var completed = false;
function sing(interval) {
var span = interval / 750;
var zd = zundoko[Math.floor(Math.random() * 2)];
var nextInterval = intervals[Math.floor(Math.random() * 2)];
console.log(Array(span + 1).join("."));
console.log(zd);
observer.onNext(interval);
observer.onNext(zd);
if(!completed) {
setTimeout(function(){ sing(nextInterval); }, nextInterval);
}
}
sing(0);
return function() {
completed = true;
};
});
var subscription = zundokoSource.bufferWithCount(9, 1).subscribe(
function(kotodama) {
if(kotodama.join(",") === "ズン,1500,ズン,750,ズン,750,ズン,750,ドコ") {
console.log("キ・ヨ・シ!!");
subscription.dispose();
}
}
);