diff --git a/index.html b/index.html
index b44715e..587e8c3 100644
--- a/index.html
+++ b/index.html
@@ -467,12 +467,11 @@
Rules
Select an interesting premade setting (using custom activations).
diff --git a/js/automata.js b/js/automata.js
index 917431e..42b0284 100644
--- a/js/automata.js
+++ b/js/automata.js
@@ -455,7 +455,7 @@ export class LangtonsAnt extends Automata {
newAnts[i][0] = (newAnts[i][0] + 1) % this.cols; // East
break;
case 2:
- newAnts[i][1] = (newAnts[i][1] + 1) % this.cols; // South
+ newAnts[i][1] = (newAnts[i][1] + 1) % this.rows; // South
break;
case 3:
newAnts[i][0] = (newAnts[i][0] - 1 + this.cols) % this.cols; // West
@@ -900,6 +900,8 @@ export class WireWorld extends Automata {
// Fill only conductors when penstate is electrons
if (this.penState == 2 || this.penState == 3) {
if (this.grid[y][x] != 0) this.grid[y][x] = this.penState;
+ } else if (this.penState == 4) {
+ if (this.grid[y][x] == 2 || this.grid[y][x] == 3) this.grid[y][x] = 1;
} else this.grid[y][x] = this.penState;
}
}
@@ -914,12 +916,11 @@ export class WireWorld extends Automata {
1: "Conductor",
2: "Electron Head",
3: "Electron Tail",
+ 4: "Signal Eraser",
};
// Change pen state
- this.penState = (this.penState + 1) % 4;
- setConsoleText(
- `Updated pen to draw ${stateNames[this.penState]} [${this.penState}]`
- );
+ this.penState = (this.penState + 1) % 5;
+ setConsoleText(`Updated pen to draw ${stateNames[this.penState]}`);
window.requestAnimationFrame(() => this.drawCursor());
}
@@ -930,6 +931,7 @@ export class WireWorld extends Automata {
1: "rgba(255, 255, 0, 0.8)",
2: "rgba(0, 0, 255, 0.8)",
3: "rgba(255, 0, 0, 0.8)",
+ 4: "rgba(0, 255, 0, 0.8)",
};
return stateColors[this.penState];
}
@@ -957,6 +959,7 @@ export class RPSGame extends Automata {
this.winCondition = winCondition;
// Number of states played with, ranges between 3 and 5
this.stateCount = [3, 4, 5].includes(stateCount) ? 3 : stateCount;
+ console.log(stateCount, this.stateCount);
// Implement GPU kernel to update grid
this.gridUpdateKernel = this.gpu
diff --git a/js/inputs/settings.js b/js/inputs/settings.js
index 54125e0..dcbcf08 100644
--- a/js/inputs/settings.js
+++ b/js/inputs/settings.js
@@ -334,6 +334,7 @@ document.getElementById("rps-state-select").onchange = (event) => {
};
//! Neural CA Rules
+// Randomize grid weights
document.getElementById("neural-randomize").onclick = (_) => {
const settingsContainer = document.getElementById("neural-settings");
const rows = parseInt(settingsContainer.querySelector(".row-select").value);
@@ -343,7 +344,7 @@ document.getElementById("neural-randomize").onclick = (_) => {
function randomWeight() {
let randWeight = (Math.random() * 2 - 1).toFixed(4);
- if (randWeight < 0 && Math.random() < 0.1)
+ if (randWeight < 0 && Math.random() < 0.15)
randWeight = Math.abs(randWeight); // Force more positive weights
return randWeight;
}
@@ -378,9 +379,8 @@ presetSelector.onchange = (event) => {
[-0.9, -0.66, -0.9],
[0.68, -0.9, 0.68],
],
- activation: eval(
- `(${"function activation(x) {\n\treturn -(1 / Math.pow(2, 0.6 * Math.pow(x, 2))) + 1\n}"})`
- ),
+ activation:
+ "function activation(x) {\n\treturn -(1 / Math.pow(2, 0.6 * Math.pow(x, 2))) + 1\n}",
},
stars: {
weights: [
@@ -388,19 +388,7 @@ presetSelector.onchange = (event) => {
[-0.759, 0.627, -0.759],
[0.565, -0.716, 0.565],
],
- activation: eval(
- `(${"function activation(x) {\n\treturn Math.abs(x)\n}"})`
- ),
- },
- "slime-mold": {
- weights: [
- [0.8, -0.85, 0.8],
- [-0.85, -0.2, -0.85],
- [0.8, -0.85, 0.8],
- ],
- activation: eval(
- `(${"function activation(x) {\n\treturn -1 / (0.89 * Math.pow(x, 2) + 1) + 1\n}"})`
- ),
+ activation: "function activation(x) {\n\treturn Math.abs(x)\n}",
},
waves: {
weights: [
@@ -408,9 +396,7 @@ presetSelector.onchange = (event) => {
[-0.716, 0.627, -0.716],
[0.565, -0.716, 0.565],
],
- activation: eval(
- `(${"function activation(x) {\n\treturn Math.abs(1.2 * x)\n}"})`
- ),
+ activation: "function activation(x) {\n\treturn Math.abs(1.2 * x)\n}",
},
mitosis: {
weights: [
@@ -418,9 +404,8 @@ presetSelector.onchange = (event) => {
[0.88, 0.4, 0.88],
[-0.939, 0.88, -0.939],
],
- activation: eval(
- `(${"function activation(x) {\n\treturn -1 / (0.91 * Math.pow(x, 2) + 1) + 1\n}"})`
- ),
+ activation:
+ "function activation(x) {\n\treturn -1 / (0.91 * Math.pow(x, 2) + 1) + 1\n}",
},
pathways: {
weights: [
@@ -428,9 +413,8 @@ presetSelector.onchange = (event) => {
[1.0, 1.0, 1.0],
[0.0, 1.0, 0.0],
],
- activation: eval(
- `(${"function activation(x) {\n\treturn 1 / Math.pow(2, Math.pow(x - 3.5, 2))\n}"})`
- ),
+ activation:
+ "function activation(x) {\n\treturn 1 / Math.pow(2, Math.pow(x - 3.5, 2))\n}",
},
"game-of-life": {
weights: [
@@ -438,9 +422,8 @@ presetSelector.onchange = (event) => {
[1.0, 9.0, 1.0],
[1.0, 1.0, 1.0],
],
- activation: eval(
- `(${"function activation(x) {\n\tif (x == 3 || x == 11 || x == 12) {\n\treturn 1;\n}\nreturn 0}"})`
- ),
+ activation:
+ "function activation(x) {\n\tx = Math.round(x);\n\tif (x == 3 || x == 11 || x == 12) return 1;\n\treturn 0;\n}",
},
};
@@ -453,11 +436,9 @@ presetSelector.onchange = (event) => {
createGrid("neural-settings");
// Update activation
- console.log(event.target.value);
- activationSelector.selectedIndex = activationSelector.options.length - 1; // Set to custom activation
- automata.activation = argMap[event.target.value].activation;
- editor.setValue(automata.activation.toString());
+ editor.setValue(argMap[event.target.value].activation);
automata.randomize();
+ automata.resetAnimationRequests();
};
// Handle changes in activation
@@ -485,9 +466,11 @@ function setActivation(type) {
})
);
automata.activation = evaluatedFuncMap[type];
+ automata.resetAnimationRequests();
// Update code editor
editor.setValue(automata.activation.toString());
+ activationSelector.selectedIndex = Object.keys(funcMap).indexOf(type);
}
// Intialize activation func code editor
@@ -511,11 +494,14 @@ editor.session.on("change", function (_) {
const code = editor.getValue();
try {
// Evaluate the code and test it on a value
- const activation = genShieldedFunction(eval(`(${code})`));
- const testValues = [Math.random(), Math.random(), Math.random(), 0, 1];
- testValues.forEach((value) => activation(value));
- automata.activation = activation;
- setConsoleText("Updated Activation Function!");
+ if (code) {
+ const activation = genShieldedFunction(eval(`(${code})`));
+ const testValues = [Math.random(), Math.random(), Math.random(), 0, 1];
+ testValues.forEach((value) => activation(value));
+ automata.activation = activation;
+ automata.resetAnimationRequests();
+ setConsoleText("Updated Activation Function!");
+ }
} catch (error) {
console.log(`Error: ${error}`);
setConsoleText("Invalid Activation Function!");
diff --git a/js/inputs/userInput.js b/js/inputs/userInput.js
index a5f9aad..2af6c8f 100644
--- a/js/inputs/userInput.js
+++ b/js/inputs/userInput.js
@@ -228,6 +228,9 @@ function handleAction(action) {
automata.baseState ? automata.baseState : 0
)
);
+ if (automata.ants) {
+ automata.ants = [];
+ }
automata.resetAnimationRequests();
setConsoleText("Cleared Grid");
break;