diff options
Diffstat (limited to 'src/simulation/senses.js')
-rw-r--r-- | src/simulation/senses.js | 182 |
1 files changed, 0 insertions, 182 deletions
diff --git a/src/simulation/senses.js b/src/simulation/senses.js deleted file mode 100644 index 970f86b..0000000 --- a/src/simulation/senses.js +++ /dev/null @@ -1,182 +0,0 @@ -'use strict'; - - -const frozen = { - size: 1, - read: (world, agent) => { - if (agent.flags.frozen === true) { - return [ 1 ]; - } else { - return [ 0 ]; - } - }, -}; - - -// add two arrays together element-wise with a scaling factor -function array_scalesum(a, s, b) { - return a.map((x, i) => x + (s*b[i])); -} -// determine the square of the distance between two cells -function lattice_dist2(x0, y0, x1, y1) { - if (x0 === x1 && y0 === y1) { return 1; } // not proper distance but avoids divide-by-zero errors c: - return ((x0-x1)**2) + ((y0-y1)**2); -} -const hear = { - size: 8, - read: (world, agent) => { - const {x, y} = agent; - const lattice_sounds = world.lattice - .map((row, cy) => row.map((cell, cx) => [ 1/lattice_dist2(x, y, cx, cy), cell ])) - .flat() - .filter(([scale, cell]) => cell.flags.emit !== undefined) - .reduce( - (acc, [scale, cell]) => array_scalesum(acc, scale, cell.flags.emit), - [0, 0, 0, 0, 0, 0, 0, 0] - ); - const agent_sounds = world.agents - .filter(a => a.flags.emit !== undefined) - .reduce( - (acc, a) => array_scalesum(acc, 1/lattice_dist2(x, y, a.x, a.y), a.flags.emit), - [0, 0, 0, 0, 0, 0, 0, 0] - ); - - return array_scalesum(lattice_sounds, 1, agent_sounds).map(ch => Math.tanh(ch)); - }, -}; - - -const [VIS_WIDTH, VIS_HEIGHT] = [31, 31]; -const [VIS_HWIDTH, VIS_HHEIGHT] = [Math.floor(VIS_WIDTH/2), Math.floor(VIS_HEIGHT/2)]; -function identity_mod(n, p) { - const mod = (n % (2*p)) - p + 1; - return mod/p; -} - -function world_pos_to_vision_pos(world, agent, x, y) { - const dx = x - agent.x; - const dy = y - agent.y; - const orientation = agent.flags.orientation || 'n'; - switch (orientation) { - case 'n': - return [VIS_HWIDTH+dx, VIS_HEIGHT+dy-1]; - case 's': - return [VIS_HWIDTH-dx, VIS_HEIGHT-dy-1]; - case 'e': - return [VIS_HWIDTH+dy, VIS_HEIGHT-dx-1]; - case 'w': - return [VIS_HWIDTH-dy, VIS_HEIGHT+dx-1]; - } -} - -function vision_pos_to_world_pos(world, agent, x, y) { - const dx = x-VIS_HWIDTH; - const dy = y-VIS_HEIGHT+1; - const orientation = agent.flags.orientation || 'n'; - switch (orientation) { - case 'n': - return [agent.x + dx, agent.y + dy]; - case 's': - return [agent.x - dx, agent.y - dy]; - case 'e': - return [agent.x - dy, agent.y - dx]; - case 'w': - return [agent.x + dy, agent.y + dx]; - } -} - -function world_pos_to_vision_idx(world, agent, x, y) { - const [vx, vy] = world_pos_to_vision_pos(world, agent, x, y); - return (VIS_WIDTH * vy) + vx; -} -function vision_idx_to_world_pos(world, agent, idx) { - const vx = idx % VIS_WIDTH; - const vy = Math.floor(idx / VIS_WIDTH); - const result = vision_pos_to_world_pos(world, agent, vx, vy); - return result; -} - -function see_cell(world, x, y) { - const team = 0; - const orientation = 0; - if (!world.lattice[y] || !world.lattice[y][x]) { - // beyond the map edge - return [ 0, 0, 0 ]; - } - const type = { - active: -0.8, - mutable: -0.4, - empty: 0.0, - immutable: 0.4, - flag: 0.8, - }[world.lattice[y][x].type]; - return [team, orientation, type]; -} - - -function relative_orientation(viewer, agent) { - switch(viewer.flags.orientation) { - case 'n': return { n: -0.8, e: -0.4, s: 0.4, w: 0.8 }[agent.flags.orientation]; - case 'e': return { e: -0.8, s: -0.4, w: 0.4, n: 0.8 }[agent.flags.orientation]; - case 's': return { s: -0.8, w: -0.4, n: 0.4, e: 0.8 }[agent.flags.orientation]; - case 'w': return { w: -0.8, n: -0.4, e: 0.4, s: 0.8 }[agent.flags.orientation]; - } -} - - -function see_agent(viewer, agent) { - const team = { - 0: -0.8, - 1: -0.4, - 2: 0.4, - 3: 0.8, - }[agent.flags.team] + (identity_mod(agent.id, 11)/16); - const orientation = relative_orientation(viewer, agent) + (identity_mod(agent.id, 37)/16); - const frozen = agent.flags.frozen || agent.flags.pretend_frozen; - const type = (() => { - if (frozen && agent.flags.flag) { - return -0.4; - } else if (frozen) { - return -0.8; - } else if (agent.flags.flag) { - return 0.8; - } else { - return 0.0; - } - })() + (identity_mod(agent.id, 499)/16); - - return [team, orientation, type]; -} - - -const see = { - size: 3*VIS_WIDTH * VIS_HEIGHT, - read: (world, agent) => { - const indices = [...Array(VIS_WIDTH*VIS_HEIGHT).keys()] - const vision = indices - .map(idx => { - const [x, y] = vision_idx_to_world_pos(world, agent, idx); - return see_cell(world, x, y); - }); - const result = world.agents.reduce( - (acc, a) => { - const idx = world_pos_to_vision_idx(world, agent, a.x, a.y); - - if (idx < 0 || idx >= VIS_WIDTH*VIS_HEIGHT) { - return acc; - } else { - acc.splice(idx, 1, see_agent(agent, a)); - return acc; - } - }, - vision - ); - return result.flat(); - }, -}; - - - -export const senses = [ - frozen, hear, see, { size: 1, read: () => [1] }, -]; |