diff --git a/index.html b/index.html
index 1022d3c..cfff558 100644
--- a/index.html
+++ b/index.html
@@ -79,6 +79,7 @@
+
@@ -179,7 +180,7 @@
-
+
diff --git a/js/Grid.js b/js/Grid.js
index fdef8e8..b581924 100644
--- a/js/Grid.js
+++ b/js/Grid.js
@@ -1,6 +1,6 @@
var DEBUG = true;
-function Grid(x, y, z, mod_range, mode) {
+function Grid(x, y, z, mod_range, mode, state) {
this.dimx = x;
this.dimy = y;
this.dimz = z;
@@ -37,11 +37,16 @@ function Grid(x, y, z, mod_range, mode) {
//update new set of cells
this.put = function(x, y, z, cell_state) {
var key = "" + x + "," + y + "," + z;
- if (cell_state) {
+
+ if (cell_state == 1 || cell_state === -1) {
this.cells[key] = cell_state;
+ console.log("mission accomplished");
+ console.log("cell state: ", cell_state);
} else {
//research this
delete this.cells[key];
+ console.log("nay");
+ console.log("cell state: ", cell_state);
}
}
diff --git a/js/bb3Rule.js b/js/bb3Rule.js
index 227bb5d..56fcb07 100644
--- a/js/bb3Rule.js
+++ b/js/bb3Rule.js
@@ -2,6 +2,8 @@
* implements the BusyBoxes reversible CA as outlined here:
* http://arxiv.org/abs/1206.2060
*/
+
+
bb3Rule = function(grid, x, y, z, frm) {
var offx, offy, offz, swpx, swpy, swpz;
var coi = grid.get(x, y, z);
diff --git a/js/bb3StateRule.js b/js/bb3StateRule.js
new file mode 100644
index 0000000..04370e9
--- /dev/null
+++ b/js/bb3StateRule.js
@@ -0,0 +1,125 @@
+/*
+ * implements the BusyBoxes reversible CA as outlined here:
+ * http://arxiv.org/abs/1206.2060
+ */
+
+STATES=3;
+
+bb3StateRule = function(grid, x, y, z, frm) {
+ var offx, offy, offz, swpx, swpy, swpz;
+ var coi = grid.get(x, y, z);
+ if ((x + y + z & 1) != (frm & 1)) return coi; // only process if field parity is correct
+
+ function getSwap(x, y, z) { // return valid swap offset or null if there is contention
+ var swapx = null, swapy = null;
+ for (var i=0; i<8; i++) {
+ var xx = x+offx[i];
+ var yy = y+offy[i];
+ var zz = z+offz[i];
+ if (grid.get(xx, yy, zz)) {
+ if ((swapx != null) && (swapx != swpx[i] || swapy != swpy[i] || swapz != swpz[i]) ) { // swap confict, forgeddaboudit
+ return null;
+ }
+ swapx = swpx[i];
+ swapy = swpy[i];
+ swapz = swpz[i];
+ }
+ }
+ if (swapx == null) return null;
+ return [swapx, swapy, swapz];
+ }
+
+ function getSwap2(x, y, z) { // return valid swap offset or null if there is contention
+ var swapx = null, swapy = null;
+ for (var i=0; i<8; i++) {
+ var xx = x+offx[i];
+ var yy = y+offy[i];
+ var zz = z+offz[i];
+ if (grid.get(xx, yy, zz)) {
+ if ((swapx != null) && (swapx != swpx[i] || swapy != swpy[i] || swapz != swpz[i]) ) { // swap confict, forgeddaboudit
+ return null;
+ }
+ swapx = swpx[i];
+ swapy = swpy[i];
+ swapz = swpz[i];
+ }
+ }
+ if (swapx == null) return null;
+ return [swapx, swapy, swapz];
+ }
+
+ function onePlane() { // process one of 3 planes dep on phase
+ var swap = getSwap(x, y, z); // proposed swap cell as delta from xyz
+ if (swap != null) { // if valid (no immediate conflicts)
+ var swapper = grid.get(x+swap[0], y+swap[1], z+swap[2]); // get state at swap cell
+ if (swapper != coi) { // if state is different from ours, we might swap
+ var revswap = getSwap(x+swap[0], y+swap[1], z+swap[2]); // proposed swap for swap cell
+ if (revswap != null) {
+ if ( (swap[0] + revswap[0] == 0) &&
+ (swap[1] + revswap[1] == 0) && // if it matches (mutual proposed swaps), do this thing
+ (swap[2] + revswap[2] == 0)) { // we return his state; he will return ours.
+ return swapper; // That's what we call a swap, Scooby Doo
+ }
+ }
+ }
+ }
+ return coi;
+ }
+
+ var m = trueMod(frame, 3); // set up offsets & swap coords dep on phase
+ if (m==0) {
+ offx = bb_offsetx;
+ offy = bb_offsety;
+ offz = bb_offsetz;
+ swpx = bb_swapx;
+ swpy = bb_swapy;
+ swpz = bb_swapz;
+ }
+ if (m==1) {
+ offx = bb_offsetz;
+ offy = bb_offsetx;
+ offz = bb_offsety;
+ swpx = bb_swapz;
+ swpy = bb_swapx;
+ swpz = bb_swapy;
+ }
+ if (m==2) {
+ offx = bb_offsety;
+ offy = bb_offsetz;
+ offz = bb_offsetx;
+ swpx = bb_swapy;
+ swpy = bb_swapz;
+ swpz = bb_swapx;
+ }
+ return onePlane();
+}
+
+// Knight's move offsets
+var bb_offsetx = [+2, +1, -1, -2, +2, +1, -1, -2];
+var bb_offsety = [+1, +2, +2, +1, -1, -2, -2, -1];
+var bb_offsetz = [0, 0, 0, 0, 0, 0, 0, 0];
+
+// corresponding swap offsets
+var bb_swapx = [+1, -1, +1, -1, +1, -1, +1, -1];
+var bb_swapy = [-1, +1, +1, -1, +1, -1, -1, +1];
+var bb_swapz = [0, 0, 0, 0, 0, 0, 0, 0];
+
+// Javascript ftw
+function trueMod(v, base) {
+ if (v < 0) {
+ return ((v % base) + base) % base;
+ }
+ return v % base;
+}
+
+// and TDD also ftw
+bb_TEST=0;
+if(bb_TEST) {
+ var grid = new Grid(10, 10, 10);
+ grid.put(0, 0, 0, 1);
+ grid.put(1, 2, 0, 1);
+ // grid.put(-1, 2, 0, 1);
+ console.log("bbRule returns:", bbRule(grid, 0, 0, 0));
+ console.log("bbRule returns:", bbRule(grid, -1, 1, 0));
+}
+
diff --git a/js/bbRule.js b/js/bbRule.js
index 324d766..f2cc26a 100644
--- a/js/bbRule.js
+++ b/js/bbRule.js
@@ -2,6 +2,9 @@
* implements the BusyBoxes reversible CA as outlined here:
* http://arxiv.org/abs/1206.2060
*/
+
+STATES=3;
+
bbRule = function(grid, x, y, z, frm) {
var offx, offy, offz, swpx, swpy, swpz;
var coi = grid.get(x, y, z);
diff --git a/js/index.js b/js/index.js
index af0517a..5477478 100644
--- a/js/index.js
+++ b/js/index.js
@@ -443,46 +443,91 @@ function bugg_unused() {
return r;
}
-function liveCell(xyz, color) {
+function liveCell(xyz, color, state) {
var cell_obj = visual_and_numerical_grid[xyz];
+
if (!cell_obj) {
-
+ //console.log("liveCell gThreeUnused: ", gThreeUnused);
if (!gThreeUnused.length) {
var threejs = new THREE.Mesh( cube, new THREE.MeshColorFillMaterial( color ) );
- cell_obj = new CellObj(threejs, 1 );
- cell_obj.threejs.overdraw = true;
+ cell_obj = new CellObj(threejs, state );
+ ///////
+ //console.log("liveCell works--WHY???: ", cell_obj);
+ // if(state === 1){
+ // console.log("look here: ", cell_obj, gThreeInUse, gThreeUnused);
+ // cell_obj.state = -1;
+ // cell_obj.threejs = new THREE.Mesh( cube, new THREE.MeshColorFillMaterial( color ) );
+ // cell_obj.threejs.overdraw = true;
+ // scene.addObject( cell_obj.threejs );
+ // }
+ cell_obj.threejs.overdraw = true;
scene.addObject( cell_obj.threejs );
if (DEBUG) console.log("liveCell: creating new obj:", xyz, cell_obj);
+
}
+ // else if(state === -1){
+ // var threejs = new THREE.Mesh( cube, new THREE.MeshColorFillMaterial( color ) );
+ // cell_obj = new CellObj(threejs, state );
+ // ///////
+ // //console.log("liveCell works--WHY???: ", cell_obj);
+ // cell_obj.threejs.overdraw = true;
+ // scene.addObject( cell_obj.threejs );
+ // }
else {
cell_obj = gThreeUnused.pop(0);
if (DEBUG) console.log("liveCell: reusing obj:", xyz, cell_obj);
+ if(state === -1){
+ cell_obj.state = -1;
+ cell_obj.threejs = new THREE.Mesh( cube, new THREE.MeshColorFillMaterial( color ) );
+ cell_obj.threejs.overdraw = true;
+ scene.addObject( cell_obj.threejs );
+ console.log("look here: ", cell_obj, gThreeInUse, gThreeUnused);
+ }
+ else if(state === 1){
+ cell_obj.state = 1;
+ cell_obj.threejs = new THREE.Mesh( cube, new THREE.MeshColorFillMaterial( color ) );
+ cell_obj.threejs.overdraw = true;
+ scene.addObject( cell_obj.threejs );
+ console.log("should be grey--look here: ", cell_obj, gThreeInUse, gThreeUnused);
+ }
// deal with color somehow
+ ///////
+ //console.log("liveCell threeUnused length is nil: ", cell_obj);
}
gThreeInUse.push(cell_obj);
setObjPosition(cell_obj.threejs, xyz);
putGrid(cell_obj, xyz);
+
if (DEBUG) console.log("live gThreeInUse:", bugg_used(), "gThreeUnused:", bugg_unused());
}
+ //console.log("liveCell cell_obj: ", cell_obj);
// else console.log("liveCell: already live, doing nuttin", xyz);
return cell_obj;
}
function killCell(xyz) {
var obj = visual_and_numerical_grid[xyz];
+ //////
+ //console.log("killed this cell: ", obj);
if (obj) {
var i = gThreeInUse.indexOf(obj);
+ //console.log("killCell gThreeInUse index: ", i);
if (i < 0) {
- console.log("killCell: not found in gThreeInUse:", xyz, obj);
+ //console.log("killCell: not found in gThreeInUse:", xyz, obj);
}
else {
if (DEBUG) console.log("killCell", xyz, "index:", i, "obj:", obj.bugg);
+ console.log("killCell", xyz, "index:", i, "obj:", obj.bugg);
gThreeInUse.splice(i, 1);
gThreeUnused.push(obj);
}
delGrid(xyz);
+ ///////
+ //console.log("after killing: ", visual_and_numerical_grid[xyz], gThreeUnused);
setObjPosition(obj.threejs, [-1111,-1111,-1111]);
+
if (DEBUG) console.log("kill gThreeInUse:", gThreeInUse.length, "gThreeUnused:", gThreeUnused.length);
+ console.log("kill gThreeInUse:", gThreeInUse.length, "gThreeUnused:", gThreeUnused.length);
}
// else console.log("killCell: obj not vangrid, doing nothing", xyz, xyz);
}
@@ -1094,9 +1139,9 @@ function onDocumentKeyDown( event ) {
if (isRunning) break;
var obj = getGrid(cursor);
// console.log("OBJ: ", obj);
- if(obj){
- // console.log("State!: ", obj.state)
- }
+ // if(obj){
+ // // console.log("State!: ", obj.state)
+ // }
if (!obj){
// var threejs = new THREE.Mesh( cube, new THREE.MeshColorFillMaterial( colors[ color ] ) );
@@ -1107,9 +1152,12 @@ function onDocumentKeyDown( event ) {
// setObjPosition(cell_obj.threejs, cursor);
// cell_obj.threejs.overdraw = true;
// scene.addObject( cell_obj.threejs );
- liveCell(cursor, DEFAULT_COLOR);
+
+ liveCell(cursor, DEFAULT_COLOR, 1);
+
+
- mainGrid.put(cursor[0],cursor[1],cursor[2], 1)
+ mainGrid.put(cursor[0],cursor[1],cursor[2], 1);
//console.log("cell_obj: ", cell_obj)
//console.log("grid: ", visual_and_numerical_grid)
@@ -1138,17 +1186,31 @@ function onDocumentKeyDown( event ) {
// cell_obj.threejs.overdraw = true;
// scene.addObject( cell_obj.threejs );
// }
+
+
+ else if (STATES == 3 && obj.state === 1){
+ killCell(cursor);
+ console.log("3rd state ThreeUnused after killing: ", gThreeUnused)
+ //mainGrid.put(cursor[0],cursor[1],cursor[2], 0);
+ updateHash();
+ gInitialHash = lasthash;
+ gInitialFrame = frame;
+ render();
+ liveCell(cursor, 0xffff00, -1 );
+ mainGrid.put(cursor[0],cursor[1],cursor[2], -1);
+ }
else{
// scene.removeObject(obj.threejs);
// delGrid(cursor);
killCell(cursor);
mainGrid.put(cursor[0],cursor[1],cursor[2], 0)
+
}
- updateHash();
+ updateHash();
gInitialHash = lasthash;
gInitialFrame = frame;
- render();
+ render();
break;
}
}
@@ -1238,6 +1300,17 @@ function setBrushColor( value ) {
brush.material[ 0 ].color.setHex( colors[ color ] ^ 0x4C000000 );
render();
}
+
+function setRule(rule){
+ var url = rule;
+ cursor = gLastCursor;
+ setBrushPosition(cursor);
+ clearScreen();
+ reset();
+ history.replaceState(url, url, url);
+ gLastRefreshedUrl = url;
+}
+
function refreshUrl(hash) {
//console.log("should refresh:", url);
var url = hash2url(hash);
@@ -1250,6 +1323,7 @@ function refreshUrl(hash) {
gLastRefreshedUrl = url;
}
else {
+
document.location = url;
}
}
@@ -1447,6 +1521,7 @@ function hash2url(hash){
// Dan is using a hash but it is a quick and dirty solution. Might be something better
function updateHash(noLink) {
var key, keys = [];
+
for (key in visual_and_numerical_grid) {
keys.push(key);
}
@@ -1521,7 +1596,7 @@ function reset(hash) {
clearScreen();
buildFromHash(hash);
refreshUrl(gUpdateHash);
- document.getElementById("duplicates").innerHTML = "";
+ document.getElementById("duplicates").innerHTML = "";
}
function update(){
@@ -1532,6 +1607,8 @@ function update(){
refreshUrl(gUpdateHash);
}
+
+
function selectHash(hash, el, size, trail) {
if (!trail) {
AVG_TRAIL = false;
@@ -1543,16 +1620,19 @@ function selectHash(hash, el, size, trail) {
trailopt = "&trail=" + trail;
}
document.location = "/?size=" + size + trailopt + "&sel=" + el.id + "&hash=" + hash;
+ console.log("size and size!!!");
}
else {
if (lastSelectedEl) {
lastSelectedEl.style.backgroundColor = "#ddd";
}
+ console.log("no pick me!!!");
reset(hash);
el.style.backgroundColor = "cyan";
lastSelectedEl = el;
}
}
+
function clearScreen() {
isRunning = false;
visual_and_numerical_grid = {};