diff options
author | sanine <sanine.not@pm.me> | 2023-11-10 15:43:49 -0600 |
---|---|---|
committer | sanine <sanine.not@pm.me> | 2023-11-10 15:43:49 -0600 |
commit | 27c786d440b66a0e2e7a168a15396185392a755b (patch) | |
tree | dd43ee99898471c59c5d56f1fa0b4cf56c5555e5 /src/simulation/senses.js | |
parent | e3716be01e57e5a4eec591d606917c1bf1066b05 (diff) |
add non-passing vision test
Diffstat (limited to 'src/simulation/senses.js')
-rw-r--r-- | src/simulation/senses.js | 125 |
1 files changed, 124 insertions, 1 deletions
diff --git a/src/simulation/senses.js b/src/simulation/senses.js index 0a882c9..87115db 100644 --- a/src/simulation/senses.js +++ b/src/simulation/senses.js @@ -46,6 +46,129 @@ const hear = { }; +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); + console.log('vision pos', vx, vy); + 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); + return vision_pos_to_world_pos(world, agent, vx, vy); +} + +function see_cell(world, x, y) { + const team = 0; + const orientation = 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 type = (() => { + if (agent.flags.frozen && agent.flags.flag) { + return -0.4; + } else if (agent.flags.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: VIS_WIDTH * VIS_HEIGHT, + read: (world, agent) => { + const vision = [...Array(VIS_WIDTH*VIS_HEIGHT).keys()] + .map(idx => { + const [x, y] = vision_idx_to_world_pos(world, agent, idx); + console.log(x, y, idx); + return see_cell(world, x, y); + }); + return 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 { + return acc.toSpliced(idx, 1, see_agent(agent, a)); + } + }, + vision + ); + }, +}; + + + export const senses = [ - frozen, hear, + frozen, hear, see, ]; |