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 = {};