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
45
46
47
48
49
50
51
52
|
'use strict';
// get the proposals for cell updates
export function lattice_update(lattice, update_rules) {
return lattice
.map((row, y) => row.map((cell, x) => [x, y, cell.type]))
.flat()
.reduce((acc, [x, y, type]) => [...acc, update_rules[type](lattice, x, y)], [])
.filter(x => x !== undefined)
}
// check if, given the current lattice configuration, a proposal is valid
export function lattice_valid(lattice, proposal) {
if (!proposal.world_updates) { return true; }
return proposal.world_updates.reduce(
(acc, update) => {
const valid =
(update.x >= 0 && update.x < lattice[0].length) &&
(update.y >= 0 && update.y < lattice.length) &&
(lattice[update.y][update.x].type == update.from)
return valid && acc;
},
true
);
}
// apply a set of proposals, returning the new lattice
export function lattice_apply(lattice, proposals) {
return proposals.reduce(
(acc, prop) => {
const change = (prop.world_updates || []).reduce(
(acc_, update) => {
const cell = acc_[update.y][update.x];
if (update.to) { cell.type = update.to; }
if (update.flags) {
cell.flags = cell.flags || {}
// this is very side-effect-y but i couldn't think of a nicer compatible way of doing it 😔
for (let k of Object.keys(update.flags)) {
cell.flags[k] = update.flags[k];
}
}
return acc_
},
[...acc]
);
return change;
},
[...lattice].map(row => row.map(cell => ({ ...cell, flags: {}, })))
);
}
|