summaryrefslogtreecommitdiff
path: root/src/world/world.js
blob: 4bab4d312ed2fc8a3593b8a4c67a9b2bddc37f40 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import { lattice_update, lattice_valid, lattice_apply } from './lattice.js';
import { agent_decide, agent_apply } from './agent.js';
import { proposal_merge } from './proposal.js';


// world structure:
// {
//   lattice
//   lattice_rules: object
//   agents: agent[]
//   senses: sense[]
//   actions: action[]
//   validity: (function(proposal) => bool)[]
// }


export function world_update(world, postprocess=[]) {
  const lattice_props = lattice_update(world.lattice, world.lattice_rules);
  const intermediate_lattice = lattice_apply(world.lattice, lattice_props);

  const decisions = world.agents
    .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 = 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, agent_props);
  const agents = intermediate_agents.map(a => agent_apply(a, agent_props));

  const new_world = {...world, lattice, agents};
  return postprocess.reduce(
    (acc, f) => f(acc),
    new_world
  );
}