-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathCatalog.js
More file actions
152 lines (136 loc) · 4.59 KB
/
Catalog.js
File metadata and controls
152 lines (136 loc) · 4.59 KB
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
import * as _ from "lodash";
export default class Catalog {
static getResourceByModelId(modelId) {
let r = -1;
for (let res of Catalog.resources) if (res.idOffset <= modelId) r++;
return Catalog.resources[r];
}
static getResourceByName(name) {
for (let res of Catalog.resources) if (res.name === name) return res;
return null;
}
// Expand an array of idsDesc to an array of integer ids
static expandIds(ids, playersCount) {
const exp = [];
for (let idsDesc of ids) {
const res = Catalog.getResourceByName(idsDesc.res);
const count = idsDesc.count.base + playersCount * idsDesc.count.byPlayer;
if (idsDesc.ids.expr) {
let id = idsDesc.ids.expr.base;
if (idsDesc.ids.expr.byPlayer === 0) {
// Single ID
if (id < res.count)
_.range(count).forEach(() => {
exp.push(id + res.idOffset);
});
else console.warn(`Invalid id ${id} for resource "${res.name}"`);
} else {
// One ID per player
for (let p = 0; p < playersCount; p++, id += idsDesc.ids.expr.byPlayer) {
if (id < res.count)
_.range(count).forEach(() => {
exp.push(id + res.idOffset);
});
else console.warn(`Invalid id ${id} for resource "${res.name}"`);
}
}
} else {
// Range of ID
let { begin, end } = idsDesc.ids.range;
if (end < begin) [begin, end] = [end, begin];
for (let id = begin; id <= end; id++) {
if (id < res.count)
_.range(count).forEach(() => {
exp.push(id + res.idOffset);
});
else console.warn(`Invalid id ${id} for resource "${res.name}"`);
}
}
}
return exp;
}
}
// ("2p+4+p+5") -> {base: 9, byPlayer: 3}
function parseExpr(expr) {
const coeff = { base: 0, byPlayer: 0 };
for (let elt of expr.split("+")) {
const n = parseInt(elt);
if (elt.endsWith("p")) coeff.byPlayer += isNaN(n) ? 1 : n;
else coeff.base += isNaN(n) ? 1 : n;
}
return coeff;
}
// parseExpr or ("42-69") -> {begin: 42, end: 69}
function parseIds(ids) {
if (ids.includes("-")) {
const range = ids.split("-");
return { range: { begin: parseInt(range[0]), end: parseInt(range[1]) } };
} else {
return { expr: parseExpr(ids) };
}
}
// idsDesc : ids "x" count
// | ids
// count : expr
// ids : expr
// | range
// expr : exprElt
// | exprElt "+" expr
// exprElt : integer "p"
// | integer
// range : integer "-" integer
// integer : \d+
function parseIdsDesc(idsDesc) {
const idsAndCount = idsDesc.split("x");
const count = idsAndCount.length > 1 ? parseExpr(idsAndCount[1]) : { base: 1, byPlayer: 0 };
const ids = parseIds(idsAndCount[0]);
const dependsOnPlayers = count.byPlayer > 0 || (ids.expr != null && ids.expr.byPlayer > 0);
return { idsDesc: { ids, count }, dependsOnPlayers };
}
function init() {
// statically load catalog description
Object.assign(Catalog, require("../../src/data/catalog.json"));
// sort resources by ascending idOffset
let count = 0;
Catalog.resources.forEach((r) => {
// build prefix
r.prefix = r.name + "-";
// compute offset of the ids of the group
r.idOffset = count;
count += r.count;
});
// Expand ids
for (let g of Object.keys(Catalog.games)) {
let ids = [];
let dependsOnPlayersCount = false;
for (let name of Object.keys(Catalog.games[g].ids)) {
let list = Catalog.games[g].ids[name];
let res = Catalog.getResourceByName(name);
if (res === null) {
console.warn(`In game ${g}, unknown resource "${name}"`);
continue;
}
for (let id of list) {
const idsDesc = parseIdsDesc(String(id));
ids.push({ ...idsDesc.idsDesc, res: name });
if (idsDesc.dependsOnPlayers) dependsOnPlayersCount = true;
}
}
Catalog.games[g].ids = ids;
Catalog.games[g].dependsOnPlayersCount = dependsOnPlayersCount;
}
}
init();
Catalog.SUFFIX = ".png";
Catalog.UNKNOWN_SUFFIX = "unknown.png";
Catalog.BACK_SUFFIX = "back.png";
Catalog.UNKNOWN_BACK_SUFFIX = "unknown_back.png";
// Covid Letter
Catalog.getResourceByName("covid").descriptions = require("../../src/data/covid-letter-desc.json");
Catalog.games["covid-letter"].html = require("../../src/data/covid-letter-html.json").join("\n");
// Star Sprint
Catalog.games["star-sprint"].html = require("../../src/data/star-sprint-html.json").join("\n");
// Five Green
Catalog.getResourceByName(
"green-five-question"
).descriptions = require("../../src/data/green-five-question-desc.json");