diff options
Diffstat (limited to 'js/elementarycellularautomata.js')
-rw-r--r-- | js/elementarycellularautomata.js | 157 |
1 files changed, 91 insertions, 66 deletions
diff --git a/js/elementarycellularautomata.js b/js/elementarycellularautomata.js index 402c9c7..2d079a2 100644 --- a/js/elementarycellularautomata.js +++ b/js/elementarycellularautomata.js @@ -85,89 +85,114 @@ function getNewValue(rule, above, c, binStrings) return rule[binStrings.indexOf(above)]; } +function startLoading() +{ + $("#run").prop("disabled", true); + $("#run").html("Loading..."); +} -$(document).ready(function() { - $("#run").click(function() +function stopLoading() +{ + $("#run").prop("disabled", false); + $("#run").html("Run"); +} + +function run() +{ + $("#error").html(""); + /* An elementary cellular automaton (e.g. Rule 110 (https://en.wikipedia.org/wiki/Rule_110)) */ + var time = parseInt($("#time").val()); /* Amount of time to run the automaton for. */ + var size = parseInt($("#size").val()); /* Size of the starting automaton (bits). */ + var c = parseInt($("#c").val()); + var startingConfig = $("#start").val(); /* Starting configuration for the automaton. */ + var ruleNumber = parseInt($("#rule").val()); /* Rule number (e.g. 110). (0 <= x < 256) This must be converted to a binary number before use. */ + + if (!check(time > 0, "Error - The value " + time + " is an invalid time. Time > 0.")) { - $("#error").html(""); - /* An elementary cellular automaton (e.g. Rule 110 (https://en.wikipedia.org/wiki/Rule_110)) */ - var time = parseInt($("#time").val()); /* Amount of time to run the automaton for. */ - var size = parseInt($("#size").val()); /* Size of the starting automaton (bits). */ - var c = parseInt($("#c").val()); - var startingConfig = $("#start").val(); /* Starting configuration for the automaton. */ - var ruleNumber = parseInt($("#rule").val()); /* Rule number (e.g. 110). (0 <= x < 256) This must be converted to a binary number before use. */ - - if (!check(time > 0, "Error - The value " + time + " is an invalid time. Time > 0.")) - { - /* Check for invalid time argument. */ - return; - } + /* Check for invalid time argument. */ + stopLoading(); + return; + } - if (!check(ruleNumber >= 0 && ruleNumber < Math.pow(2, Math.pow(2, 2*c+1)), - "Error - Rule number " + ruleNumber + " does not exist. 0 ≤ Rule number ≤ 2<sup>2<sup>2c+1</sup></sup>")) - { - /* Check for an out-of-bounds rule number. */ - return; - } - if (!check(startingConfigValid(startingConfig), "Error - Starting configuration invalid: " + startingConfig)) + if (!check(ruleNumber >= 0 && ruleNumber < Math.pow(2, Math.pow(2, 2*c+1)), + "Error - Rule number " + ruleNumber + " does not exist. 0 ≤ Rule number ≤ 2<sup>2<sup>2c+1</sup></sup>")) + { + /* Check for an out-of-bounds rule number. */ + stopLoading(); + return; + } + if (!check(startingConfigValid(startingConfig), "Error - Starting configuration invalid: " + startingConfig)) + { + /* Check for an invalid starting configuration. e.g. 024930283848 */ + stopLoading(); + return; + } + + if (!check(startingConfig.length <= size, "Error - Starting configuration length is greater than size!")) + { + stopLoading(); + return; + } + + if (!check(size > 0, "Error - Invalid size: " + size + ". Size > 0")) + { + /* Check for invalid size argument. */ + stopLoading(); + return; + } + + var rule = bin(ruleNumber, Math.pow(2, 2*c+1)); + + $("#canvas").prop("width", size*2); + $("#canvas").prop("height", time*2); + + + ctx = document.getElementById("canvas").getContext("2d"); + + ctx.fillStyle = "#ffffff" + ctx.fillRect(0, 0, size, time); + ctx.fillStyle = "#000000" + + startingConfig = padConfiguration(startingConfig, size); + /* Run the automaton. */ + + drawState(startingConfig, 0); + var binStrings = Array.from(Array(Math.pow(2, 2*c+1)).keys()).map(function(x) { return bin(x, 2*c+1); }).reverse(); + var lastState = startingConfig; + + for (var t = 1; t < time; t++) + { + var nextState = ""; + for (var i = 0; i < c; i++) { - /* Check for an invalid starting configuration. e.g. 024930283848 */ - return; + nextState += getNewValue(rule, pad(lastState.substring(0, i+c+1), 2*c+1), c, binStrings) } - if (!check(startingConfig.length <= size, "Error - Starting configuration length is greater than size!")) + for (var i = c; i < size-c; i++) { - return; + nextState += getNewValue(rule, lastState.substring(i-c, i+c+1), c, binStrings); } - if (!check(size > 0, "Error - Invalid size: " + size + ". Size > 0")) + for (var i = size-c; i < size; i++) { - /* Check for invalid size argument. */ - return; + nextState += getNewValue(rule, pad(lastState.substring(i-c, size), 2*c+1), c, binStrings); } - var rule = bin(ruleNumber, Math.pow(2, 2*c+1)); - - document.getElementById("canvas").width = size*2; - document.getElementById("canvas").height = time*2; - - - ctx = document.getElementById("canvas").getContext("2d"); + drawState(nextState, t); + lastState = nextState; + } - ctx.fillStyle = "#ffffff" - ctx.fillRect(0, 0, size, time); - ctx.fillStyle = "#000000" + stopLoading(); - startingConfig = padConfiguration(startingConfig, size); - /* Run the automaton. */ +} - drawState(startingConfig, 0); - var binStrings = Array.from(Array(Math.pow(2, 2*c+1)).keys()).map(function(x) { return bin(x, 2*c+1); }).reverse(); - var lastState = startingConfig; - - for (var t = 1; t < time; t++) - { - var nextState = ""; - for (var i = 0; i < c; i++) - { - nextState += getNewValue(rule, pad(lastState.substring(0, i+c+1), 2*c+1), c, binStrings) - } - - for (var i = c; i < size-c; i++) - { - nextState += getNewValue(rule, lastState.substring(i-c, i+c+1), c, binStrings); - } - - for (var i = size-c; i < size; i++) - { - nextState += getNewValue(rule, pad(lastState.substring(i-c, size), 2*c+1), c, binStrings); - } - - drawState(nextState, t); - lastState = nextState; - } +$(document).ready(function() { + $("#run").click(function() + { + startLoading(); + window.setTimeout(run, 1); }); |