diff options
-rw-r--r-- | src/simulation/validity.js | 14 | ||||
-rw-r--r-- | src/simulation/validity.test.js | 43 | ||||
-rw-r--r-- | src/world/world.js | 18 |
3 files changed, 66 insertions, 9 deletions
diff --git a/src/simulation/validity.js b/src/simulation/validity.js new file mode 100644 index 0000000..de4acd1 --- /dev/null +++ b/src/simulation/validity.js @@ -0,0 +1,14 @@ +export const validity = [ + // prevent agents from moving onto immutables + (world, proposal) => (proposal.agent_changes || []).reduce( + (acc, change) => { + const {x, y} = change; + if (x !== undefined && y !== undefined && world.lattice[y][x].type === 'immutable') { + return false; + } else { + return acc; + } + }, + true, + ), +]; diff --git a/src/simulation/validity.test.js b/src/simulation/validity.test.js new file mode 100644 index 0000000..ba9e684 --- /dev/null +++ b/src/simulation/validity.test.js @@ -0,0 +1,43 @@ +'use strict'; + +import { world_update } from '../world/world.js'; +import { validity } from './validity.js'; + +test("agents are not allowed to move into immutables", () => { + const actions = [{ + size: 1, propose: (world, agent, head) => { + return [{ + agent_changes: [{ + agent_id: agent.id, + x: agent.x + 1, y: agent.y, + }], + }]; + }, + }]; + + const agent = { + id: 1, + net: { compute: () => [[1], null] }, + state: null, + x: 0, y: 0, + flags: {}, + }; + + const lattice = [[{ type: 'empty', flags: {} }, { type: 'immutable', flags: {} }]]; + + const world = { + lattice, + lattice_rules: { empty: ()=>{}, immutable: ()=>{} }, + agents: [agent], + senses: [], + actions, + validity, + }; + + expect(world_update(world).agents[0]).toEqual(agent); + world.validity = []; + expect(world_update(world).agents[0]).toEqual({ + ...agent, + x: 1, y: 0, + }); +}); diff --git a/src/world/world.js b/src/world/world.js index e1ba0cf..4bab4d3 100644 --- a/src/world/world.js +++ b/src/world/world.js @@ -19,21 +19,21 @@ export function world_update(world, postprocess=[]) { const intermediate_lattice = lattice_apply(world.lattice, lattice_props); const decisions = world.agents - .map(a => agent_decide(world, agent, world.senses, world.actions)) + .map(a => agent_decide(world, a, world.senses, world.actions)) .reduce( ([agents, props], [agent, prop]) => [[...agents, agent], [...props, prop]], [[], []] ); const intermediate_agents = decisions[0]; - const agent_props = decisions[1] - .flat() - .reduce((acc, prop) => proposal_merge(acc, prop), []) - .filter(prop => lattice_valid(intermediate_lattice, prop)) + const agent_props = world.validity.reduce( + (acc, rule) => acc.filter(prop => rule({...world, lattice: intermediate_lattice}, prop)), + decisions[1] + .flat() + .reduce((acc, prop) => proposal_merge(acc, prop), []) + .filter(prop => lattice_valid(intermediate_lattice, prop)) + ); - const lattice = lattice_apply(intermediate_lattice, world.validity.reduce( - (acc, rule) => acc.filter(rule), - agent_props - )); + const lattice = lattice_apply(intermediate_lattice, agent_props); const agents = intermediate_agents.map(a => agent_apply(a, agent_props)); const new_world = {...world, lattice, agents}; |