let w, h, a, b, notes, assign function init(z, fn){ // really bad notes = z assign = fn build() setTempo(50) } function build(){ w = notes.length h = notes[0].length a = a || new Array(w) b = b || new Array(w) for (var i = 0; i < w; i++) { a[i] = a[i] || new Array(h) b[i] = b[i] || new Array(h) for (var j = 0; j < h; j++) { a[i][j] = b[i][j] = (notes[i][j] && notes[i][j].playing) ? 1 : 0 } } } let timeout, delay = 1200 // ~120 bpm function toggle(){ build() if (timeout) { clearTimeout(timeout) timeout = null } else { step() } } function assign_item(freq,state){ b[freq.i][freq.j] = state ? 1 : 0 } function setTempo(bpm){ console.log('bpm:', bpm) delay = 60000/bpm } function swap () { var tmp = a a = b b = tmp } function step() { clearTimeout(timeout) timeout = setTimeout(step, delay) swap() let i, j, ni, pi, nj, pj, score, state for (i = 0; i < w; i++) { for (j = 0; j < h; j++) { ni = i === 0 ? w-1 : i-1 pi = i === w-1 ? 0 : i+1 nj = j === 0 ? h-1 : j-1 pj = j === h-1 ? 0 : j+1 score = a[ni][nj] + a[ni][j] + a[ni][pj] + a[i][nj] + a[i][pj] + a[pi][nj] + a[pi][j] + a[pi][pj] state = fitness(a[i][j], score) b[i][j] = state if (a[i][j] !== state) { assign(notes[i][j], state) } } } } function fitness (old, score) { if (old === 1) { if (score === 2 || score === 3) return 1 } else { if (score === 3) return 1 } return 0 } export default { init, step, assign_item, toggle, setTempo }