var width = 750, height = 500, sqr = document.getElementById('cell_size').value, cells_x = width/sqr, cells_y = height/sqr, speed = document.getElementById('speed').value * 10, colors = {live:"#66b266", dead:"#b26666"}, data = []; var svg = d3.select("#chart").append("svg") .attr("width", width) .attr("height", height) .attr("id", "svg_chart"); var choose_life = function() { if (Math.random() < parseInt(document.getElementById('rate_label').innerHTML) / 100) { return "live" } else { return "dead" } } var init = function() { data = []; var alive_3 = 0 svg.selectAll(".cell").remove() for (var i = 0; i < cells_x; i++) { for (var j = 0; j < cells_y; j++) { var status = choose_life() data.push({x:i,y:j, life: status, next:""}) if (status === "live") { alive_3 += 1 } } } document.getElementById('pop_count').innerHTML = Math.floor(alive_3 / data.length * 10000) / 100; document.getElementById('pop_delta').innerHTML = 0; svg.selectAll(".cell") .data(data) .enter() .append("rect") .attr("x", function(d) {return d.x * sqr;}) .attr("y", function(d) {return d.y * sqr;}) .attr("width", sqr) .attr("height", sqr) .attr("id", function(d) {return "p_" + d.x + "_" + d.y;}) .attr("class", "cell") .style("fill", function(d) {return colors[d.life];}); } init(); // Game play var start = function() { document.getElementById("start_button").innerHTML = "Stop" document.getElementById("step_count").innerHTML = 0 lust_4_life(); } var end = function() { document.getElementById("start_button").innerHTML = "Start" } var count_neighbors = function(i, x, y) { var count = 0; //ul if (x != 0 && y != 0) { if (data[i - cells_y - 1].life == "live") { count += 1 } } //u if (y != 0) { if (data[i - 1].life == "live") { count += 1 } } else { // overflow if (data[i + cells_y - 1].life == "live") { count += 1 } } //ur if (x != cells_x - 1 && y != 0) { if (data[i + cells_y - 1].life == "live") { count += 1 } } //r if (x != cells_x - 1) { if (data[i + cells_y].life == "live") { count += 1 } } //br if (x != cells_x - 1 && y != cells_y - 1) { if (data[i + cells_y + 1].life == "live") { count += 1 } } //b if (y != cells_y - 1) { if (data[i + 1].life == "live") { count += 1 } } else { // overflow if (data[i - cells_y + 1].life == "live") { count += 1 } } //bl if (x != 0 && y != cells_y + 1) { if (data[i - cells_y + 1].life == "live") { count += 1 } } //l if (x != 0) { if (data[i - cells_y].life == "live") { count += 1 } } return count } var lust_4_life = function() { var change = false, alive = 0, alive_2 = 0; if (document.getElementById("start_button").innerHTML == "Stop") { for (var i = 0; i < data.length; i++) { if (data[i].life == "live") { alive_2 += 1; } var count = count_neighbors(i, data[i].x, data[i].y) if (count == 2 && data[i].life == "live" || count == 3 && data[i].life == "live") { data[i].next = "live" alive += 1 } else if(count == 3 && data[i].life == "dead") { data[i].next = "live" alive += 1 } else { data[i].next = "dead" } } for (var i = 0; i < data.length; i++) { if (!change) { if (data[i].life != data[i].next) { change = true } } data[i].life = data[i].next; } var cells = svg.selectAll(".cell") .data(data); cells.enter().append("rect") .attr("class", "cell") .attr("x", function(d) {return d.x * sqr;}) .attr("y", function(d) {return d.y * sqr;}) .attr("width", sqr) .attr("height", sqr) .attr("id", function(d) {return "p_" + d.x + "_" + d.y;}) .merge(cells) .style("fill", function(d) {return colors[d.life];}); cells.exit().remove(); } if (change) { step_count = document.getElementById("step_count") step_count.innerHTML = parseInt(step_count.innerHTML) + 1 document.getElementById("pop_count").innerHTML = Math.floor(alive / data.length * 10000) / 100 document.getElementById("pop_delta").innerHTML = alive > 0 ? Math.floor(((alive - alive_2) / alive) * 10000) / 100 : 0 window.setTimeout(lust_4_life,speed); } else { end() } } // Event listeners document.getElementById("start_button").addEventListener("click", function(){ if (this.innerHTML == "Start") { start(); } else { end(); } }); document.getElementById("refresh").addEventListener("click", function(){ end(); init(); }); document.getElementById("cell_size").addEventListener("change", function(){ sqr = this.value; cells_x = width/sqr, cells_y = height/sqr, end(); init(); }); document.getElementById("rate").addEventListener("change", function(){ document.getElementById('rate_label').innerHTML = event.target.value + "%"; end(); init(); }); document.getElementById("speed").addEventListener("change", function(){ document.getElementById('speed_label').innerHTML = event.target.value * 10 + " ms"; speed = event.target.value * 10 });