diff options
Diffstat (limited to 'src/world/agent.js')
-rw-r--r-- | src/world/agent.js | 44 |
1 files changed, 40 insertions, 4 deletions
diff --git a/src/world/agent.js b/src/world/agent.js index 7ab501c..f7e5a63 100644 --- a/src/world/agent.js +++ b/src/world/agent.js @@ -1,4 +1,4 @@ -import { pairs } from '../util.js'; +import { pairs, deepEqual } from '../util.js'; /* agent structure: * { @@ -33,6 +33,7 @@ import { pairs } from '../util.js'; * x, y: number * from: string * to: string + * flags: object? * } */ @@ -45,6 +46,10 @@ import { pairs } from '../util.js'; */ +// return a tuple [conflict, merge] +// conflict is true if the two world_changes are incompatible +// merge is true if the two world changes are identical +// otherwise they are false function world_change_conflict(a, b) { if (a.x != b.x) { return [false, false]; } if (a.y != b.y) { return [false, false]; } @@ -54,15 +59,46 @@ function world_change_conflict(a, b) { } +function agent_change_conflict(a, b) { + if (deepEqual(a, b)) { + // identical: merge + return [false, true]; + } else if ( + (a.agent_id === b.agent_id) && + ((a.x != b.x) || (a.y != b.y)) + ) { + // same agent, different tiles: conflict + return [true, false]; + } else if ( + (a.agent_id != b.agent_id) && + (a.x === b.x) && + (a.y === b.y) + ) { + // different agents, same tile: conflict + return [true, false]; + } else { + // no conflict c: + return [false, false]; + } +} + + function proposal_conflict_merge(a, b) { - const [world_conflict, world_merge] = pairs(a.world_changes, b.world_changes).reduce( + const [world_conflict, world_merge] = pairs(a.world_changes || [], b.world_changes || []).reduce( (acc, [a, b]) => { const [conflict, merge] = world_change_conflict(a, b); return [acc[0] || conflict, acc[1] || merge]; }, [false, false] - ) - return [world_conflict, world_merge]; + ); + const [agent_conflict, agent_merge] = pairs(a.agent_changes || [], b.agent_changes || []).reduce( + (acc, [a, b]) => { + const [conflict, merge] = agent_change_conflict(a, b); + return [acc[0] || conflict, acc[1] || merge]; + }, + [false, false] + ); + return [world_conflict || agent_conflict, world_merge || agent_merge]; } |