]> git.eli173.com Git - hexmata/commitdiff
need to upload lol
authorElijah Cohen <eli@eli173.com>
Wed, 30 Mar 2022 06:31:41 +0000 (01:31 -0500)
committerElijah Cohen <eli@eli173.com>
Wed, 30 Mar 2022 06:31:41 +0000 (01:31 -0500)
grid.js [new file with mode: 0644]
index.html [new file with mode: 0644]
notes.org [new file with mode: 0644]
play.js [new file with mode: 0644]
wireworld.js [new file with mode: 0644]

diff --git a/grid.js b/grid.js
new file mode 100644 (file)
index 0000000..69c88a3
--- /dev/null
+++ b/grid.js
@@ -0,0 +1,83 @@
+
+
+class Hex {
+               // cubic coords, stored axially
+               // ref: https://www.redblobgames.com/grids/hexagons/
+               constructor(q,r,s) {
+                               if(typeof s == "undefined") {
+                                               s = -q-r;
+                               }
+                               if(q+r+s !=0) {
+                                               throw("invalid coords")
+                               }
+                               this.q = q;
+                               this.r = r;
+               }
+               get s() {
+                               return -this.q-this.r;
+               }
+               clone() {
+                               return new Hex(this.q, this.r);
+               }
+               neighbors() {
+                               var arr = [];
+                               for(var i=0; i<6; i++) {
+                                               arr.push(this.clone());
+                               }
+                               arr[0].q -= 1;
+                               arr[1].q += 1;
+                               arr[2].q += 1;
+                               arr[2].r -= 1;
+                               arr[3].q -= 1;
+                               arr[3].r += 1;
+                               arr[4].r -= 1;
+                               arr[5].r += 1;
+                               return arr;
+               }
+
+
+               // methods for being displayed I guess
+               getCanvasCoords(xorig, yorig, scale, ispoint) {
+                               // x,y is origin place, scale is how much to multiply unit dist by
+                               var xi = 0;
+                               var yi = 0;
+                               // ispoint determines ^ or _ for how they look on top
+                               if(ispoint) {
+                                               xi = scale * (Math.sqrt(3)*this.q+Math.sqrt(3)*this.r/2);
+                                               yi = scale * (this.r*3/2);
+                               }
+                               else {
+                                               xi = scale * (this.q*3/2);
+                                               yi = scale * (Math.sqrt(3)*this.q/2+Math.sqrt(3)*this.r);
+                               }
+                               return {x: xi+xorig, y: yi+yorig}
+               }
+
+}
+
+
+function getClickCoords(c, scale, xoff, yoff, event) {
+               let rect = c.getBoundingClientRect();
+               // origin points modulo page placement
+               let ox = event.clientX - rect.left;
+               let oy = event.clientY - rect.top;
+
+               let dfox = (ox - xoff)/scale;
+               let dfoy = (oy - yoff)/scale;
+
+               // in basis r,q:
+               // [1 0] ->xy [  rt(3)    0  ]
+               // [0 1] ->xy [ rt(3)/2  3/2 ]
+               // [ r3 r3/2 |  1   0 ]
+               // [ 0  3/2  |  0   1 ] //
+               // [ 1 1/2 | 1/r3  0  ]
+               // [ 0  1  |  0   2/3 ]
+               // [ 1 0 | 1/r3 -1/3 ]
+               // [ 0 1 |  0   2/3  ]
+
+               preq = dfox*1/Math.sqrt(3) - dfoy*1/3;
+               prer = dfoy*2/3;
+               r = Math.round(prer);
+               q = Math.round(preq);
+               return {r: r, q: q};
+}
diff --git a/index.html b/index.html
new file mode 100644 (file)
index 0000000..f086894
--- /dev/null
@@ -0,0 +1,28 @@
+<!doctype html>
+<meta charset="utf-8">
+<html>
+  <head>
+    <script src="grid.js"></script>
+               <script src="wireworld.js"></script>
+               <script src="play.js"></script>
+               <script>
+                       function run() {
+                                       lc();
+                                       console.log("hello");
+                       }
+               </script>
+    <title>hww</title>
+  </head>
+  <body onload="run()" style="background-color: #f8f8ff;">
+               <div class="ctrl">
+                       <input type="button" id="step" value="step"/>
+                       <input type="button" id="playpause" value="play"/>
+                       <input type="range" id="tempo" min="20" max="500"/>
+                       <input type="button" id="clear" value="clear"/>
+                       <input type="button" id="reset" value="reset"/>
+                       <input type="button" id="es" value="export state"/>
+                       <input type="button" id="is" value="import state"/>
+               </div>
+    <div><canvas width="2000" height="2000" id="c"></canvas></div>
+  </body>
+</html>
diff --git a/notes.org b/notes.org
new file mode 100644 (file)
index 0000000..2194d5d
--- /dev/null
+++ b/notes.org
@@ -0,0 +1,28 @@
+wireworld demos:
+
+two clocks:
+[{"q":-4,"r":-2,"state":"off"},{"q":-3,"r":-3,"state":"tail"},{"q":-2,"r":-4,"state":"head"},{"q":-1,"r":-4,"state":"off"},{"q":-1,"r":-3,"state":"off"},{"q":-2,"r":-2,"state":"tail"},{"q":-4,"r":-1,"state":"off"},{"q":-3,"r":-1,"state":"head"},{"q":1,"r":-3,"state":"tail"},{"q":3,"r":-4,"state":"off"},{"q":2,"r":-4,"state":"head"},{"q":3,"r":-3,"state":"tail"},{"q":2,"r":-2,"state":"head"},{"q":1,"r":-1,"state":"off"},{"q":0,"r":-1,"state":"off"},{"q":0,"r":-2,"state":"off"}]
+
+longer clocks:
+[{"q":-1,"r":-5,"state":"off"},{"q":0,"r":-5,"state":"off"},{"q":2,"r":-5,"state":"off"},{"q":1,"r":-5,"state":"off"},{"q":3,"r":-5,"state":"off"},{"q":4,"r":-5,"state":"tail"},{"q":4,"r":-4,"state":"head"},{"q":3,"r":-3,"state":"off"},{"q":2,"r":-3,"state":"off"},{"q":1,"r":-3,"state":"tail"},{"q":-1,"r":-3,"state":"off"},{"q":0,"r":-3,"state":"head"},{"q":-2,"r":-3,"state":"off"},{"q":6,"r":-4,"state":"head"},{"q":7,"r":-5,"state":"off"},{"q":8,"r":-5,"state":"off"},{"q":9,"r":-5,"state":"off"},{"q":10,"r":-5,"state":"off"},{"q":11,"r":-5,"state":"off"},{"q":12,"r":-5,"state":"off"},{"q":11,"r":-3,"state":"off"},{"q":10,"r":-3,"state":"off"},{"q":9,"r":-3,"state":"off"},{"q":8,"r":-3,"state":"off"},{"q":7,"r":-3,"state":"off"},{"q":6,"r":-3,"state":"tail"},{"q":-2,"r":-5,"state":"off"},{"q":-3,"r":-4,"state":"off"},{"q":-3,"r":-3,"state":"off"},{"q":13,"r":-5,"state":"tail"},{"q":13,"r":-4,"state":"head"},{"q":12,"r":-3,"state":"off"}]
+
+diodes:
+[{"q":-4,"r":0,"state":"head"},{"q":-3,"r":-1,"state":"tail"},{"q":-2,"r":-1,"state":"off"},{"q":-2,"r":0,"state":"off"},{"q":-3,"r":1,"state":"off"},{"q":-4,"r":1,"state":"off"},{"q":-1,"r":-2,"state":"off"},{"q":0,"r":-3,"state":"off"},{"q":1,"r":-3,"state":"off"},{"q":2,"r":-3,"state":"off"},{"q":-3,"r":2,"state":"off"},{"q":-3,"r":3,"state":"off"},{"q":-2,"r":3,"state":"off"},{"q":-1,"r":3,"state":"off"},{"q":2,"r":-2,"state":"off"},{"q":3,"r":-2,"state":"off"},{"q":4,"r":-2,"state":"off"},{"q":3,"r":-4,"state":"off"},{"q":4,"r":-4,"state":"off"},{"q":5,"r":-4,"state":"off"},{"q":5,"r":-3,"state":"off"},{"q":6,"r":-3,"state":"off"},{"q":7,"r":-3,"state":"off"},{"q":8,"r":-3,"state":"off"},{"q":0,"r":2,"state":"off"},{"q":1,"r":2,"state":"off"},{"q":2,"r":2,"state":"off"},{"q":-1,"r":4,"state":"off"},{"q":0,"r":4,"state":"off"},{"q":1,"r":4,"state":"off"},{"q":2,"r":3,"state":"off"},{"q":4,"r":3,"state":"off"},{"q":5,"r":3,"state":"off"},{"q":3,"r":3,"state":"off"},{"q":0,"r":3,"state":"off"},{"q":4,"r":-3,"state":"off"}]
+
+
+'or' gate: (2 diodes, essentially)
+[{"q":-4,"r":4,"state":"off"},{"q":-3,"r":4,"state":"off"},{"q":-3,"r":3,"state":"off"},{"q":-2,"r":3,"state":"off"},{"q":-4,"r":5,"state":"off"},{"q":-3,"r":5,"state":"off"},{"q":-5,"r":4,"state":"off"},{"q":-1,"r":3,"state":"off"},{"q":-2,"r":5,"state":"off"},{"q":-1,"r":4,"state":"off"},{"q":0,"r":4,"state":"off"},{"q":1,"r":3,"state":"off"},{"q":0,"r":5,"state":"off"},{"q":1,"r":2,"state":"off"},{"q":2,"r":3,"state":"off"},{"q":2,"r":1,"state":"off"},{"q":3,"r":2,"state":"off"},{"q":3,"r":0,"state":"off"},{"q":3,"r":1,"state":"off"},{"q":4,"r":0,"state":"off"},{"q":4,"r":1,"state":"off"},{"q":5,"r":-1,"state":"off"},{"q":6,"r":-2,"state":"off"},{"q":-6,"r":4,"state":"off"},{"q":-7,"r":4,"state":"head"},{"q":7,"r":-3,"state":"head"},{"q":0,"r":7,"state":"off"},{"q":0,"r":6,"state":"off"},{"q":0,"r":9,"state":"off"},{"q":0,"r":8,"state":"off"}]
+
+'xor' gate:
+[{"q":-7,"r":-2,"state":"head"},{"q":-6,"r":-2,"state":"off"},{"q":-5,"r":-2,"state":"off"},{"q":-4,"r":-2,"state":"off"},{"q":-3,"r":-1,"state":"off"},{"q":-2,"r":-2,"state":"off"},{"q":-2,"r":-3,"state":"off"},{"q":0,"r":-2,"state":"off"},{"q":4,"r":-4,"state":"off"},{"q":6,"r":-7,"state":"off"},{"q":7,"r":-6,"state":"off"},{"q":8,"r":-8,"state":"off"},{"q":9,"r":-9,"state":"off"},{"q":10,"r":-10,"state":"off"},{"q":3,"r":-3,"state":"off"},{"q":1,"r":-2,"state":"off"},{"q":2,"r":-2,"state":"off"},{"q":2,"r":-3,"state":"off"},{"q":2,"r":-1,"state":"off"},{"q":2,"r":0,"state":"off"},{"q":11,"r":-11,"state":"tail"},{"q":3,"r":-2,"state":"off"},{"q":1,"r":-1,"state":"off"},{"q":6,"r":-6,"state":"off"},{"q":2,"r":1,"state":"off"},{"q":2,"r":2,"state":"off"},{"q":2,"r":3,"state":"off"},{"q":-3,"r":-2,"state":"off"},{"q":-2,"r":-1,"state":"off"},{"q":-1,"r":-3,"state":"off"},{"q":5,"r":-6,"state":"off"},{"q":6,"r":-5,"state":"off"},{"q":7,"r":-7,"state":"off"},{"q":4,"r":-5,"state":"off"},{"q":5,"r":-4,"state":"off"},{"q":0,"r":-3,"state":"off"},{"q":-1,"r":-1,"state":"off"}]
+
+'not' gate variation:
+[{"q":-5,"r":-1,"state":"off"},{"q":-4,"r":-2,"state":"off"},{"q":-4,"r":-1,"state":"off"},{"q":-5,"r":0,"state":"off"},{"q":-6,"r":-1,"state":"off"},{"q":-7,"r":-1,"state":"head"},{"q":-3,"r":-2,"state":"off"},{"q":-2,"r":-2,"state":"off"},{"q":-4,"r":0,"state":"off"},{"q":-3,"r":0,"state":"off"},{"q":-2,"r":-1,"state":"off"},{"q":0,"r":-1,"state":"off"},{"q":1,"r":-1,"state":"off"},{"q":-1,"r":-1,"state":"off"},{"q":2,"r":-1,"state":"off"},{"q":2,"r":0,"state":"off"},{"q":2,"r":1,"state":"off"},{"q":2,"r":3,"state":"off"},{"q":2,"r":2,"state":"off"},{"q":2,"r":-2,"state":"off"},{"q":1,"r":0,"state":"off"},{"q":3,"r":-2,"state":"off"},{"q":3,"r":-1,"state":"off"},{"q":4,"r":-3,"state":"off"},{"q":5,"r":-4,"state":"off"},{"q":6,"r":-6,"state":"off"},{"q":6,"r":-5,"state":"off"},{"q":7,"r":-7,"state":"off"},{"q":9,"r":-8,"state":"tail"},{"q":8,"r":-8,"state":"off"},{"q":10,"r":-8,"state":"head"},{"q":10,"r":-7,"state":"off"},{"q":10,"r":-6,"state":"off"},{"q":9,"r":-5,"state":"off"},{"q":8,"r":-4,"state":"off"},{"q":7,"r":-4,"state":"off"},{"q":6,"r":-4,"state":"off"}]
+
+nand: (a xor b) or (not b)
+wholly unoptimized, broken timing
+[{"q":-3,"r":1,"state":"off"},{"q":-2,"r":1,"state":"off"},{"q":10,"r":-6,"state":"off"},{"q":9,"r":-5,"state":"off"},{"q":8,"r":-4,"state":"off"},{"q":7,"r":-3,"state":"off"},{"q":5,"r":-2,"state":"off"},{"q":6,"r":-2,"state":"off"},{"q":6,"r":-3,"state":"off"},{"q":7,"r":-2,"state":"off"},{"q":6,"r":-1,"state":"off"},{"q":5,"r":0,"state":"off"},{"q":4,"r":-1,"state":"off"},{"q":4,"r":0,"state":"off"},{"q":3,"r":1,"state":"off"},{"q":2,"r":2,"state":"off"},{"q":1,"r":2,"state":"off"},{"q":0,"r":2,"state":"off"},{"q":-1,"r":2,"state":"off"},{"q":9,"r":-2,"state":"off"},{"q":10,"r":-2,"state":"off"},{"q":9,"r":-1,"state":"off"},{"q":9,"r":0,"state":"off"},{"q":11,"r":-1,"state":"off"},{"q":10,"r":-5,"state":"off"},{"q":10,"r":-4,"state":"off"},{"q":10,"r":-3,"state":"off"},{"q":11,"r":-3,"state":"off"},{"q":11,"r":-2,"state":"off"},{"q":10,"r":0,"state":"off"},{"q":10,"r":1,"state":"off"},{"q":11,"r":-7,"state":"head"},{"q":10,"r":2,"state":"off"},{"q":9,"r":2,"state":"off"},{"q":10,"r":3,"state":"off"},{"q":9,"r":3,"state":"off"},{"q":8,"r":4,"state":"off"},{"q":11,"r":2,"state":"off"},{"q":12,"r":2,"state":"off"},{"q":13,"r":1,"state":"off"},{"q":14,"r":0,"state":"off"},{"q":15,"r":-1,"state":"off"},{"q":15,"r":-2,"state":"off"},{"q":15,"r":-3,"state":"off"},{"q":15,"r":-4,"state":"off"},{"q":15,"r":-5,"state":"off"},{"q":15,"r":-6,"state":"head"},{"q":16,"r":-1,"state":"off"},{"q":17,"r":-1,"state":"off"},{"q":18,"r":-2,"state":"off"},{"q":18,"r":-3,"state":"off"},{"q":18,"r":-5,"state":"off"},{"q":18,"r":-4,"state":"off"},{"q":18,"r":-6,"state":"off"},{"q":18,"r":-7,"state":"off"},{"q":17,"r":-8,"state":"off"},{"q":18,"r":-8,"state":"off"},{"q":15,"r":-7,"state":"tail"},{"q":16,"r":-8,"state":"off"},{"q":-1,"r":1,"state":"off"},{"q":-2,"r":3,"state":"off"},{"q":-3,"r":3,"state":"off"},{"q":-3,"r":2,"state":"off"},{"q":-4,"r":3,"state":"off"},{"q":-4,"r":2,"state":"off"},{"q":-5,"r":2,"state":"off"},{"q":-6,"r":2,"state":"off"},{"q":1,"r":3,"state":"off"},{"q":3,"r":2,"state":"off"},{"q":2,"r":3,"state":"off"},{"q":2,"r":4,"state":"off"},{"q":2,"r":5,"state":"off"},{"q":7,"r":5,"state":"off"},{"q":3,"r":6,"state":"off"},{"q":5,"r":6,"state":"off"},{"q":6,"r":7,"state":"off"},{"q":7,"r":4,"state":"off"},{"q":8,"r":5,"state":"off"},{"q":6,"r":5,"state":"off"},{"q":7,"r":6,"state":"off"},{"q":5,"r":7,"state":"off"},{"q":4,"r":8,"state":"off"},{"q":1,"r":5,"state":"off"},{"q":3,"r":4,"state":"off"},{"q":3,"r":5,"state":"off"},{"q":1,"r":6,"state":"off"},{"q":1,"r":7,"state":"off"},{"q":2,"r":7,"state":"off"},{"q":2,"r":8,"state":"off"},{"q":2,"r":9,"state":"off"},{"q":3,"r":9,"state":"off"},{"q":2,"r":10,"state":"off"},{"q":2,"r":11,"state":"off"},{"q":2,"r":12,"state":"off"},{"q":3,"r":13,"state":"off"},{"q":2,"r":13,"state":"off"},{"q":4,"r":13,"state":"off"},{"q":4,"r":14,"state":"off"},{"q":-7,"r":2,"state":"head"}]
+
+
+broken 'nand' attempt:
+[{"q":-3,"r":-2,"state":"off"},{"q":-2,"r":-2,"state":"off"},{"q":-1,"r":-3,"state":"off"},{"q":0,"r":-3,"state":"off"},{"q":-2,"r":-1,"state":"off"},{"q":-1,"r":-1,"state":"off"},{"q":1,"r":-2,"state":"off"},{"q":2,"r":-2,"state":"off"},{"q":3,"r":-2,"state":"off"},{"q":4,"r":-2,"state":"off"},{"q":4,"r":-1,"state":"off"},{"q":5,"r":-3,"state":"off"},{"q":6,"r":-4,"state":"off"},{"q":8,"r":-7,"state":"off"},{"q":9,"r":-6,"state":"off"},{"q":10,"r":-8,"state":"off"},{"q":11,"r":-9,"state":"off"},{"q":3,"r":-1,"state":"off"},{"q":5,"r":-2,"state":"off"},{"q":0,"r":-2,"state":"off"},{"q":-2,"r":-3,"state":"off"},{"q":-3,"r":-1,"state":"off"},{"q":-4,"r":-2,"state":"head"},{"q":8,"r":-6,"state":"off"},{"q":11,"r":-8,"state":"off"},{"q":12,"r":-10,"state":"tail"},{"q":7,"r":-4,"state":"off"},{"q":4,"r":0,"state":"off"},{"q":3,"r":1,"state":"off"},{"q":5,"r":0,"state":"off"},{"q":4,"r":1,"state":"off"},{"q":3,"r":2,"state":"off"},{"q":5,"r":1,"state":"off"},{"q":5,"r":2,"state":"off"},{"q":3,"r":3,"state":"off"},{"q":4,"r":3,"state":"off"},{"q":4,"r":4,"state":"off"},{"q":8,"r":2,"state":"off"},{"q":4,"r":6,"state":"off"},{"q":5,"r":6,"state":"off"},{"q":7,"r":4,"state":"off"},{"q":6,"r":5,"state":"off"},{"q":6,"r":6,"state":"off"},{"q":4,"r":7,"state":"off"},{"q":5,"r":7,"state":"off"},{"q":5,"r":8,"state":"off"},{"q":5,"r":9,"state":"off"},{"q":4,"r":10,"state":"off"},{"q":3,"r":11,"state":"off"},{"q":2,"r":11,"state":"off"},{"q":1,"r":11,"state":"off"},{"q":5,"r":10,"state":"off"},{"q":6,"r":8,"state":"off"},{"q":6,"r":9,"state":"off"},{"q":7,"r":9,"state":"off"},{"q":7,"r":10,"state":"off"},{"q":1,"r":10,"state":"off"},{"q":0,"r":10,"state":"off"},{"q":0,"r":12,"state":"off"},{"q":-1,"r":12,"state":"off"},{"q":-2,"r":12,"state":"off"},{"q":-1,"r":11,"state":"off"},{"q":-1,"r":10,"state":"off"},{"q":-2,"r":11,"state":"off"},{"q":-3,"r":11,"state":"off"},{"q":-4,"r":11,"state":"off"},{"q":-5,"r":11,"state":"off"},{"q":-6,"r":11,"state":"off"},{"q":-7,"r":11,"state":"off"},{"q":-4,"r":5,"state":"head"},{"q":-4,"r":6,"state":"off"},{"q":-4,"r":4,"state":"tail"},{"q":-5,"r":6,"state":"off"},{"q":-6,"r":7,"state":"off"},{"q":-3,"r":6,"state":"off"},{"q":-2,"r":6,"state":"off"},{"q":-1,"r":5,"state":"off"},{"q":0,"r":4,"state":"off"},{"q":0,"r":3,"state":"off"},{"q":0,"r":2,"state":"off"},{"q":-1,"r":2,"state":"off"},{"q":-2,"r":2,"state":"off"},{"q":-3,"r":3,"state":"off"},{"q":-8,"r":11,"state":"off"},{"q":-9,"r":11,"state":"off"},{"q":-9,"r":10,"state":"off"},{"q":-7,"r":7,"state":"off"},{"q":-8,"r":7,"state":"off"},{"q":-9,"r":8,"state":"off"},{"q":-9,"r":9,"state":"off"},{"q":6,"r":-5,"state":"off"},{"q":8,"r":-5,"state":"off"},{"q":7,"r":-6,"state":"off"},{"q":9,"r":-7,"state":"off"},{"q":11,"r":-7,"state":"off"},{"q":7,"r":3,"state":"off"},{"q":8,"r":4,"state":"off"},{"q":9,"r":3,"state":"off"},{"q":9,"r":2,"state":"off"},{"q":10,"r":2,"state":"off"},{"q":9,"r":1,"state":"off"},{"q":10,"r":1,"state":"off"},{"q":11,"r":0,"state":"off"},{"q":11,"r":-1,"state":"off"},{"q":11,"r":-2,"state":"off"},{"q":12,"r":-3,"state":"off"},{"q":13,"r":-4,"state":"off"},{"q":13,"r":-5,"state":"off"},{"q":12,"r":-7,"state":"off"},{"q":13,"r":-7,"state":"off"},{"q":4,"r":5,"state":"off"},{"q":13,"r":-6,"state":"off"}]
diff --git a/play.js b/play.js
new file mode 100644 (file)
index 0000000..1f3f43d
--- /dev/null
+++ b/play.js
@@ -0,0 +1,95 @@
+
+
+
+g = new WWGrid();
+
+//params
+xcenter = 200
+ycenter = 200
+scale = 10
+
+g.change(WWState.OFF, 0,0);
+g.change(WWState.OFF, 0,1);
+g.change(WWState.OFF, 1,1);
+g.change(WWState.HEAD, -1,0);
+g.change(WWState.OFF, 1,-1);
+
+/*
+for(var i=-5; i<5; i++) {
+               for(var j=-5; j<5; j++) {
+                               g.change(WWState.EMPTY, i, j);
+               }
+}*/
+
+g.change(WWState.EMPTY, 0,0);
+g.change(WWState.HEAD, 1,0);
+g.change(WWState.HEAD, 2,0);
+g.change(WWState.TAIL, 0,1);
+g.change(WWState.TAIL, 0,2);
+
+var ctx = null;
+var c = null;
+
+var timeout = 200;
+var rstgrid = g;
+var intervalID = null;
+
+function play() {
+               g.step();
+               drawGrid(g, ctx, xcenter,ycenter,scale);
+}
+
+function lc() {
+               c = document.getElementById('c');
+               ctx = c.getContext('2d');
+               //c.addEventListener('click', e=>getClickCoords(c, 20, 200, 200, e));
+               c.addEventListener('click', e=>wwonclick(c,ctx,g,xcenter,ycenter,scale,e));
+               drawGrid(g, ctx, xcenter,ycenter,scale);
+               document.addEventListener('keydown', e=>{
+                               console.log(e.key);
+                               if(e.key == "p") pptoggle(e);
+                               if(e.key == "s") {g.step();drawGrid(g,ctx,xcenter,ycenter,scale);}
+                               if(e.key == "r") {g=rstgrid.clone(); drawGrid(g, ctx, xcenter,ycenter,scale)}
+               });
+               step = document.getElementById('step');
+               step.addEventListener('click', function(e){g.step();drawGrid(g,ctx,xcenter,ycenter,scale);})
+               playbtn = document.getElementById('playpause');
+               playbtn.addEventListener('click',pptoggle);
+               range = document.getElementById("tempo");
+               range.addEventListener('click', function(e) {timeout=range.value});
+               clr = document.getElementById("clear");
+               clr.onclick = () => {g.cells = [];
+                                                                                                                drawGrid(g, ctx, xcenter,ycenter,scale)};
+               rst = document.getElementById("reset");
+               rst.onclick = () => {g=rstgrid.clone(); drawGrid(g, ctx, xcenter,ycenter,scale)};
+               es = document.getElementById("es");
+               es.onclick = exportState;
+               is = document.getElementById("is");
+               is.onclick = importState;
+}
+
+pptoggle = function(e) {
+               if(intervalID == null) {
+                               g.clean();
+                               rstgrid = g.clone();
+                               intervalID = setInterval(play, timeout);
+                               playbtn.value = "pause"
+               }
+               else {
+                               clearInterval(intervalID);
+                               intervalID = null;
+                               playbtn.value = "play"
+               }
+};
+
+exportState = function() {
+               let s = g.exportState();
+               alert(s);
+               
+}
+importState = function() {
+               console.log("hi");
+               let s = prompt("paste state string below");
+               g.loadState(s);
+               drawGrid(g, ctx, xcenter,ycenter,scale);                
+}
diff --git a/wireworld.js b/wireworld.js
new file mode 100644 (file)
index 0000000..167bee4
--- /dev/null
@@ -0,0 +1,177 @@
+
+
+// wireworld implementation for hex grids with grid js
+
+
+
+
+const WWState = {
+               EMPTY: 'empty',
+               OFF: 'off',
+               HEAD: 'head',
+               TAIL: 'tail'
+};
+Object.freeze(WWState);
+
+class WWCell extends Hex {
+               constructor(state,q,r,s) {
+                               super(q,r,s);
+                               this.state = state;
+               }
+               clone() {
+                               return new WWCell(this.state, this.q, this.r, this.s);
+               }
+               static fromJSON(o) {
+                               return new WWCell(o.state, o.q, o.r);
+               }
+}
+
+
+
+class WWGrid {
+               constructor() {
+                               this.cells = [];
+               }
+               clean() {
+                               this.cells = this.cells.filter(x=>x.state!=WWState.EMPTY);
+               }
+               clone() {
+                               let ng = new WWGrid();
+                               for(let i of this.cells) {
+                                               ng.cells.push(i.clone())
+                               }
+                               return ng;
+               }
+               exportState() {
+                               this.clean();
+                               //console.log(JSON.stringify(this.cells));
+                               return JSON.stringify(this.cells);
+               }
+               loadState(str) {
+                               let obj = JSON.parse(str);
+                               if(!Array.isArray(obj)) return;
+                               this.cells = [];
+                               for(let i of obj) {
+                                               this.cells.push(WWCell.fromJSON(i));
+                               }
+               }
+
+               change(state,q,r) {
+                               let cells = this.cells.filter(c => c.q==q && c.r==r);
+                               if(cells.length == 0) {
+                                               this.cells.push(new WWCell(state,q,r));
+                               }
+                               else {
+                                               cells[0].state = state;
+                               }
+               }
+               
+               stateAt(q,r) {
+                               let cells = this.cells.filter(c => c.q==q && c.r==r);
+                               if(cells.length == 0) return WWState.EMPTY;
+                               return cells[0].state;
+               }
+               
+               step() {
+                               let cellcp = this.cells.map(c => c.clone());
+                               // will be in the same order
+                               for(var i=0; i<cellcp.length; i++) {
+                                               switch(cellcp[i].state) {
+                                               case WWState.HEAD:
+                                                               this.cells[i].state = WWState.TAIL;
+                                                               break;
+                                               case WWState.TAIL:
+                                                               this.cells[i].state = WWState.OFF;
+                                                               break;
+                                               case WWState.OFF:
+                                                               function stateAtClone(cl,q,r) {
+                                                                               let cells = cl.filter(c => c.q==q && c.r==r);
+                                                                               if(cells.length == 0) return WWState.OFF;
+                                                                               return cells[0].state;
+                                                               }
+                                                               let nbrs = cellcp[i].neighbors();
+                                                               var heads = 0;
+                                                               for(var j=0; j<6; j++) {
+                                                                               var st8 = stateAtClone(cellcp,nbrs[j].q, nbrs[j].r);
+                                                                               if(st8==WWState.HEAD) heads++;
+                                                               }
+                                                               if(heads > 0 && heads < 3) {
+                                                                               this.cells[i].state = WWState.HEAD;
+                                                               }
+                                                               break;
+                                               case WWState.EMPTY:
+                                               default:
+                                                               break;
+                                               }
+                               }
+                               // this is it, yeah? yeah I think that's enough
+                               // probably a more efficient way of doing this,
+                               // but fine for now
+
+                               // sooo.. hashlife:
+                               // I think that this may prove to be a reasonable
+                               // setup for an eventual implementation
+                               // that said js is probs the worst language for that
+               }
+
+
+
+}
+
+
+function drawState(ctx,st,x,y,sz) {
+               ctx.save();
+               switch(st) {
+               case WWState.OFF:
+                               ctx.fillStyle = 'rgb(0,0,0)';
+                               break;
+               case WWState.EMPTY:
+                               ctx.fillStyle = 'rgb(255,255,255)';
+                               ctx.restore();
+                               return;
+                               break;
+               case WWState.TAIL:
+                               ctx.fillStyle = 'rgb(0,0,255)';
+                               break;
+               case WWState.HEAD:
+               default:
+                               ctx.fillStyle = 'rgb(255,0,0)';
+                               break;
+               }
+               ctx.beginPath();
+               r = sz * Math.sqrt(3)/2 * 0.9;
+               ctx.arc(x,y,r,0,Math.PI*2,true);
+               ctx.stroke();
+               ctx.fill();
+               ctx.restore();
+}
+
+function drawGrid(grid, ctx, cx, cy, scale) {
+               ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height);
+               for(var i of grid.cells) {
+                               coords = i.getCanvasCoords(cx, cy, scale, true);
+                               drawState(ctx, i.state, coords.x, coords.y, scale);
+               }
+}
+
+function nextkey(k) {
+               switch(k) {
+               case WWState.EMPTY:
+                               return WWState.OFF;
+               case WWState.OFF:
+                               return WWState.HEAD;
+               case WWState.HEAD:
+                               return WWState.TAIL;
+               default: //tail
+                               return WWState.EMPTY;
+               }
+}
+
+function wwonclick(c, ctx, grid, cx, cy, scale, event) {
+               let rqcoord = getClickCoords(c, scale, cx, cy, event);
+               let currst8 = grid.stateAt(rqcoord.q, rqcoord.r);
+               let nextst8 = nextkey(currst8);
+               grid.change(nextst8, rqcoord.q, rqcoord.r);
+               drawGrid(grid, ctx, cx, cy, scale);
+
+}