From 18febf79da600dc772b24a6e04f4250e70d4a6ff Mon Sep 17 00:00:00 2001 From: Elijah Cohen Date: Wed, 30 Mar 2022 01:31:41 -0500 Subject: [PATCH 1/1] need to upload lol --- grid.js | 83 ++++++++++++++++++++++++ index.html | 28 ++++++++ notes.org | 28 ++++++++ play.js | 95 +++++++++++++++++++++++++++ wireworld.js | 177 +++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 411 insertions(+) create mode 100644 grid.js create mode 100644 index.html create mode 100644 notes.org create mode 100644 play.js create mode 100644 wireworld.js diff --git a/grid.js b/grid.js new file mode 100644 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 index 0000000..f086894 --- /dev/null +++ b/index.html @@ -0,0 +1,28 @@ + + + + + + + + + hww + + +
+ + + + + + + +
+
+ + diff --git a/notes.org b/notes.org new file mode 100644 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 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 index 0000000..167bee4 --- /dev/null +++ b/wireworld.js @@ -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 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); + +} -- 2.39.2