var CELLS = Symbol() var key = function key(x,y) { return `${x},${y}` } function grid(w, h) { this[CELLS] = new Map() this.width = w; this.height = h; } grid.prototype = { cell(x,y) { var k = key(x,y) if (!this[CELLS].has(k)) this[CELLS].set(k,[]) return this[CELLS].get(k) }, add(entity, pos) { this.cell(pos.x, pos.y).push(entity); entity.coord = pos.slice(); }, remove(entity, pos) { var c = this.cell(pos.x, pos.y); c.splice(c.indexOf(entity), 1); }, at(pos) { return this.cell(pos.x, pos.y); }, inBounds(pos) { return pos.x >= 0 && pos.x < this.width && pos.y >= 0 && pos.y < this.height; }, each(fn) { for (var [k, list] of this[CELLS]) for (var p of list) fn(p, p.coord); }, toString() { var out = `grid [${this.width}x${this.height}] ` for (var y = 0; y < this.height; y++) { for (var x = 0; x < this.width; x++) { var cell = this.at([x,y]); out += cell.length } if (y !== this.height - 1) out += "\n" } return out }, } return grid