summaryrefslogtreecommitdiff
path: root/src/world/agent.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/world/agent.js')
-rw-r--r--src/world/agent.js55
1 files changed, 55 insertions, 0 deletions
diff --git a/src/world/agent.js b/src/world/agent.js
new file mode 100644
index 0000000..d91481b
--- /dev/null
+++ b/src/world/agent.js
@@ -0,0 +1,55 @@
+'use strict';
+
+import { sense_read } from './sense.js';
+import { proposal_merge } from './proposal.js';
+
+
+export function agent_decide(lattice, agent, senses, actions) {
+ const inputs = senses.map(s => sense_read(lattice, agent, s)).flat();
+ const [result, state] = agent.net.compute(inputs, agent.state);
+
+ const new_agent = { ...agent, state };
+ const [proposals, _] = actions.reduce(
+ ([proposals, result], action) => {
+ const head = result.slice(0, action.size);
+ const tail = result.slice(action.size);
+
+ const props = action
+ .propose(new_agent, head)
+ .reduce(
+ (acc, proposal) => proposal_merge(acc, proposal),
+ proposals
+ );
+
+ return [props, tail];
+ },
+ [[], result]
+ );
+
+ return [new_agent, proposals];
+}
+
+
+function change_apply(agent, ch) {
+ const { x, y, flags } = ch;
+ return {
+ ...agent,
+ x: (x || agent.x), y: (y || agent.y),
+ flags: { ...agent.flags, ...flags },
+ };
+}
+
+
+export function agent_apply(agent, proposals) {
+ return proposals
+ .filter(p => p.agent_changes)
+ .reduce(
+ (acc, p) => p.agent_changes
+ .filter(ch => ch.agent_id === agent.id)
+ .reduce(
+ (acc_, ch) => change_apply(acc_, ch),
+ acc
+ ),
+ agent
+ );
+}