@pompidup/kingdomino-engine 1.1.1 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +158 -46
- package/dist/index.js +1536 -1158
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -1,609 +1,929 @@
|
|
|
1
|
-
// src/adapters/driver/index.ts
|
|
2
|
-
import { loadEnvFile } from "process";
|
|
3
|
-
|
|
4
1
|
// src/datasources/dominoes.json
|
|
5
|
-
var dominoes_default =
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
{
|
|
18
|
-
left: {
|
|
19
|
-
type: "wheat",
|
|
20
|
-
crowns: 0
|
|
21
|
-
},
|
|
22
|
-
right: {
|
|
23
|
-
type: "wheat",
|
|
24
|
-
crowns: 0
|
|
25
|
-
},
|
|
26
|
-
number: 2
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
left: {
|
|
30
|
-
type: "forest",
|
|
31
|
-
crowns: 0
|
|
32
|
-
},
|
|
33
|
-
right: {
|
|
34
|
-
type: "forest",
|
|
35
|
-
crowns: 0
|
|
36
|
-
},
|
|
37
|
-
number: 3
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
left: {
|
|
41
|
-
type: "forest",
|
|
42
|
-
crowns: 0
|
|
43
|
-
},
|
|
44
|
-
right: {
|
|
45
|
-
type: "forest",
|
|
46
|
-
crowns: 0
|
|
47
|
-
},
|
|
48
|
-
number: 4
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
left: {
|
|
52
|
-
type: "forest",
|
|
53
|
-
crowns: 0
|
|
54
|
-
},
|
|
55
|
-
right: {
|
|
56
|
-
type: "forest",
|
|
57
|
-
crowns: 0
|
|
58
|
-
},
|
|
59
|
-
number: 5
|
|
60
|
-
},
|
|
61
|
-
{
|
|
62
|
-
left: {
|
|
63
|
-
type: "forest",
|
|
64
|
-
crowns: 0
|
|
65
|
-
},
|
|
66
|
-
right: {
|
|
67
|
-
type: "forest",
|
|
68
|
-
crowns: 0
|
|
69
|
-
},
|
|
70
|
-
number: 6
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
left: {
|
|
74
|
-
type: "water",
|
|
75
|
-
crowns: 0
|
|
76
|
-
},
|
|
77
|
-
right: {
|
|
78
|
-
type: "water",
|
|
79
|
-
crowns: 0
|
|
80
|
-
},
|
|
81
|
-
number: 7
|
|
82
|
-
},
|
|
83
|
-
{
|
|
84
|
-
left: {
|
|
85
|
-
type: "water",
|
|
86
|
-
crowns: 0
|
|
87
|
-
},
|
|
88
|
-
right: {
|
|
89
|
-
type: "water",
|
|
90
|
-
crowns: 0
|
|
91
|
-
},
|
|
92
|
-
number: 8
|
|
93
|
-
},
|
|
94
|
-
{
|
|
95
|
-
left: {
|
|
96
|
-
type: "water",
|
|
97
|
-
crowns: 0
|
|
98
|
-
},
|
|
99
|
-
right: {
|
|
100
|
-
type: "water",
|
|
101
|
-
crowns: 0
|
|
102
|
-
},
|
|
103
|
-
number: 9
|
|
104
|
-
},
|
|
105
|
-
{
|
|
106
|
-
left: {
|
|
107
|
-
type: "grass",
|
|
108
|
-
crowns: 0
|
|
109
|
-
},
|
|
110
|
-
right: {
|
|
111
|
-
type: "grass",
|
|
112
|
-
crowns: 0
|
|
113
|
-
},
|
|
114
|
-
number: 10
|
|
115
|
-
},
|
|
116
|
-
{
|
|
117
|
-
left: {
|
|
118
|
-
type: "grass",
|
|
119
|
-
crowns: 0
|
|
120
|
-
},
|
|
121
|
-
right: {
|
|
122
|
-
type: "grass",
|
|
123
|
-
crowns: 0
|
|
124
|
-
},
|
|
125
|
-
number: 11
|
|
126
|
-
},
|
|
127
|
-
{
|
|
128
|
-
left: {
|
|
129
|
-
type: "swamp",
|
|
130
|
-
crowns: 0
|
|
131
|
-
},
|
|
132
|
-
right: {
|
|
133
|
-
type: "swamp",
|
|
134
|
-
crowns: 0
|
|
135
|
-
},
|
|
136
|
-
number: 12
|
|
137
|
-
},
|
|
138
|
-
{
|
|
139
|
-
left: {
|
|
140
|
-
type: "wheat",
|
|
141
|
-
crowns: 0
|
|
142
|
-
},
|
|
143
|
-
right: {
|
|
144
|
-
type: "forest",
|
|
145
|
-
crowns: 0
|
|
146
|
-
},
|
|
147
|
-
number: 13
|
|
148
|
-
},
|
|
149
|
-
{
|
|
150
|
-
left: {
|
|
151
|
-
type: "wheat",
|
|
152
|
-
crowns: 0
|
|
153
|
-
},
|
|
154
|
-
right: {
|
|
155
|
-
type: "water",
|
|
156
|
-
crowns: 0
|
|
157
|
-
},
|
|
158
|
-
number: 14
|
|
159
|
-
},
|
|
160
|
-
{
|
|
161
|
-
left: {
|
|
162
|
-
type: "wheat",
|
|
163
|
-
crowns: 0
|
|
164
|
-
},
|
|
165
|
-
right: {
|
|
166
|
-
type: "grass",
|
|
167
|
-
crowns: 0
|
|
168
|
-
},
|
|
169
|
-
number: 15
|
|
170
|
-
},
|
|
171
|
-
{
|
|
172
|
-
left: {
|
|
173
|
-
type: "wheat",
|
|
174
|
-
crowns: 0
|
|
175
|
-
},
|
|
176
|
-
right: {
|
|
177
|
-
type: "swamp",
|
|
178
|
-
crowns: 0
|
|
179
|
-
},
|
|
180
|
-
number: 16
|
|
181
|
-
},
|
|
182
|
-
{
|
|
183
|
-
left: {
|
|
184
|
-
type: "forest",
|
|
185
|
-
crowns: 0
|
|
186
|
-
},
|
|
187
|
-
right: {
|
|
188
|
-
type: "water",
|
|
189
|
-
crowns: 0
|
|
190
|
-
},
|
|
191
|
-
number: 17
|
|
192
|
-
},
|
|
193
|
-
{
|
|
194
|
-
left: {
|
|
195
|
-
type: "forest",
|
|
196
|
-
crowns: 0
|
|
197
|
-
},
|
|
198
|
-
right: {
|
|
199
|
-
type: "grass",
|
|
200
|
-
crowns: 0
|
|
201
|
-
},
|
|
202
|
-
number: 18
|
|
203
|
-
},
|
|
204
|
-
{
|
|
205
|
-
left: {
|
|
206
|
-
type: "wheat",
|
|
207
|
-
crowns: 1
|
|
208
|
-
},
|
|
209
|
-
right: {
|
|
210
|
-
type: "forest",
|
|
211
|
-
crowns: 0
|
|
212
|
-
},
|
|
213
|
-
number: 19
|
|
214
|
-
},
|
|
215
|
-
{
|
|
216
|
-
left: {
|
|
217
|
-
type: "wheat",
|
|
218
|
-
crowns: 1
|
|
219
|
-
},
|
|
220
|
-
right: {
|
|
221
|
-
type: "water",
|
|
222
|
-
crowns: 0
|
|
223
|
-
},
|
|
224
|
-
number: 20
|
|
225
|
-
},
|
|
226
|
-
{
|
|
227
|
-
left: {
|
|
228
|
-
type: "wheat",
|
|
229
|
-
crowns: 1
|
|
230
|
-
},
|
|
231
|
-
right: {
|
|
232
|
-
type: "grass",
|
|
233
|
-
crowns: 0
|
|
234
|
-
},
|
|
235
|
-
number: 21
|
|
236
|
-
},
|
|
237
|
-
{
|
|
238
|
-
left: {
|
|
239
|
-
type: "wheat",
|
|
240
|
-
crowns: 1
|
|
241
|
-
},
|
|
242
|
-
right: {
|
|
243
|
-
type: "swamp",
|
|
244
|
-
crowns: 0
|
|
245
|
-
},
|
|
246
|
-
number: 22
|
|
247
|
-
},
|
|
248
|
-
{
|
|
249
|
-
left: {
|
|
250
|
-
type: "wheat",
|
|
251
|
-
crowns: 1
|
|
252
|
-
},
|
|
253
|
-
right: {
|
|
254
|
-
type: "mine",
|
|
255
|
-
crowns: 0
|
|
256
|
-
},
|
|
257
|
-
number: 23
|
|
258
|
-
},
|
|
259
|
-
{
|
|
260
|
-
left: {
|
|
261
|
-
type: "forest",
|
|
262
|
-
crowns: 1
|
|
263
|
-
},
|
|
264
|
-
right: {
|
|
265
|
-
type: "wheat",
|
|
266
|
-
crowns: 0
|
|
267
|
-
},
|
|
268
|
-
number: 24
|
|
269
|
-
},
|
|
270
|
-
{
|
|
271
|
-
left: {
|
|
272
|
-
type: "forest",
|
|
273
|
-
crowns: 1
|
|
274
|
-
},
|
|
275
|
-
right: {
|
|
276
|
-
type: "wheat",
|
|
277
|
-
crowns: 0
|
|
2
|
+
var dominoes_default = {
|
|
3
|
+
Classic: [
|
|
4
|
+
{
|
|
5
|
+
left: {
|
|
6
|
+
type: "wheat",
|
|
7
|
+
crowns: 0
|
|
8
|
+
},
|
|
9
|
+
right: {
|
|
10
|
+
type: "wheat",
|
|
11
|
+
crowns: 0
|
|
12
|
+
},
|
|
13
|
+
number: 1
|
|
278
14
|
},
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
15
|
+
{
|
|
16
|
+
left: {
|
|
17
|
+
type: "wheat",
|
|
18
|
+
crowns: 0
|
|
19
|
+
},
|
|
20
|
+
right: {
|
|
21
|
+
type: "wheat",
|
|
22
|
+
crowns: 0
|
|
23
|
+
},
|
|
24
|
+
number: 2
|
|
285
25
|
},
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
26
|
+
{
|
|
27
|
+
left: {
|
|
28
|
+
type: "forest",
|
|
29
|
+
crowns: 0
|
|
30
|
+
},
|
|
31
|
+
right: {
|
|
32
|
+
type: "forest",
|
|
33
|
+
crowns: 0
|
|
34
|
+
},
|
|
35
|
+
number: 3
|
|
289
36
|
},
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
37
|
+
{
|
|
38
|
+
left: {
|
|
39
|
+
type: "forest",
|
|
40
|
+
crowns: 0
|
|
41
|
+
},
|
|
42
|
+
right: {
|
|
43
|
+
type: "forest",
|
|
44
|
+
crowns: 0
|
|
45
|
+
},
|
|
46
|
+
number: 4
|
|
296
47
|
},
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
48
|
+
{
|
|
49
|
+
left: {
|
|
50
|
+
type: "forest",
|
|
51
|
+
crowns: 0
|
|
52
|
+
},
|
|
53
|
+
right: {
|
|
54
|
+
type: "forest",
|
|
55
|
+
crowns: 0
|
|
56
|
+
},
|
|
57
|
+
number: 5
|
|
300
58
|
},
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
59
|
+
{
|
|
60
|
+
left: {
|
|
61
|
+
type: "forest",
|
|
62
|
+
crowns: 0
|
|
63
|
+
},
|
|
64
|
+
right: {
|
|
65
|
+
type: "forest",
|
|
66
|
+
crowns: 0
|
|
67
|
+
},
|
|
68
|
+
number: 6
|
|
307
69
|
},
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
70
|
+
{
|
|
71
|
+
left: {
|
|
72
|
+
type: "sea",
|
|
73
|
+
crowns: 0
|
|
74
|
+
},
|
|
75
|
+
right: {
|
|
76
|
+
type: "sea",
|
|
77
|
+
crowns: 0
|
|
78
|
+
},
|
|
79
|
+
number: 7
|
|
311
80
|
},
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
81
|
+
{
|
|
82
|
+
left: {
|
|
83
|
+
type: "sea",
|
|
84
|
+
crowns: 0
|
|
85
|
+
},
|
|
86
|
+
right: {
|
|
87
|
+
type: "sea",
|
|
88
|
+
crowns: 0
|
|
89
|
+
},
|
|
90
|
+
number: 8
|
|
318
91
|
},
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
92
|
+
{
|
|
93
|
+
left: {
|
|
94
|
+
type: "sea",
|
|
95
|
+
crowns: 0
|
|
96
|
+
},
|
|
97
|
+
right: {
|
|
98
|
+
type: "sea",
|
|
99
|
+
crowns: 0
|
|
100
|
+
},
|
|
101
|
+
number: 9
|
|
322
102
|
},
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
103
|
+
{
|
|
104
|
+
left: {
|
|
105
|
+
type: "plain",
|
|
106
|
+
crowns: 0
|
|
107
|
+
},
|
|
108
|
+
right: {
|
|
109
|
+
type: "plain",
|
|
110
|
+
crowns: 0
|
|
111
|
+
},
|
|
112
|
+
number: 10
|
|
329
113
|
},
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
114
|
+
{
|
|
115
|
+
left: {
|
|
116
|
+
type: "plain",
|
|
117
|
+
crowns: 0
|
|
118
|
+
},
|
|
119
|
+
right: {
|
|
120
|
+
type: "plain",
|
|
121
|
+
crowns: 0
|
|
122
|
+
},
|
|
123
|
+
number: 11
|
|
333
124
|
},
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
125
|
+
{
|
|
126
|
+
left: {
|
|
127
|
+
type: "swamp",
|
|
128
|
+
crowns: 0
|
|
129
|
+
},
|
|
130
|
+
right: {
|
|
131
|
+
type: "swamp",
|
|
132
|
+
crowns: 0
|
|
133
|
+
},
|
|
134
|
+
number: 12
|
|
340
135
|
},
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
136
|
+
{
|
|
137
|
+
left: {
|
|
138
|
+
type: "wheat",
|
|
139
|
+
crowns: 0
|
|
140
|
+
},
|
|
141
|
+
right: {
|
|
142
|
+
type: "forest",
|
|
143
|
+
crowns: 0
|
|
144
|
+
},
|
|
145
|
+
number: 13
|
|
344
146
|
},
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
147
|
+
{
|
|
148
|
+
left: {
|
|
149
|
+
type: "wheat",
|
|
150
|
+
crowns: 0
|
|
151
|
+
},
|
|
152
|
+
right: {
|
|
153
|
+
type: "sea",
|
|
154
|
+
crowns: 0
|
|
155
|
+
},
|
|
156
|
+
number: 14
|
|
351
157
|
},
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
158
|
+
{
|
|
159
|
+
left: {
|
|
160
|
+
type: "wheat",
|
|
161
|
+
crowns: 0
|
|
162
|
+
},
|
|
163
|
+
right: {
|
|
164
|
+
type: "plain",
|
|
165
|
+
crowns: 0
|
|
166
|
+
},
|
|
167
|
+
number: 15
|
|
355
168
|
},
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
169
|
+
{
|
|
170
|
+
left: {
|
|
171
|
+
type: "wheat",
|
|
172
|
+
crowns: 0
|
|
173
|
+
},
|
|
174
|
+
right: {
|
|
175
|
+
type: "swamp",
|
|
176
|
+
crowns: 0
|
|
177
|
+
},
|
|
178
|
+
number: 16
|
|
362
179
|
},
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
180
|
+
{
|
|
181
|
+
left: {
|
|
182
|
+
type: "forest",
|
|
183
|
+
crowns: 0
|
|
184
|
+
},
|
|
185
|
+
right: {
|
|
186
|
+
type: "sea",
|
|
187
|
+
crowns: 0
|
|
188
|
+
},
|
|
189
|
+
number: 17
|
|
366
190
|
},
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
191
|
+
{
|
|
192
|
+
left: {
|
|
193
|
+
type: "forest",
|
|
194
|
+
crowns: 0
|
|
195
|
+
},
|
|
196
|
+
right: {
|
|
197
|
+
type: "plain",
|
|
198
|
+
crowns: 0
|
|
199
|
+
},
|
|
200
|
+
number: 18
|
|
373
201
|
},
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
202
|
+
{
|
|
203
|
+
left: {
|
|
204
|
+
type: "wheat",
|
|
205
|
+
crowns: 1
|
|
206
|
+
},
|
|
207
|
+
right: {
|
|
208
|
+
type: "forest",
|
|
209
|
+
crowns: 0
|
|
210
|
+
},
|
|
211
|
+
number: 19
|
|
377
212
|
},
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
213
|
+
{
|
|
214
|
+
left: {
|
|
215
|
+
type: "wheat",
|
|
216
|
+
crowns: 1
|
|
217
|
+
},
|
|
218
|
+
right: {
|
|
219
|
+
type: "sea",
|
|
220
|
+
crowns: 0
|
|
221
|
+
},
|
|
222
|
+
number: 20
|
|
384
223
|
},
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
224
|
+
{
|
|
225
|
+
left: {
|
|
226
|
+
type: "wheat",
|
|
227
|
+
crowns: 1
|
|
228
|
+
},
|
|
229
|
+
right: {
|
|
230
|
+
type: "plain",
|
|
231
|
+
crowns: 0
|
|
232
|
+
},
|
|
233
|
+
number: 21
|
|
388
234
|
},
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
235
|
+
{
|
|
236
|
+
left: {
|
|
237
|
+
type: "wheat",
|
|
238
|
+
crowns: 1
|
|
239
|
+
},
|
|
240
|
+
right: {
|
|
241
|
+
type: "swamp",
|
|
242
|
+
crowns: 0
|
|
243
|
+
},
|
|
244
|
+
number: 22
|
|
395
245
|
},
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
246
|
+
{
|
|
247
|
+
left: {
|
|
248
|
+
type: "wheat",
|
|
249
|
+
crowns: 1
|
|
250
|
+
},
|
|
251
|
+
right: {
|
|
252
|
+
type: "mine",
|
|
253
|
+
crowns: 0
|
|
254
|
+
},
|
|
255
|
+
number: 23
|
|
399
256
|
},
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
257
|
+
{
|
|
258
|
+
left: {
|
|
259
|
+
type: "forest",
|
|
260
|
+
crowns: 1
|
|
261
|
+
},
|
|
262
|
+
right: {
|
|
263
|
+
type: "wheat",
|
|
264
|
+
crowns: 0
|
|
265
|
+
},
|
|
266
|
+
number: 24
|
|
406
267
|
},
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
268
|
+
{
|
|
269
|
+
left: {
|
|
270
|
+
type: "forest",
|
|
271
|
+
crowns: 1
|
|
272
|
+
},
|
|
273
|
+
right: {
|
|
274
|
+
type: "wheat",
|
|
275
|
+
crowns: 0
|
|
276
|
+
},
|
|
277
|
+
number: 25
|
|
410
278
|
},
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
279
|
+
{
|
|
280
|
+
left: {
|
|
281
|
+
type: "forest",
|
|
282
|
+
crowns: 1
|
|
283
|
+
},
|
|
284
|
+
right: {
|
|
285
|
+
type: "wheat",
|
|
286
|
+
crowns: 0
|
|
287
|
+
},
|
|
288
|
+
number: 26
|
|
417
289
|
},
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
290
|
+
{
|
|
291
|
+
left: {
|
|
292
|
+
type: "forest",
|
|
293
|
+
crowns: 1
|
|
294
|
+
},
|
|
295
|
+
right: {
|
|
296
|
+
type: "wheat",
|
|
297
|
+
crowns: 0
|
|
298
|
+
},
|
|
299
|
+
number: 27
|
|
421
300
|
},
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
301
|
+
{
|
|
302
|
+
left: {
|
|
303
|
+
type: "forest",
|
|
304
|
+
crowns: 1
|
|
305
|
+
},
|
|
306
|
+
right: {
|
|
307
|
+
type: "sea",
|
|
308
|
+
crowns: 0
|
|
309
|
+
},
|
|
310
|
+
number: 28
|
|
428
311
|
},
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
312
|
+
{
|
|
313
|
+
left: {
|
|
314
|
+
type: "forest",
|
|
315
|
+
crowns: 1
|
|
316
|
+
},
|
|
317
|
+
right: {
|
|
318
|
+
type: "plain",
|
|
319
|
+
crowns: 0
|
|
320
|
+
},
|
|
321
|
+
number: 29
|
|
432
322
|
},
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
323
|
+
{
|
|
324
|
+
left: {
|
|
325
|
+
type: "sea",
|
|
326
|
+
crowns: 1
|
|
327
|
+
},
|
|
328
|
+
right: {
|
|
329
|
+
type: "wheat",
|
|
330
|
+
crowns: 0
|
|
331
|
+
},
|
|
332
|
+
number: 30
|
|
439
333
|
},
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
334
|
+
{
|
|
335
|
+
left: {
|
|
336
|
+
type: "sea",
|
|
337
|
+
crowns: 1
|
|
338
|
+
},
|
|
339
|
+
right: {
|
|
340
|
+
type: "wheat",
|
|
341
|
+
crowns: 0
|
|
342
|
+
},
|
|
343
|
+
number: 31
|
|
443
344
|
},
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
345
|
+
{
|
|
346
|
+
left: {
|
|
347
|
+
type: "sea",
|
|
348
|
+
crowns: 1
|
|
349
|
+
},
|
|
350
|
+
right: {
|
|
351
|
+
type: "forest",
|
|
352
|
+
crowns: 0
|
|
353
|
+
},
|
|
354
|
+
number: 32
|
|
450
355
|
},
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
356
|
+
{
|
|
357
|
+
left: {
|
|
358
|
+
type: "sea",
|
|
359
|
+
crowns: 1
|
|
360
|
+
},
|
|
361
|
+
right: {
|
|
362
|
+
type: "forest",
|
|
363
|
+
crowns: 0
|
|
364
|
+
},
|
|
365
|
+
number: 33
|
|
454
366
|
},
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
367
|
+
{
|
|
368
|
+
left: {
|
|
369
|
+
type: "sea",
|
|
370
|
+
crowns: 1
|
|
371
|
+
},
|
|
372
|
+
right: {
|
|
373
|
+
type: "forest",
|
|
374
|
+
crowns: 0
|
|
375
|
+
},
|
|
376
|
+
number: 34
|
|
461
377
|
},
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
378
|
+
{
|
|
379
|
+
left: {
|
|
380
|
+
type: "sea",
|
|
381
|
+
crowns: 1
|
|
382
|
+
},
|
|
383
|
+
right: {
|
|
384
|
+
type: "forest",
|
|
385
|
+
crowns: 0
|
|
386
|
+
},
|
|
387
|
+
number: 35
|
|
465
388
|
},
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
389
|
+
{
|
|
390
|
+
left: {
|
|
391
|
+
type: "wheat",
|
|
392
|
+
crowns: 0
|
|
393
|
+
},
|
|
394
|
+
right: {
|
|
395
|
+
type: "plain",
|
|
396
|
+
crowns: 1
|
|
397
|
+
},
|
|
398
|
+
number: 36
|
|
472
399
|
},
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
400
|
+
{
|
|
401
|
+
left: {
|
|
402
|
+
type: "sea",
|
|
403
|
+
crowns: 0
|
|
404
|
+
},
|
|
405
|
+
right: {
|
|
406
|
+
type: "plain",
|
|
407
|
+
crowns: 1
|
|
408
|
+
},
|
|
409
|
+
number: 37
|
|
476
410
|
},
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
411
|
+
{
|
|
412
|
+
left: {
|
|
413
|
+
type: "wheat",
|
|
414
|
+
crowns: 0
|
|
415
|
+
},
|
|
416
|
+
right: {
|
|
417
|
+
type: "swamp",
|
|
418
|
+
crowns: 1
|
|
419
|
+
},
|
|
420
|
+
number: 38
|
|
483
421
|
},
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
422
|
+
{
|
|
423
|
+
left: {
|
|
424
|
+
type: "plain",
|
|
425
|
+
crowns: 0
|
|
426
|
+
},
|
|
427
|
+
right: {
|
|
428
|
+
type: "swamp",
|
|
429
|
+
crowns: 0
|
|
430
|
+
},
|
|
431
|
+
number: 39
|
|
487
432
|
},
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
433
|
+
{
|
|
434
|
+
left: {
|
|
435
|
+
type: "mine",
|
|
436
|
+
crowns: 1
|
|
437
|
+
},
|
|
438
|
+
right: {
|
|
439
|
+
type: "wheat",
|
|
440
|
+
crowns: 0
|
|
441
|
+
},
|
|
442
|
+
number: 40
|
|
494
443
|
},
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
444
|
+
{
|
|
445
|
+
left: {
|
|
446
|
+
type: "wheat",
|
|
447
|
+
crowns: 0
|
|
448
|
+
},
|
|
449
|
+
right: {
|
|
450
|
+
type: "plain",
|
|
451
|
+
crowns: 2
|
|
452
|
+
},
|
|
453
|
+
number: 41
|
|
498
454
|
},
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
455
|
+
{
|
|
456
|
+
left: {
|
|
457
|
+
type: "sea",
|
|
458
|
+
crowns: 0
|
|
459
|
+
},
|
|
460
|
+
right: {
|
|
461
|
+
type: "plain",
|
|
462
|
+
crowns: 2
|
|
463
|
+
},
|
|
464
|
+
number: 42
|
|
505
465
|
},
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
466
|
+
{
|
|
467
|
+
left: {
|
|
468
|
+
type: "wheat",
|
|
469
|
+
crowns: 0
|
|
470
|
+
},
|
|
471
|
+
right: {
|
|
472
|
+
type: "swamp",
|
|
473
|
+
crowns: 2
|
|
474
|
+
},
|
|
475
|
+
number: 43
|
|
509
476
|
},
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
477
|
+
{
|
|
478
|
+
left: {
|
|
479
|
+
type: "plain",
|
|
480
|
+
crowns: 0
|
|
481
|
+
},
|
|
482
|
+
right: {
|
|
483
|
+
type: "swamp",
|
|
484
|
+
crowns: 2
|
|
485
|
+
},
|
|
486
|
+
number: 44
|
|
516
487
|
},
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
488
|
+
{
|
|
489
|
+
left: {
|
|
490
|
+
type: "mine",
|
|
491
|
+
crowns: 2
|
|
492
|
+
},
|
|
493
|
+
right: {
|
|
494
|
+
type: "wheat",
|
|
495
|
+
crowns: 0
|
|
496
|
+
},
|
|
497
|
+
number: 45
|
|
520
498
|
},
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
499
|
+
{
|
|
500
|
+
left: {
|
|
501
|
+
type: "swamp",
|
|
502
|
+
crowns: 0
|
|
503
|
+
},
|
|
504
|
+
right: {
|
|
505
|
+
type: "mine",
|
|
506
|
+
crowns: 2
|
|
507
|
+
},
|
|
508
|
+
number: 46
|
|
527
509
|
},
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
510
|
+
{
|
|
511
|
+
left: {
|
|
512
|
+
type: "swamp",
|
|
513
|
+
crowns: 0
|
|
514
|
+
},
|
|
515
|
+
right: {
|
|
516
|
+
type: "mine",
|
|
517
|
+
crowns: 2
|
|
518
|
+
},
|
|
519
|
+
number: 47
|
|
531
520
|
},
|
|
532
|
-
|
|
533
|
-
}
|
|
534
|
-
];
|
|
535
|
-
|
|
536
|
-
// src/adapters/driven/inMemoryDominoes.ts
|
|
537
|
-
var inMemoryDominoes = () => {
|
|
538
|
-
const dominoes = [];
|
|
539
|
-
dominoes_default.forEach((domino) => {
|
|
540
|
-
dominoes.push({
|
|
521
|
+
{
|
|
541
522
|
left: {
|
|
542
|
-
type:
|
|
543
|
-
crowns:
|
|
523
|
+
type: "wheat",
|
|
524
|
+
crowns: 0
|
|
544
525
|
},
|
|
545
526
|
right: {
|
|
546
|
-
type:
|
|
547
|
-
crowns:
|
|
527
|
+
type: "mine",
|
|
528
|
+
crowns: 3
|
|
548
529
|
},
|
|
549
|
-
number:
|
|
530
|
+
number: 48
|
|
531
|
+
}
|
|
532
|
+
]
|
|
533
|
+
};
|
|
534
|
+
|
|
535
|
+
// src/adapterServerside/jsonDominoes.ts
|
|
536
|
+
var jsonDominoes = () => {
|
|
537
|
+
const dominoes = {};
|
|
538
|
+
for (const [key, value] of Object.entries(dominoes_default)) {
|
|
539
|
+
const currentDominoes = [];
|
|
540
|
+
value.forEach((domino) => {
|
|
541
|
+
currentDominoes.push({
|
|
542
|
+
left: {
|
|
543
|
+
type: domino.left.type,
|
|
544
|
+
crowns: domino.left.crowns
|
|
545
|
+
},
|
|
546
|
+
right: {
|
|
547
|
+
type: domino.right.type,
|
|
548
|
+
crowns: domino.right.crowns
|
|
549
|
+
},
|
|
550
|
+
number: domino.number
|
|
551
|
+
});
|
|
552
|
+
});
|
|
553
|
+
dominoes[key] = currentDominoes;
|
|
554
|
+
}
|
|
555
|
+
return {
|
|
556
|
+
getForMode: (mode) => {
|
|
557
|
+
return dominoes[mode.name] || [];
|
|
558
|
+
}
|
|
559
|
+
};
|
|
560
|
+
};
|
|
561
|
+
var jsonDominoes_default = jsonDominoes;
|
|
562
|
+
|
|
563
|
+
// src/datasources/modes.json
|
|
564
|
+
var modes_default = [
|
|
565
|
+
{
|
|
566
|
+
name: "Classic",
|
|
567
|
+
description: "Original KingDomino rules"
|
|
568
|
+
}
|
|
569
|
+
];
|
|
570
|
+
|
|
571
|
+
// src/adapterServerside/jsonModes.ts
|
|
572
|
+
var jsonModes = () => {
|
|
573
|
+
const modes = [];
|
|
574
|
+
modes_default.forEach((mode) => {
|
|
575
|
+
modes.push({
|
|
576
|
+
name: mode.name,
|
|
577
|
+
description: mode.description
|
|
578
|
+
});
|
|
579
|
+
});
|
|
580
|
+
return {
|
|
581
|
+
getAvailables: () => {
|
|
582
|
+
return modes;
|
|
583
|
+
}
|
|
584
|
+
};
|
|
585
|
+
};
|
|
586
|
+
var jsonModes_default = jsonModes;
|
|
587
|
+
|
|
588
|
+
// src/datasources/rules.json
|
|
589
|
+
var rules_default = {
|
|
590
|
+
commun: [
|
|
591
|
+
{
|
|
592
|
+
playersLimit: 2,
|
|
593
|
+
lordsPerPlayer: 2,
|
|
594
|
+
maxDominoes: 24,
|
|
595
|
+
dominoesPerTurn: 4,
|
|
596
|
+
maxTurns: 6
|
|
597
|
+
},
|
|
598
|
+
{
|
|
599
|
+
playersLimit: 3,
|
|
600
|
+
lordsPerPlayer: 1,
|
|
601
|
+
maxDominoes: 36,
|
|
602
|
+
dominoesPerTurn: 3,
|
|
603
|
+
maxTurns: 12
|
|
604
|
+
},
|
|
605
|
+
{
|
|
606
|
+
playersLimit: 4,
|
|
607
|
+
lordsPerPlayer: 1,
|
|
608
|
+
maxDominoes: 48,
|
|
609
|
+
dominoesPerTurn: 4,
|
|
610
|
+
maxTurns: 12
|
|
611
|
+
}
|
|
612
|
+
],
|
|
613
|
+
extra: [
|
|
614
|
+
{
|
|
615
|
+
name: "The middle Kingdom",
|
|
616
|
+
description: "Gain 10 additional points if your castle is in the middle of the kingdom.",
|
|
617
|
+
mode: [{ name: "Classic", description: "King Domino classic mode" }]
|
|
618
|
+
},
|
|
619
|
+
{
|
|
620
|
+
name: "Harmony",
|
|
621
|
+
description: "Gain 5 additional points if your kingdom is complete (no discarded dominoes).",
|
|
622
|
+
mode: [{ name: "Classic", description: "King Domino classic mode" }]
|
|
623
|
+
}
|
|
624
|
+
]
|
|
625
|
+
};
|
|
626
|
+
|
|
627
|
+
// src/adapterServerside/jsonRules.ts
|
|
628
|
+
var jsonRules = () => {
|
|
629
|
+
const rules = {
|
|
630
|
+
basic: {},
|
|
631
|
+
extraRules: []
|
|
632
|
+
};
|
|
633
|
+
const commonRules = rules_default.commun;
|
|
634
|
+
const extraRules = rules_default.extra;
|
|
635
|
+
commonRules.forEach((rule) => {
|
|
636
|
+
rules.basic[rule.playersLimit] = {
|
|
637
|
+
lords: rule.lordsPerPlayer,
|
|
638
|
+
maxDominoes: rule.maxDominoes,
|
|
639
|
+
dominoesPerTurn: rule.dominoesPerTurn,
|
|
640
|
+
maxTurns: rule.maxTurns
|
|
641
|
+
};
|
|
642
|
+
});
|
|
643
|
+
extraRules.forEach((rule) => {
|
|
644
|
+
rules.extraRules.push({
|
|
645
|
+
name: rule.name,
|
|
646
|
+
description: rule.description,
|
|
647
|
+
mode: rule.mode
|
|
550
648
|
});
|
|
551
649
|
});
|
|
552
650
|
return {
|
|
553
651
|
getAll: () => {
|
|
554
|
-
return
|
|
652
|
+
return rules;
|
|
653
|
+
},
|
|
654
|
+
getAllExtra: () => {
|
|
655
|
+
return rules.extraRules;
|
|
555
656
|
}
|
|
556
657
|
};
|
|
557
658
|
};
|
|
558
|
-
var
|
|
659
|
+
var jsonRules_default = jsonRules;
|
|
559
660
|
|
|
560
|
-
// src/
|
|
561
|
-
var
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
661
|
+
// src/utils/result.ts
|
|
662
|
+
var ok = (value) => ({ tag: "Ok", value });
|
|
663
|
+
var err = (error) => ({ tag: "Err", error });
|
|
664
|
+
var isOk = (result) => result.tag === "Ok";
|
|
665
|
+
var isErr = (result) => result.tag === "Err";
|
|
666
|
+
|
|
667
|
+
// src/application/handlers/addExtraRulesHandler.ts
|
|
668
|
+
var addExtraRulesHandler = (useCase) => (command) => {
|
|
669
|
+
const { game, extraRules } = command;
|
|
670
|
+
if (game.nextAction.step !== "options") {
|
|
671
|
+
throw new Error("Invalid next action");
|
|
672
|
+
}
|
|
673
|
+
const result = useCase(game, extraRules);
|
|
674
|
+
if (isErr(result)) {
|
|
675
|
+
throw new Error(result.error);
|
|
676
|
+
}
|
|
677
|
+
return result.value;
|
|
678
|
+
};
|
|
679
|
+
|
|
680
|
+
// src/application/handlers/addPlayersHandler.ts
|
|
681
|
+
var addPlayersHandler = (useCase) => (command) => {
|
|
682
|
+
const { game, players } = command;
|
|
683
|
+
if (game.nextAction.step !== "addPlayers") {
|
|
684
|
+
throw new Error("Invalid next action");
|
|
685
|
+
}
|
|
686
|
+
const result = useCase(game, players);
|
|
687
|
+
if (isErr(result)) {
|
|
688
|
+
throw new Error(result.error);
|
|
689
|
+
}
|
|
690
|
+
return result.value;
|
|
691
|
+
};
|
|
692
|
+
|
|
693
|
+
// src/application/handlers/chooseDominoHandler.ts
|
|
694
|
+
var chooseDominoHandler = (useCase) => (command) => {
|
|
695
|
+
const { game, lordId, dominoPick } = command;
|
|
696
|
+
if (game.nextAction.nextAction !== "pickDomino") {
|
|
697
|
+
throw new Error("Invalid next action");
|
|
698
|
+
}
|
|
699
|
+
const result = useCase(game, lordId, dominoPick);
|
|
700
|
+
if (isErr(result)) {
|
|
701
|
+
throw new Error(result.error);
|
|
702
|
+
}
|
|
703
|
+
return result.value;
|
|
704
|
+
};
|
|
705
|
+
|
|
706
|
+
// src/application/handlers/createGameHandler.ts
|
|
707
|
+
var createGameHandler = (useCase) => (command) => {
|
|
708
|
+
const result = useCase(command.mode);
|
|
709
|
+
if (isErr(result)) {
|
|
710
|
+
throw new Error(result.error);
|
|
711
|
+
}
|
|
712
|
+
return result.value;
|
|
713
|
+
};
|
|
714
|
+
|
|
715
|
+
// src/core/domain/types/game.ts
|
|
716
|
+
var gameSteps = {
|
|
717
|
+
addPlayers: "addPlayers",
|
|
718
|
+
options: "options",
|
|
719
|
+
start: "start",
|
|
720
|
+
result: "result"
|
|
721
|
+
};
|
|
722
|
+
var isGameWithNextAction = (game) => {
|
|
723
|
+
return game.nextAction.type === "action";
|
|
724
|
+
};
|
|
725
|
+
|
|
726
|
+
// src/application/handlers/discardDominoHandler.ts
|
|
727
|
+
var discardDominoHandler = (useCase) => (command) => {
|
|
728
|
+
const { game, lordId } = command;
|
|
729
|
+
if (game.nextAction.nextAction !== "placeDomino") {
|
|
730
|
+
throw new Error("Invalid next action");
|
|
731
|
+
}
|
|
732
|
+
const result = useCase(game, lordId);
|
|
733
|
+
if (isErr(result)) {
|
|
734
|
+
throw new Error(result.error);
|
|
735
|
+
}
|
|
736
|
+
if (isGameWithNextAction(result.value)) {
|
|
737
|
+
return result.value;
|
|
738
|
+
}
|
|
739
|
+
return result.value;
|
|
740
|
+
};
|
|
741
|
+
|
|
742
|
+
// src/application/handlers/getExtraRulesHandler.ts
|
|
743
|
+
var getExtraRulesHandler = (getExtraRulesUseCase2) => (command) => {
|
|
744
|
+
const { mode, players } = command;
|
|
745
|
+
const result = getExtraRulesUseCase2(mode, players);
|
|
746
|
+
if (isErr(result)) {
|
|
747
|
+
throw new Error(result.error);
|
|
748
|
+
}
|
|
749
|
+
return result.value;
|
|
750
|
+
};
|
|
751
|
+
|
|
752
|
+
// src/application/handlers/getModesHandler.ts
|
|
753
|
+
var getModesHandler = (getModeUseCase) => (_command) => {
|
|
754
|
+
const result = getModeUseCase();
|
|
755
|
+
if (isErr(result)) {
|
|
756
|
+
throw new Error(result.error);
|
|
757
|
+
}
|
|
758
|
+
return result.value;
|
|
759
|
+
};
|
|
760
|
+
|
|
761
|
+
// src/application/handlers/getResultHandler.ts
|
|
762
|
+
var getResultHandler = (useCase) => (command) => {
|
|
763
|
+
const { game } = command;
|
|
764
|
+
if (game.nextAction.step !== "result") {
|
|
765
|
+
throw new Error("Invalid next step");
|
|
766
|
+
}
|
|
767
|
+
const result = useCase(game);
|
|
768
|
+
if (isErr(result)) {
|
|
769
|
+
throw new Error(result.error);
|
|
770
|
+
}
|
|
771
|
+
return result.value;
|
|
772
|
+
};
|
|
773
|
+
|
|
774
|
+
// src/application/handlers/placeDominoHandler.ts
|
|
775
|
+
var placeDominoHandler = (useCase) => (command) => {
|
|
776
|
+
const { game, lordId, position, orientation, rotation } = command;
|
|
777
|
+
if (game.nextAction.nextAction !== "placeDomino") {
|
|
778
|
+
throw new Error("Invalid next action");
|
|
779
|
+
}
|
|
780
|
+
const result = useCase(game, lordId, position, orientation, rotation);
|
|
781
|
+
if (isErr(result)) {
|
|
782
|
+
throw new Error(result.error);
|
|
783
|
+
}
|
|
784
|
+
if (isGameWithNextAction(result.value)) {
|
|
785
|
+
return result.value;
|
|
786
|
+
}
|
|
787
|
+
return result.value;
|
|
788
|
+
};
|
|
789
|
+
|
|
790
|
+
// src/application/handlers/startGameHandler.ts
|
|
791
|
+
var startGameHandler = (useCase) => (command) => {
|
|
792
|
+
const { game } = command;
|
|
793
|
+
if (game.nextAction.step !== "start") {
|
|
794
|
+
throw new Error("Invalid next action");
|
|
795
|
+
}
|
|
796
|
+
const result = useCase(game);
|
|
797
|
+
if (isErr(result)) {
|
|
798
|
+
throw new Error(result.error);
|
|
799
|
+
}
|
|
800
|
+
return result.value;
|
|
801
|
+
};
|
|
802
|
+
|
|
803
|
+
// src/core/domain/types/kingdom.ts
|
|
804
|
+
var GRIDSIZE = 9;
|
|
805
|
+
|
|
806
|
+
// src/core/domain/types/domino.ts
|
|
807
|
+
var GROUND = [
|
|
808
|
+
"castle",
|
|
809
|
+
"wheat",
|
|
810
|
+
"forest",
|
|
811
|
+
"sea",
|
|
812
|
+
"plain",
|
|
813
|
+
"swamp",
|
|
814
|
+
"mine"
|
|
815
|
+
];
|
|
816
|
+
|
|
817
|
+
// src/core/domain/types/player.ts
|
|
818
|
+
var playerActions = {
|
|
819
|
+
placeDomino: "placeDomino",
|
|
820
|
+
pickDomino: "pickDomino",
|
|
821
|
+
pass: "pass"
|
|
822
|
+
};
|
|
823
|
+
|
|
824
|
+
// src/core/domain/entities/rule.ts
|
|
825
|
+
var getAvailablesExtraRules = (extraRules, mode, numberOfPlayers) => {
|
|
826
|
+
const availableExtraRules = extraRules.filter((rule) => {
|
|
827
|
+
return rule.mode.filter((m) => m.name === mode).length > 0 && (!rule.playersLimit || rule.playersLimit === numberOfPlayers);
|
|
828
|
+
});
|
|
829
|
+
if (availableExtraRules.length === 0) {
|
|
830
|
+
return err("No extra rules found");
|
|
831
|
+
}
|
|
832
|
+
return ok(availableExtraRules);
|
|
833
|
+
};
|
|
834
|
+
var toExtraRule = (rule, extraRules) => {
|
|
835
|
+
const foundRule = extraRules.find((r) => r.name === rule);
|
|
836
|
+
if (!foundRule) {
|
|
837
|
+
return err(`Rule not found: ${rule}`);
|
|
838
|
+
}
|
|
839
|
+
return ok(foundRule);
|
|
840
|
+
};
|
|
841
|
+
|
|
842
|
+
// src/core/useCases/addExtraRules.ts
|
|
843
|
+
var addExtraRulesUseCase = (deps) => (game, rules) => {
|
|
844
|
+
const { ruleRepository } = deps;
|
|
845
|
+
const availableExtraRules = ruleRepository.getAllExtra();
|
|
846
|
+
const newExtraRules = [];
|
|
847
|
+
for (const rule of rules) {
|
|
848
|
+
const result = toExtraRule(rule, availableExtraRules);
|
|
849
|
+
if (isErr(result)) {
|
|
850
|
+
return result;
|
|
851
|
+
}
|
|
852
|
+
newExtraRules.push(result.value);
|
|
853
|
+
}
|
|
854
|
+
const updatedRules = {
|
|
855
|
+
basic: game.rules.basic,
|
|
856
|
+
extra: newExtraRules
|
|
857
|
+
};
|
|
858
|
+
const next = {
|
|
859
|
+
type: "step",
|
|
860
|
+
step: gameSteps.start
|
|
861
|
+
};
|
|
862
|
+
const updatedGame = {
|
|
863
|
+
...game,
|
|
864
|
+
rules: updatedRules,
|
|
865
|
+
nextAction: next
|
|
575
866
|
};
|
|
576
|
-
return
|
|
867
|
+
return ok(updatedGame);
|
|
577
868
|
};
|
|
578
869
|
|
|
579
|
-
// src/
|
|
870
|
+
// src/core/domain/entities/player.ts
|
|
871
|
+
var MINPLAYERSNAMELENGTH = 3;
|
|
872
|
+
var validatePlayer = (name) => {
|
|
873
|
+
if (!name || name.trim().length < MINPLAYERSNAMELENGTH) {
|
|
874
|
+
return err(`Invalid player name: ${name}`);
|
|
875
|
+
}
|
|
876
|
+
return ok(name);
|
|
877
|
+
};
|
|
878
|
+
var createPlayer = (playerName, id, kingdom) => {
|
|
879
|
+
const name = validatePlayer(playerName);
|
|
880
|
+
if (isErr(name)) {
|
|
881
|
+
return name;
|
|
882
|
+
}
|
|
883
|
+
return ok({
|
|
884
|
+
name: name.value,
|
|
885
|
+
id,
|
|
886
|
+
kingdom
|
|
887
|
+
});
|
|
888
|
+
};
|
|
889
|
+
|
|
890
|
+
// src/core/domain/entities/domino.ts
|
|
891
|
+
var isGround = (ground) => {
|
|
892
|
+
return GROUND.includes(ground);
|
|
893
|
+
};
|
|
894
|
+
var createTile = (ground, crowns = 0) => {
|
|
895
|
+
if (isGround(ground)) {
|
|
896
|
+
return { type: ground, crowns };
|
|
897
|
+
}
|
|
898
|
+
return { type: ground, crowns: 0 };
|
|
899
|
+
};
|
|
900
|
+
|
|
901
|
+
// src/core/domain/entities/kingdom.ts
|
|
580
902
|
var createEmptyKingdom = () => {
|
|
581
|
-
const
|
|
582
|
-
const
|
|
583
|
-
|
|
584
|
-
{ length:
|
|
585
|
-
() => Array.from({ length: gridSize }, () => emptyTile)
|
|
903
|
+
const emptyTile = createTile("empty");
|
|
904
|
+
const grid = Array.from(
|
|
905
|
+
{ length: GRIDSIZE },
|
|
906
|
+
() => Array.from({ length: GRIDSIZE }, () => emptyTile)
|
|
586
907
|
);
|
|
908
|
+
return grid;
|
|
587
909
|
};
|
|
588
|
-
var
|
|
589
|
-
const
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
...kingdom2.slice(position.y + 1)
|
|
599
|
-
];
|
|
910
|
+
var placeCastle = (kingdom) => {
|
|
911
|
+
const castle = createTile("castle");
|
|
912
|
+
const newKingdom = deepCopyKingdom(kingdom);
|
|
913
|
+
newKingdom[4][4] = castle;
|
|
914
|
+
return newKingdom;
|
|
915
|
+
};
|
|
916
|
+
var placeTile = (kingdom, position, tile) => {
|
|
917
|
+
const newKingdom = deepCopyKingdom(kingdom);
|
|
918
|
+
newKingdom[position.y][position.x] = tile;
|
|
919
|
+
return newKingdom;
|
|
600
920
|
};
|
|
601
|
-
var getTile = (
|
|
602
|
-
const tile =
|
|
603
|
-
if (tile
|
|
604
|
-
|
|
921
|
+
var getTile = (kingdom, position) => {
|
|
922
|
+
const tile = kingdom[position.y]?.[position.x];
|
|
923
|
+
if (!tile) {
|
|
924
|
+
return err("Invalid placement (not fit into the grid)");
|
|
605
925
|
}
|
|
606
|
-
return tile;
|
|
926
|
+
return ok(tile);
|
|
607
927
|
};
|
|
608
928
|
var calculateDominoPosition = (position, orientation, rotation, domino) => {
|
|
609
929
|
let firstTile;
|
|
@@ -675,51 +995,60 @@ var calculateDominoPosition = (position, orientation, rotation, domino) => {
|
|
|
675
995
|
}
|
|
676
996
|
return [firstTile, secondTile];
|
|
677
997
|
};
|
|
678
|
-
var placeDomino = (
|
|
998
|
+
var placeDomino = (kingdom, position, orientation, rotation, domino) => {
|
|
679
999
|
const [firstTile, secondTile] = calculateDominoPosition(
|
|
680
1000
|
position,
|
|
681
1001
|
orientation,
|
|
682
1002
|
rotation,
|
|
683
1003
|
domino
|
|
684
1004
|
);
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
1005
|
+
const isFreePlaceResult = isFreePlace(
|
|
1006
|
+
kingdom,
|
|
1007
|
+
firstTile.position,
|
|
1008
|
+
secondTile.position
|
|
1009
|
+
);
|
|
1010
|
+
if (isErr(isFreePlaceResult)) {
|
|
1011
|
+
return isFreePlaceResult;
|
|
690
1012
|
}
|
|
691
1013
|
const adjacentTiles = isAdjacent(
|
|
692
|
-
|
|
1014
|
+
kingdom,
|
|
693
1015
|
firstTile.position,
|
|
694
1016
|
secondTile.position
|
|
695
1017
|
);
|
|
696
1018
|
if (adjacentTiles.length === 0) {
|
|
697
|
-
|
|
1019
|
+
return err("Invalid placement (not adjacent)");
|
|
698
1020
|
}
|
|
699
1021
|
const hasValidAdjacentTiles = hasValidAdjacent(adjacentTiles, [
|
|
700
1022
|
firstTile.tile,
|
|
701
1023
|
secondTile.tile
|
|
702
1024
|
]);
|
|
703
1025
|
if (!hasValidAdjacentTiles) {
|
|
704
|
-
|
|
1026
|
+
return err("Invalid placement (not valid adjacent)");
|
|
705
1027
|
}
|
|
706
|
-
return placeTiles(
|
|
1028
|
+
return ok(placeTiles(kingdom, [firstTile, secondTile]));
|
|
707
1029
|
};
|
|
708
|
-
var placeTiles = (
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
1030
|
+
var placeTiles = (kingdom, tiles) => {
|
|
1031
|
+
let newKingdom = deepCopyKingdom(kingdom);
|
|
1032
|
+
for (const { tile, position } of tiles) {
|
|
1033
|
+
newKingdom = placeTile(newKingdom, position, tile);
|
|
1034
|
+
}
|
|
1035
|
+
return newKingdom;
|
|
713
1036
|
};
|
|
714
|
-
var isFreePlace = (
|
|
715
|
-
const firstTile = getTile(
|
|
716
|
-
const secondTile = getTile(
|
|
717
|
-
if (firstTile
|
|
718
|
-
return
|
|
1037
|
+
var isFreePlace = (kingdom, firstPosition, secondPosition) => {
|
|
1038
|
+
const firstTile = getTile(kingdom, firstPosition);
|
|
1039
|
+
const secondTile = getTile(kingdom, secondPosition);
|
|
1040
|
+
if (isErr(firstTile)) {
|
|
1041
|
+
return firstTile;
|
|
1042
|
+
}
|
|
1043
|
+
if (isErr(secondTile)) {
|
|
1044
|
+
return secondTile;
|
|
719
1045
|
}
|
|
720
|
-
|
|
1046
|
+
if (firstTile.value.type !== "empty" || secondTile.value.type !== "empty") {
|
|
1047
|
+
return err("Invalid placement (not empty)");
|
|
1048
|
+
}
|
|
1049
|
+
return ok(true);
|
|
721
1050
|
};
|
|
722
|
-
var isAdjacent = (
|
|
1051
|
+
var isAdjacent = (kingdom, firstPosition, secondPosition) => {
|
|
723
1052
|
const xFirstPosition = firstPosition.x;
|
|
724
1053
|
const yFirstPosition = firstPosition.y;
|
|
725
1054
|
const xSecondPosition = secondPosition.x;
|
|
@@ -748,9 +1077,11 @@ var isAdjacent = (kingdom2, firstPosition, secondPosition) => {
|
|
|
748
1077
|
1
|
|
749
1078
|
);
|
|
750
1079
|
adjacentTilesKeys.forEach((key) => {
|
|
751
|
-
const tile = getTile(
|
|
752
|
-
if (tile) {
|
|
753
|
-
|
|
1080
|
+
const tile = getTile(kingdom, key);
|
|
1081
|
+
if (isOk(tile)) {
|
|
1082
|
+
if (tile.value.type !== "empty") {
|
|
1083
|
+
adjacentTiles.push(tile.value);
|
|
1084
|
+
}
|
|
754
1085
|
}
|
|
755
1086
|
});
|
|
756
1087
|
return adjacentTiles;
|
|
@@ -762,675 +1093,722 @@ var hasValidAdjacent = (adjacentTiles, tiles) => {
|
|
|
762
1093
|
});
|
|
763
1094
|
});
|
|
764
1095
|
};
|
|
765
|
-
var
|
|
766
|
-
const
|
|
767
|
-
const
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
);
|
|
776
|
-
const
|
|
777
|
-
const
|
|
778
|
-
const
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
};
|
|
791
|
-
var kingdom_default = kingdom;
|
|
792
|
-
|
|
793
|
-
// src/hexagon/internal/services/setup.ts
|
|
794
|
-
var setup = (dependencies) => (payload) => {
|
|
795
|
-
const { state, players } = payload;
|
|
796
|
-
if (!players) {
|
|
797
|
-
throw new Error("There must be at least 2 players");
|
|
798
|
-
}
|
|
799
|
-
if (players.length > 4) {
|
|
800
|
-
throw new Error("There must be no more than 4 players");
|
|
801
|
-
}
|
|
802
|
-
if (players.length < 2) {
|
|
803
|
-
throw new Error("There must be at least 2 players");
|
|
804
|
-
}
|
|
805
|
-
const { dominoes } = state;
|
|
806
|
-
const { shuffleMethod: shuffleMethod2, uuidMethod: uuidMethod2 } = dependencies;
|
|
807
|
-
const { maxDominoes, dominoesPerTurn, maxTurns } = rules[players.length];
|
|
808
|
-
const shuffledDominoes = shuffleMethod2(dominoes);
|
|
809
|
-
shuffledDominoes.splice(maxDominoes);
|
|
810
|
-
const newPlayers = players.map((player) => {
|
|
811
|
-
return {
|
|
812
|
-
...player,
|
|
813
|
-
kingdom: kingdom_default.createKingdomWithCastle(),
|
|
814
|
-
id: uuidMethod2()
|
|
815
|
-
};
|
|
816
|
-
});
|
|
817
|
-
let newLords;
|
|
818
|
-
if (newPlayers.length === 2) {
|
|
819
|
-
newLords = [
|
|
820
|
-
{
|
|
821
|
-
id: uuidMethod2(),
|
|
822
|
-
playerId: newPlayers[0].id,
|
|
823
|
-
order: 1,
|
|
824
|
-
turnEnded: false,
|
|
825
|
-
hasPick: false,
|
|
826
|
-
hasPlace: false
|
|
827
|
-
},
|
|
828
|
-
{
|
|
829
|
-
id: uuidMethod2(),
|
|
830
|
-
playerId: newPlayers[0].id,
|
|
831
|
-
order: 2,
|
|
832
|
-
turnEnded: false,
|
|
833
|
-
hasPick: false,
|
|
834
|
-
hasPlace: false
|
|
835
|
-
},
|
|
836
|
-
{
|
|
837
|
-
id: uuidMethod2(),
|
|
838
|
-
playerId: newPlayers[1].id,
|
|
839
|
-
order: 3,
|
|
840
|
-
turnEnded: false,
|
|
841
|
-
hasPick: false,
|
|
842
|
-
hasPlace: false
|
|
843
|
-
},
|
|
844
|
-
{
|
|
845
|
-
id: uuidMethod2(),
|
|
846
|
-
playerId: newPlayers[1].id,
|
|
847
|
-
order: 4,
|
|
848
|
-
turnEnded: false,
|
|
849
|
-
hasPick: false,
|
|
850
|
-
hasPlace: false
|
|
851
|
-
}
|
|
852
|
-
];
|
|
853
|
-
} else {
|
|
854
|
-
newLords = newPlayers.map((player, index) => {
|
|
855
|
-
return {
|
|
856
|
-
id: uuidMethod2(),
|
|
857
|
-
playerId: player.id,
|
|
858
|
-
order: index + 1,
|
|
859
|
-
turnEnded: false,
|
|
860
|
-
hasPick: false,
|
|
861
|
-
hasPlace: false
|
|
862
|
-
};
|
|
863
|
-
});
|
|
864
|
-
}
|
|
865
|
-
const lordsWithOrder = shuffleMethod2(newLords);
|
|
866
|
-
lordsWithOrder.forEach((lord, index) => {
|
|
867
|
-
lord.order = index + 1;
|
|
868
|
-
});
|
|
869
|
-
lordsWithOrder.sort((a, b) => a.order - b.order);
|
|
870
|
-
const newState = {
|
|
871
|
-
...state,
|
|
872
|
-
dominoes: shuffledDominoes,
|
|
873
|
-
players: newPlayers,
|
|
874
|
-
lords: lordsWithOrder,
|
|
875
|
-
maxTurns,
|
|
876
|
-
maxDominoes,
|
|
877
|
-
dominoesPerTurn,
|
|
878
|
-
turn: 0
|
|
879
|
-
};
|
|
880
|
-
return newState;
|
|
881
|
-
};
|
|
882
|
-
|
|
883
|
-
// src/hexagon/internal/services/startTurn.ts
|
|
884
|
-
var startTurn = (payload) => {
|
|
885
|
-
const { state } = payload;
|
|
886
|
-
const turn = state.turn + 1;
|
|
887
|
-
const lords = state.lords;
|
|
888
|
-
lords.forEach((lord) => {
|
|
889
|
-
lord.turnEnded = false;
|
|
890
|
-
lord.hasPick = false;
|
|
891
|
-
lord.hasPlace = false;
|
|
892
|
-
});
|
|
893
|
-
const updatedState = {
|
|
894
|
-
...state,
|
|
895
|
-
lords,
|
|
896
|
-
turn
|
|
897
|
-
};
|
|
898
|
-
return { game: updatedState };
|
|
1096
|
+
var checkCastleIsInMiddle = (kingdom) => {
|
|
1097
|
+
const castlePosition = kingdom.map((row) => row.findIndex((tile) => tile.type === "castle")).find((index) => index !== -1);
|
|
1098
|
+
const leftTiles = castlePosition !== void 0 ? kingdom[castlePosition].slice(0, castlePosition) : [];
|
|
1099
|
+
const leftTilesCount = leftTiles.filter(
|
|
1100
|
+
(tile) => tile.type !== "empty"
|
|
1101
|
+
).length;
|
|
1102
|
+
const rightTiles = castlePosition !== void 0 ? kingdom[castlePosition].slice(castlePosition + 1) : [];
|
|
1103
|
+
const rightTilesCount = rightTiles.filter(
|
|
1104
|
+
(tile) => tile.type !== "empty"
|
|
1105
|
+
).length;
|
|
1106
|
+
const topTiles = castlePosition !== void 0 ? kingdom[castlePosition].slice(0, castlePosition) : [];
|
|
1107
|
+
const topTilesCount = topTiles.filter((tile) => tile.type !== "empty").length;
|
|
1108
|
+
const bottomTiles = castlePosition != void 0 ? kingdom[castlePosition].slice(castlePosition + 1) : [];
|
|
1109
|
+
const bottomTilesCount = bottomTiles.filter(
|
|
1110
|
+
(tile) => tile.type !== "empty"
|
|
1111
|
+
).length;
|
|
1112
|
+
return leftTilesCount === rightTilesCount && topTilesCount === bottomTilesCount && leftTilesCount === topTilesCount;
|
|
1113
|
+
};
|
|
1114
|
+
var countDominoes = (kingdom) => {
|
|
1115
|
+
const notEmpties = kingdom.flat().filter((tile) => tile.type !== "empty");
|
|
1116
|
+
const totalDominoes = (notEmpties.length - 1) / 2;
|
|
1117
|
+
return totalDominoes;
|
|
1118
|
+
};
|
|
1119
|
+
var deepCopyKingdom = (kingdom) => {
|
|
1120
|
+
return kingdom.map((line) => line.map((tile) => ({ ...tile })));
|
|
899
1121
|
};
|
|
900
1122
|
|
|
901
|
-
// src/
|
|
902
|
-
var
|
|
903
|
-
const {
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
if (!isLordTurn(state, lordId)) {
|
|
907
|
-
throw new Error("It is not your turn");
|
|
908
|
-
}
|
|
909
|
-
const lord = lords.find((lord2) => lord2.id === lordId);
|
|
910
|
-
if (lord?.hasPick) {
|
|
911
|
-
throw new Error("You have already picked");
|
|
912
|
-
}
|
|
913
|
-
const domino = checkValidityDomino(state, dominoPick);
|
|
914
|
-
const isError = (domino2) => {
|
|
915
|
-
return domino2.error !== void 0;
|
|
916
|
-
};
|
|
917
|
-
if (isError(domino)) {
|
|
918
|
-
throw new Error(domino.error);
|
|
1123
|
+
// src/core/useCases/addPlayers.ts
|
|
1124
|
+
var addPlayersUseCase = (deps) => (game, players) => {
|
|
1125
|
+
const { uuidMethod: uuidMethod2, shuffleMethod: shuffleMethod2, ruleRepository } = deps;
|
|
1126
|
+
if (!players || players.length < 2 || players.length > 4) {
|
|
1127
|
+
return err("Invalid number of players");
|
|
919
1128
|
}
|
|
920
|
-
const
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
if (lord2.id === lordId) {
|
|
929
|
-
lord2.hasPick = true;
|
|
930
|
-
lord2.turnEnded = true;
|
|
931
|
-
lord2.dominoPicked = domino.domino;
|
|
1129
|
+
const newPlayers = [];
|
|
1130
|
+
for (const player of players) {
|
|
1131
|
+
let kingdom = createEmptyKingdom();
|
|
1132
|
+
kingdom = placeCastle(kingdom);
|
|
1133
|
+
let id = uuidMethod2();
|
|
1134
|
+
const newPlayer = createPlayer(player, id, kingdom);
|
|
1135
|
+
if (isErr(newPlayer)) {
|
|
1136
|
+
return newPlayer;
|
|
932
1137
|
}
|
|
933
|
-
|
|
934
|
-
});
|
|
935
|
-
const updatedState = {
|
|
936
|
-
...state,
|
|
937
|
-
currentDominoes: updatedCurrentDominoes,
|
|
938
|
-
lords: updatedLords
|
|
939
|
-
};
|
|
940
|
-
return updatedState;
|
|
941
|
-
};
|
|
942
|
-
|
|
943
|
-
// src/hexagon/internal/services/place.ts
|
|
944
|
-
var place = (payload) => {
|
|
945
|
-
const { lordId, data } = payload;
|
|
946
|
-
const { state, position, orientation, rotation } = data;
|
|
947
|
-
const currentLord = state.lords.find((lord) => lord.id === lordId);
|
|
948
|
-
const currentPlayer = state.players.find(
|
|
949
|
-
(player) => player.id === currentLord?.playerId
|
|
950
|
-
);
|
|
951
|
-
const currentKingdom = currentPlayer?.kingdom;
|
|
952
|
-
if (!currentKingdom) {
|
|
953
|
-
throw new Error("Kingdom not found");
|
|
1138
|
+
newPlayers.push(newPlayer.value);
|
|
954
1139
|
}
|
|
955
|
-
const
|
|
956
|
-
|
|
957
|
-
|
|
1140
|
+
const rules = ruleRepository.getAll();
|
|
1141
|
+
const basicRules = rules.basic[newPlayers.length];
|
|
1142
|
+
if (!basicRules) {
|
|
1143
|
+
return err("No base rules found");
|
|
958
1144
|
}
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
const
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
1145
|
+
const dominoes = game.dominoes;
|
|
1146
|
+
const { maxDominoes } = basicRules;
|
|
1147
|
+
const shuffledDominoes = shuffleMethod2(dominoes);
|
|
1148
|
+
const splicedDominoes = shuffledDominoes.slice(0, maxDominoes);
|
|
1149
|
+
const next = {
|
|
1150
|
+
type: "step",
|
|
1151
|
+
step: "options"
|
|
1152
|
+
};
|
|
1153
|
+
const updatedGame = {
|
|
1154
|
+
...game,
|
|
1155
|
+
players: newPlayers,
|
|
1156
|
+
dominoes: splicedDominoes,
|
|
1157
|
+
rules: {
|
|
1158
|
+
...game.rules,
|
|
1159
|
+
basic: basicRules
|
|
1160
|
+
},
|
|
1161
|
+
nextAction: next
|
|
970
1162
|
};
|
|
971
|
-
return
|
|
1163
|
+
return ok(updatedGame);
|
|
972
1164
|
};
|
|
973
1165
|
|
|
974
|
-
// src/
|
|
975
|
-
var
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
1166
|
+
// src/core/domain/entities/lord.ts
|
|
1167
|
+
var createLord = (id, playerId) => {
|
|
1168
|
+
return {
|
|
1169
|
+
id,
|
|
1170
|
+
playerId,
|
|
1171
|
+
turnEnded: false,
|
|
1172
|
+
hasPick: false,
|
|
1173
|
+
hasPlace: true
|
|
1174
|
+
};
|
|
1175
|
+
};
|
|
1176
|
+
var hasPick = (lord) => lord.hasPick;
|
|
1177
|
+
var hasPlace = (lord) => lord.hasPlace;
|
|
1178
|
+
var hasTurnEnded = (lord) => lord.turnEnded;
|
|
1179
|
+
var canPass = (lord) => {
|
|
1180
|
+
return !hasPick(lord) && !hasPlace(lord) && !hasTurnEnded(lord);
|
|
1181
|
+
};
|
|
1182
|
+
var canPick = (lord) => {
|
|
1183
|
+
return !hasPick(lord) && hasPlace(lord) && !hasTurnEnded(lord);
|
|
1184
|
+
};
|
|
1185
|
+
var canPlaceAndDominoPickedIsDefined = (lord) => {
|
|
1186
|
+
return !hasPick(lord) && !hasPlace(lord) && !hasTurnEnded(lord) && lord.dominoPicked !== void 0;
|
|
1187
|
+
};
|
|
1188
|
+
var updateLordOrder = (lords) => {
|
|
1189
|
+
return lords.sort((a2, b2) => {
|
|
1190
|
+
return a2.dominoPicked.number - b2.dominoPicked.number;
|
|
987
1191
|
});
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
1192
|
+
};
|
|
1193
|
+
var resetLordsActions = (lord) => {
|
|
1194
|
+
const lordsCopy = [...lord];
|
|
1195
|
+
for (const lord2 of lordsCopy) {
|
|
1196
|
+
lord2.turnEnded = false;
|
|
1197
|
+
lord2.hasPick = false;
|
|
1198
|
+
lord2.hasPlace = false;
|
|
1199
|
+
}
|
|
1200
|
+
return lordsCopy;
|
|
1201
|
+
};
|
|
1202
|
+
var nextLordWithAction = (lords) => {
|
|
1203
|
+
const nextLord = findNextLord(lords);
|
|
1204
|
+
return {
|
|
1205
|
+
type: "action",
|
|
1206
|
+
nextLord: nextLord.id,
|
|
1207
|
+
nextAction: hasPlace(nextLord) ? playerActions.pickDomino : playerActions.placeDomino
|
|
998
1208
|
};
|
|
999
|
-
|
|
1209
|
+
};
|
|
1210
|
+
var findNextLord = (lords) => {
|
|
1211
|
+
const lord = lords.find((lord2) => !hasTurnEnded(lord2));
|
|
1212
|
+
if (!lord) {
|
|
1213
|
+
return lords[0];
|
|
1214
|
+
}
|
|
1215
|
+
return lord;
|
|
1216
|
+
};
|
|
1217
|
+
var allLordsHavePlayed = (lords) => {
|
|
1218
|
+
return lords.every((lord) => lord.turnEnded);
|
|
1000
1219
|
};
|
|
1001
1220
|
|
|
1002
|
-
// src/
|
|
1003
|
-
var
|
|
1004
|
-
const
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1221
|
+
// src/core/useCases/chooseDomino.ts
|
|
1222
|
+
var chooseDominoUseCase = (game, lordId, dominoPick) => {
|
|
1223
|
+
const currentLord = game.lords.find(
|
|
1224
|
+
(lord) => lord.id === game.nextAction.nextLord
|
|
1225
|
+
);
|
|
1226
|
+
if (!currentLord) {
|
|
1227
|
+
return err("Lord not found");
|
|
1228
|
+
}
|
|
1229
|
+
if (currentLord.id !== lordId) {
|
|
1230
|
+
return err("Not your turn");
|
|
1231
|
+
}
|
|
1232
|
+
if (!canPick(currentLord)) {
|
|
1233
|
+
return err("Lord can't pick");
|
|
1234
|
+
}
|
|
1235
|
+
const selectedDomino = game.currentDominoes.find(
|
|
1236
|
+
(domino) => domino.domino.number === dominoPick
|
|
1237
|
+
);
|
|
1238
|
+
if (!selectedDomino) {
|
|
1239
|
+
return err("Domino not found");
|
|
1240
|
+
}
|
|
1241
|
+
if (selectedDomino.picked) {
|
|
1242
|
+
return err("Domino already picked");
|
|
1243
|
+
}
|
|
1244
|
+
const updatedCurrentDominoes = game.currentDominoes.map((domino) => {
|
|
1245
|
+
if (domino.domino.number === dominoPick) {
|
|
1246
|
+
domino.picked = true;
|
|
1247
|
+
domino.lordId = currentLord.id;
|
|
1248
|
+
}
|
|
1249
|
+
return domino;
|
|
1250
|
+
});
|
|
1251
|
+
const updatedLords = game.lords.map((lord) => {
|
|
1252
|
+
if (lord.id === currentLord.id) {
|
|
1253
|
+
lord.hasPick = true;
|
|
1254
|
+
lord.turnEnded = true;
|
|
1255
|
+
lord.dominoPicked = selectedDomino.domino;
|
|
1256
|
+
}
|
|
1257
|
+
return lord;
|
|
1258
|
+
});
|
|
1259
|
+
const turnEnded = allLordsHavePlayed(updatedLords);
|
|
1260
|
+
if (turnEnded) {
|
|
1261
|
+
const lords = resetLordsActions(updateLordOrder(updatedLords));
|
|
1262
|
+
const updatedTurn = game.turn + 1;
|
|
1263
|
+
const next2 = nextLordWithAction(lords);
|
|
1264
|
+
const dominoesCopy = [...game.dominoes];
|
|
1265
|
+
const dominoesDrawn = dominoesCopy.splice(
|
|
1266
|
+
0,
|
|
1267
|
+
game.rules.basic.dominoesPerTurn
|
|
1268
|
+
);
|
|
1269
|
+
dominoesDrawn.sort((a2, b2) => a2.number - b2.number);
|
|
1270
|
+
const updatedCurrentDominoes2 = dominoesDrawn.map((domino, index) => {
|
|
1012
1271
|
return {
|
|
1013
1272
|
domino,
|
|
1014
1273
|
picked: false,
|
|
1015
1274
|
lordId: null,
|
|
1016
1275
|
position: index + 1
|
|
1017
1276
|
};
|
|
1018
|
-
})
|
|
1277
|
+
});
|
|
1278
|
+
return ok({
|
|
1279
|
+
...game,
|
|
1280
|
+
currentDominoes: updatedCurrentDominoes2,
|
|
1281
|
+
dominoes: dominoesCopy,
|
|
1282
|
+
lords,
|
|
1283
|
+
turn: updatedTurn,
|
|
1284
|
+
nextAction: next2
|
|
1285
|
+
});
|
|
1286
|
+
}
|
|
1287
|
+
const next = nextLordWithAction(updatedLords);
|
|
1288
|
+
const updatedState = {
|
|
1289
|
+
...game,
|
|
1290
|
+
currentDominoes: updatedCurrentDominoes,
|
|
1291
|
+
lords: updatedLords,
|
|
1292
|
+
nextAction: next
|
|
1019
1293
|
};
|
|
1020
|
-
return
|
|
1294
|
+
return ok(updatedState);
|
|
1021
1295
|
};
|
|
1022
1296
|
|
|
1023
|
-
// src/
|
|
1024
|
-
var
|
|
1025
|
-
const
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
[
|
|
1030
|
-
[
|
|
1031
|
-
[
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
}
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
);
|
|
1048
|
-
if (currentZone) {
|
|
1049
|
-
currentZone.crowns += crowns;
|
|
1050
|
-
currentZone.size++;
|
|
1051
|
-
currentZone.tiles.push([x, y]);
|
|
1052
|
-
} else {
|
|
1053
|
-
properties.push({ type, crowns, size: 1, tiles: [[x, y]] });
|
|
1054
|
-
}
|
|
1055
|
-
directions.forEach(([dx, dy]) => {
|
|
1056
|
-
const nx = x + dx;
|
|
1057
|
-
const ny = y + dy;
|
|
1058
|
-
if (nx >= 0 && ny >= 0 && nx < kingdom2[0].length && ny < kingdom2.length && kingdom2[ny][nx].type === type) {
|
|
1059
|
-
markZone(nx, ny, kingdom2[ny][nx].type, kingdom2[ny][nx].crowns);
|
|
1060
|
-
}
|
|
1061
|
-
});
|
|
1297
|
+
// src/core/domain/entities/game.ts
|
|
1298
|
+
var create = (payload) => {
|
|
1299
|
+
const { id, mode, dominoes } = payload;
|
|
1300
|
+
return {
|
|
1301
|
+
id,
|
|
1302
|
+
dominoes,
|
|
1303
|
+
currentDominoes: [],
|
|
1304
|
+
players: [],
|
|
1305
|
+
lords: [],
|
|
1306
|
+
turn: 0,
|
|
1307
|
+
nextAction: {
|
|
1308
|
+
type: "step",
|
|
1309
|
+
step: gameSteps.addPlayers
|
|
1310
|
+
},
|
|
1311
|
+
rules: {
|
|
1312
|
+
basic: {
|
|
1313
|
+
lords: 0,
|
|
1314
|
+
maxDominoes: 0,
|
|
1315
|
+
dominoesPerTurn: 0,
|
|
1316
|
+
maxTurns: 0
|
|
1317
|
+
},
|
|
1318
|
+
extra: []
|
|
1319
|
+
},
|
|
1320
|
+
mode
|
|
1062
1321
|
};
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
maxPropertiesSize: 0,
|
|
1074
|
-
totalCrowns: 0
|
|
1075
|
-
};
|
|
1322
|
+
};
|
|
1323
|
+
|
|
1324
|
+
// src/core/domain/entities/mode.ts
|
|
1325
|
+
var findMode = (mode, availableMode) => {
|
|
1326
|
+
return availableMode.find((m) => m.name === mode);
|
|
1327
|
+
};
|
|
1328
|
+
var createMode = (mode, availableMode) => {
|
|
1329
|
+
const foundMode = findMode(mode, availableMode);
|
|
1330
|
+
if (foundMode) {
|
|
1331
|
+
return ok(foundMode);
|
|
1076
1332
|
}
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
);
|
|
1084
|
-
const
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1333
|
+
return err(`Invalid mode: ${mode}`);
|
|
1334
|
+
};
|
|
1335
|
+
|
|
1336
|
+
// src/core/useCases/createGame.ts
|
|
1337
|
+
var createGameUseCase = (deps) => (mode) => {
|
|
1338
|
+
const { modeRepository, dominoesRepository, uuidMethod: uuidMethod2 } = deps;
|
|
1339
|
+
const id = uuidMethod2();
|
|
1340
|
+
const availableMode = modeRepository.getAvailables();
|
|
1341
|
+
const newMode = createMode(mode, availableMode);
|
|
1342
|
+
if (isErr(newMode)) {
|
|
1343
|
+
return newMode;
|
|
1344
|
+
}
|
|
1345
|
+
const dominoes = dominoesRepository.getForMode(newMode.value);
|
|
1346
|
+
if (!dominoes || dominoes.length === 0) {
|
|
1347
|
+
return err(`No dominoes found for mode ${newMode.value.name}`);
|
|
1348
|
+
}
|
|
1349
|
+
const payload = {
|
|
1350
|
+
id,
|
|
1351
|
+
mode: newMode.value,
|
|
1352
|
+
dominoes
|
|
1092
1353
|
};
|
|
1354
|
+
const newGame = create(payload);
|
|
1355
|
+
return ok(newGame);
|
|
1093
1356
|
};
|
|
1094
1357
|
|
|
1095
|
-
// src/
|
|
1096
|
-
var
|
|
1097
|
-
const
|
|
1098
|
-
const
|
|
1099
|
-
|
|
1358
|
+
// src/core/useCases/discardDomino.ts
|
|
1359
|
+
var discardDominoUseCase = (game, lordId) => {
|
|
1360
|
+
const nextAction = game.nextAction;
|
|
1361
|
+
const currentLord = game.lords.find(
|
|
1362
|
+
(lord) => lord.id === nextAction.nextLord
|
|
1363
|
+
);
|
|
1100
1364
|
if (!currentLord) {
|
|
1101
|
-
|
|
1365
|
+
return err("Lord not found");
|
|
1102
1366
|
}
|
|
1103
|
-
currentLord.
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1367
|
+
if (currentLord.id !== lordId) {
|
|
1368
|
+
return err("Not your turn");
|
|
1369
|
+
}
|
|
1370
|
+
if (!canPass(currentLord)) {
|
|
1371
|
+
return err("Lord can't pass");
|
|
1372
|
+
}
|
|
1373
|
+
const maxTurns = game.rules.basic.maxTurns;
|
|
1374
|
+
const currentTurn = game.turn;
|
|
1375
|
+
const isLastTurn = currentTurn === maxTurns;
|
|
1376
|
+
const updatedLord = game.lords.map((lord) => {
|
|
1377
|
+
if (lord.id === currentLord.id) {
|
|
1378
|
+
if (isLastTurn) {
|
|
1379
|
+
return {
|
|
1380
|
+
...lord,
|
|
1381
|
+
turnEnded: true,
|
|
1382
|
+
hasPlace: true
|
|
1383
|
+
};
|
|
1109
1384
|
}
|
|
1110
|
-
return
|
|
1111
|
-
|
|
1385
|
+
return {
|
|
1386
|
+
...lord,
|
|
1387
|
+
hasPlace: true
|
|
1388
|
+
};
|
|
1389
|
+
}
|
|
1390
|
+
return lord;
|
|
1391
|
+
});
|
|
1392
|
+
let updatedGame;
|
|
1393
|
+
const resultStep = {
|
|
1394
|
+
type: "step",
|
|
1395
|
+
step: gameSteps.result
|
|
1112
1396
|
};
|
|
1113
|
-
|
|
1397
|
+
if (isLastTurn && allLordsHavePlayed(updatedLord)) {
|
|
1398
|
+
updatedGame = {
|
|
1399
|
+
...game,
|
|
1400
|
+
lords: updatedLord,
|
|
1401
|
+
nextAction: resultStep
|
|
1402
|
+
};
|
|
1403
|
+
} else {
|
|
1404
|
+
updatedGame = {
|
|
1405
|
+
...game,
|
|
1406
|
+
lords: updatedLord,
|
|
1407
|
+
nextAction: nextLordWithAction(updatedLord)
|
|
1408
|
+
};
|
|
1409
|
+
}
|
|
1410
|
+
return ok(updatedGame);
|
|
1114
1411
|
};
|
|
1115
1412
|
|
|
1116
|
-
// src/
|
|
1117
|
-
var
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
pick,
|
|
1123
|
-
place,
|
|
1124
|
-
pass,
|
|
1125
|
-
definePlayerOrder,
|
|
1126
|
-
draw,
|
|
1127
|
-
calculateScore
|
|
1128
|
-
};
|
|
1129
|
-
};
|
|
1130
|
-
var isLordTurn = (state, lordId) => {
|
|
1131
|
-
const { lords, currentDominoes } = state;
|
|
1132
|
-
const currentLordOrder = lords.find((lord) => lord.id === lordId)?.order;
|
|
1133
|
-
const pickedDominoes = currentDominoes.filter(
|
|
1134
|
-
(currentDomino) => currentDomino.picked
|
|
1135
|
-
);
|
|
1136
|
-
if (currentLordOrder !== pickedDominoes.length + 1) {
|
|
1137
|
-
return false;
|
|
1413
|
+
// src/core/useCases/getExtraRules.ts
|
|
1414
|
+
var getExtraRulesUseCase = (deps) => (mode, players) => {
|
|
1415
|
+
const { ruleRepository } = deps;
|
|
1416
|
+
const allExtraRules = ruleRepository.getAllExtra();
|
|
1417
|
+
if (!allExtraRules) {
|
|
1418
|
+
return err("No rules found");
|
|
1138
1419
|
}
|
|
1139
|
-
return
|
|
1420
|
+
return getAvailablesExtraRules(allExtraRules, mode, players);
|
|
1140
1421
|
};
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
);
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1422
|
+
|
|
1423
|
+
// src/core/useCases/getModes.ts
|
|
1424
|
+
var getModesUseCase = (deps) => () => {
|
|
1425
|
+
const { modeRepository } = deps;
|
|
1426
|
+
return ok(modeRepository.getAvailables());
|
|
1427
|
+
};
|
|
1428
|
+
|
|
1429
|
+
// src/core/useCases/getResult.ts
|
|
1430
|
+
var getResultUseCase = (game) => {
|
|
1431
|
+
const { players, rules } = game;
|
|
1432
|
+
const { basic, extra } = rules;
|
|
1433
|
+
const scores = players.map((player) => {
|
|
1434
|
+
const { kingdom } = player;
|
|
1435
|
+
const visited = kingdom.map((row) => row.map(() => false));
|
|
1436
|
+
const properties = [];
|
|
1437
|
+
const directions = [
|
|
1438
|
+
[-1, 0],
|
|
1439
|
+
[1, 0],
|
|
1440
|
+
[0, -1],
|
|
1441
|
+
[0, 1]
|
|
1442
|
+
];
|
|
1443
|
+
const markZone = (x, y, type, crowns) => {
|
|
1444
|
+
if (x < 0 || y < 0 || x >= kingdom[0].length || y >= kingdom.length || visited[y][x] || kingdom[y][x].type !== type || kingdom[y][x].type === "empty" || kingdom[y][x].type === "castle") {
|
|
1445
|
+
return;
|
|
1446
|
+
}
|
|
1447
|
+
visited[y][x] = true;
|
|
1448
|
+
const currentZone = properties.find(
|
|
1449
|
+
(property) => property.type === type && property.tiles.some(([tx, ty]) => {
|
|
1450
|
+
for (let [dx, dy] of directions) {
|
|
1451
|
+
if (tx + dx === x && ty + dy === y) {
|
|
1452
|
+
return true;
|
|
1453
|
+
}
|
|
1454
|
+
}
|
|
1455
|
+
return false;
|
|
1456
|
+
})
|
|
1457
|
+
);
|
|
1458
|
+
if (currentZone) {
|
|
1459
|
+
currentZone.size += 1;
|
|
1460
|
+
currentZone.tiles.push([x, y]);
|
|
1461
|
+
currentZone.crowns += crowns;
|
|
1462
|
+
} else {
|
|
1463
|
+
properties.push({
|
|
1464
|
+
type,
|
|
1465
|
+
crowns,
|
|
1466
|
+
size: 1,
|
|
1467
|
+
tiles: [[x, y]]
|
|
1468
|
+
});
|
|
1469
|
+
}
|
|
1470
|
+
directions.forEach(([dx, dy]) => {
|
|
1471
|
+
const nx = x + dx;
|
|
1472
|
+
const ny = y + dy;
|
|
1473
|
+
if (nx >= 0 && ny >= 0 && nx < kingdom[0].length && ny < kingdom.length && kingdom[ny][nx].type === type) {
|
|
1474
|
+
markZone(nx, ny, kingdom[ny][nx].type, kingdom[ny][nx].crowns);
|
|
1475
|
+
}
|
|
1476
|
+
});
|
|
1149
1477
|
};
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1478
|
+
kingdom.forEach((row, y) => {
|
|
1479
|
+
row.forEach((tile, x) => {
|
|
1480
|
+
if (!visited[y][x]) {
|
|
1481
|
+
markZone(x, y, tile.type, tile.crowns);
|
|
1482
|
+
}
|
|
1483
|
+
});
|
|
1484
|
+
});
|
|
1485
|
+
if (properties.length === 0) {
|
|
1486
|
+
return {
|
|
1487
|
+
playerId: player.id,
|
|
1488
|
+
playerName: player.name,
|
|
1489
|
+
details: {
|
|
1490
|
+
points: 0,
|
|
1491
|
+
maxPropertiesSize: 0,
|
|
1492
|
+
totalCrowns: 0
|
|
1493
|
+
}
|
|
1494
|
+
};
|
|
1495
|
+
}
|
|
1496
|
+
let points = properties.reduce(
|
|
1497
|
+
(score, property) => score + property.crowns * property.size,
|
|
1498
|
+
0
|
|
1499
|
+
);
|
|
1500
|
+
const maxPropertiesSize = Math.max(
|
|
1501
|
+
...properties.map((property) => property.size ?? 0)
|
|
1502
|
+
);
|
|
1503
|
+
const totalCrowns = properties.reduce(
|
|
1504
|
+
(total, property) => total + property.crowns,
|
|
1505
|
+
0
|
|
1506
|
+
);
|
|
1507
|
+
if (extra.length > 0) {
|
|
1508
|
+
extra.forEach((extraRule) => {
|
|
1509
|
+
if (extraRule.name === "The middle Kingdom") {
|
|
1510
|
+
const castleIsInMiddle = checkCastleIsInMiddle(kingdom);
|
|
1511
|
+
if (castleIsInMiddle) {
|
|
1512
|
+
points += 10;
|
|
1513
|
+
}
|
|
1514
|
+
}
|
|
1515
|
+
if (extraRule.name === "Harmony") {
|
|
1516
|
+
const totalDominoes = countDominoes(kingdom);
|
|
1517
|
+
const dominoLimit = basic.maxDominoes;
|
|
1518
|
+
const totalPlayers = players.length;
|
|
1519
|
+
const dominoesPerPlayer = dominoLimit / totalPlayers;
|
|
1520
|
+
if (totalDominoes === dominoesPerPlayer) {
|
|
1521
|
+
points += 5;
|
|
1522
|
+
}
|
|
1523
|
+
}
|
|
1524
|
+
});
|
|
1525
|
+
}
|
|
1526
|
+
return {
|
|
1527
|
+
playerId: player.id,
|
|
1528
|
+
playerName: player.name,
|
|
1529
|
+
details: {
|
|
1530
|
+
points,
|
|
1531
|
+
maxPropertiesSize,
|
|
1532
|
+
totalCrowns
|
|
1533
|
+
}
|
|
1155
1534
|
};
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
var rules = {
|
|
1161
|
-
2: {
|
|
1162
|
-
lords: 2,
|
|
1163
|
-
maxDominoes: 24,
|
|
1164
|
-
dominoesPerTurn: 4,
|
|
1165
|
-
maxTurns: 6
|
|
1166
|
-
},
|
|
1167
|
-
3: {
|
|
1168
|
-
lords: 1,
|
|
1169
|
-
maxDominoes: 36,
|
|
1170
|
-
dominoesPerTurn: 3,
|
|
1171
|
-
maxTurns: 12
|
|
1172
|
-
},
|
|
1173
|
-
4: {
|
|
1174
|
-
lords: 1,
|
|
1175
|
-
maxDominoes: 48,
|
|
1176
|
-
dominoesPerTurn: 4,
|
|
1177
|
-
maxTurns: 12
|
|
1178
|
-
}
|
|
1179
|
-
};
|
|
1180
|
-
var game_default = gameStep;
|
|
1181
|
-
|
|
1182
|
-
// src/hexagon/internal/services/result.ts
|
|
1183
|
-
var result = (scores) => {
|
|
1184
|
-
scores.sort((a, b) => {
|
|
1185
|
-
if (a.details.score !== b.details.score) {
|
|
1186
|
-
return b.details.score - a.details.score;
|
|
1535
|
+
});
|
|
1536
|
+
scores.sort((a2, b2) => {
|
|
1537
|
+
if (a2.details.points !== b2.details.points) {
|
|
1538
|
+
return b2.details.points - a2.details.points;
|
|
1187
1539
|
}
|
|
1188
|
-
if (
|
|
1189
|
-
return
|
|
1540
|
+
if (a2.details.maxPropertiesSize !== b2.details.maxPropertiesSize) {
|
|
1541
|
+
return b2.details.maxPropertiesSize - a2.details.maxPropertiesSize;
|
|
1190
1542
|
}
|
|
1191
|
-
return
|
|
1543
|
+
return b2.details.totalCrowns - a2.details.totalCrowns;
|
|
1192
1544
|
});
|
|
1193
|
-
const
|
|
1545
|
+
const result = [];
|
|
1194
1546
|
let isTie = false;
|
|
1195
|
-
|
|
1196
|
-
|
|
1547
|
+
result.push({
|
|
1548
|
+
playerId: scores[0].playerId,
|
|
1549
|
+
playerName: scores[0].playerName,
|
|
1550
|
+
details: scores[0].details,
|
|
1197
1551
|
position: 1
|
|
1198
1552
|
});
|
|
1199
|
-
for (let
|
|
1200
|
-
const currentScore = scores[
|
|
1201
|
-
const previousScore = scores[
|
|
1202
|
-
if (previousScore && currentScore && currentScore.details.
|
|
1553
|
+
for (let i2 = 1; i2 < scores.length; i2++) {
|
|
1554
|
+
const currentScore = scores[i2];
|
|
1555
|
+
const previousScore = scores[i2 - 1];
|
|
1556
|
+
if (previousScore && currentScore && currentScore.details.points === previousScore.details.points && currentScore.details.maxPropertiesSize === previousScore.details.maxPropertiesSize && currentScore.details.totalCrowns === previousScore.details.totalCrowns) {
|
|
1203
1557
|
isTie = true;
|
|
1204
1558
|
}
|
|
1205
1559
|
if (isTie) {
|
|
1206
|
-
|
|
1560
|
+
result.push({
|
|
1207
1561
|
...currentScore,
|
|
1208
|
-
position:
|
|
1562
|
+
position: result[i2 - 1].position
|
|
1209
1563
|
});
|
|
1210
1564
|
} else {
|
|
1211
|
-
|
|
1565
|
+
result.push({
|
|
1212
1566
|
...currentScore,
|
|
1213
|
-
position:
|
|
1567
|
+
position: i2 + 1
|
|
1214
1568
|
});
|
|
1215
1569
|
}
|
|
1216
1570
|
isTie = false;
|
|
1217
1571
|
}
|
|
1218
|
-
return
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
var availableMode = ["Classic"];
|
|
1223
|
-
|
|
1224
|
-
// src/adapters/driven/uuid.ts
|
|
1225
|
-
import { randomUUID } from "crypto";
|
|
1226
|
-
var uuidMethod = () => {
|
|
1227
|
-
return randomUUID();
|
|
1572
|
+
return ok({
|
|
1573
|
+
...game,
|
|
1574
|
+
result
|
|
1575
|
+
});
|
|
1228
1576
|
};
|
|
1229
1577
|
|
|
1230
|
-
// src/
|
|
1231
|
-
var
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1578
|
+
// src/core/useCases/placeDomino.ts
|
|
1579
|
+
var placeDominoUseCase = (game, lordId, position, orientation, rotation) => {
|
|
1580
|
+
const nextAction = game.nextAction;
|
|
1581
|
+
const currentLord = game.lords.find(
|
|
1582
|
+
(lord) => lord.id === nextAction.nextLord
|
|
1583
|
+
);
|
|
1584
|
+
if (!currentLord) {
|
|
1585
|
+
return err("Lord not found");
|
|
1235
1586
|
}
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
// src/adapters/driver/index.ts
|
|
1240
|
-
var gameEngine = () => {
|
|
1241
|
-
let dependencies;
|
|
1242
|
-
try {
|
|
1243
|
-
loadEnvFile();
|
|
1244
|
-
} catch (error) {
|
|
1245
|
-
console.log("No .env file found. Using default configuration.");
|
|
1246
|
-
}
|
|
1247
|
-
if (process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") {
|
|
1248
|
-
console.log("Game engine is running in development mode");
|
|
1249
|
-
dependencies = {
|
|
1250
|
-
dominoesRepository: inMemoryDominoes_default(),
|
|
1251
|
-
uuidMethod: () => `uuid-${Math.random()}`,
|
|
1252
|
-
shuffleMethod: (array) => array
|
|
1253
|
-
};
|
|
1254
|
-
} else {
|
|
1255
|
-
console.log("Game engine is running in production mode");
|
|
1256
|
-
dependencies = {
|
|
1257
|
-
dominoesRepository: inMemoryDominoes_default(),
|
|
1258
|
-
uuidMethod,
|
|
1259
|
-
shuffleMethod
|
|
1260
|
-
};
|
|
1587
|
+
if (currentLord.id !== lordId) {
|
|
1588
|
+
return err("Not your turn");
|
|
1261
1589
|
}
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
return
|
|
1281
|
-
}
|
|
1282
|
-
const
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
const start = (game, players) => {
|
|
1286
|
-
const setupState = setup2({
|
|
1287
|
-
state: game,
|
|
1288
|
-
players
|
|
1289
|
-
});
|
|
1290
|
-
const drawState = draw2({ state: setupState });
|
|
1291
|
-
return {
|
|
1292
|
-
nextLord: drawState.lords[0].id,
|
|
1293
|
-
nextAction: "pick",
|
|
1294
|
-
game: drawState
|
|
1295
|
-
};
|
|
1296
|
-
};
|
|
1297
|
-
const passTurn = (game, lordId) => {
|
|
1298
|
-
const updatedGame = pass2({
|
|
1299
|
-
lordId,
|
|
1300
|
-
action: "pass",
|
|
1301
|
-
data: {
|
|
1302
|
-
state: game
|
|
1303
|
-
}
|
|
1304
|
-
});
|
|
1305
|
-
const resp = defineNextAction(updatedGame, "pass", lordId);
|
|
1306
|
-
return resp;
|
|
1307
|
-
};
|
|
1308
|
-
const placeDomino2 = (game, lordId, position, orientation, rotation) => {
|
|
1309
|
-
const updatedGame = place2({
|
|
1310
|
-
lordId,
|
|
1311
|
-
action: "place",
|
|
1312
|
-
data: {
|
|
1313
|
-
state: game,
|
|
1314
|
-
position,
|
|
1315
|
-
orientation,
|
|
1316
|
-
rotation
|
|
1317
|
-
}
|
|
1318
|
-
});
|
|
1319
|
-
const resp = defineNextAction(updatedGame, "place", lordId);
|
|
1320
|
-
return resp;
|
|
1321
|
-
};
|
|
1322
|
-
const pickDomino = (game, lordId, dominoPick) => {
|
|
1323
|
-
const updatedGame = pick2({
|
|
1324
|
-
lordId,
|
|
1325
|
-
action: "pick",
|
|
1326
|
-
data: {
|
|
1327
|
-
state: game,
|
|
1328
|
-
dominoPick
|
|
1329
|
-
}
|
|
1330
|
-
});
|
|
1331
|
-
const resp = defineNextAction(updatedGame, "pick", lordId);
|
|
1332
|
-
return resp;
|
|
1333
|
-
};
|
|
1334
|
-
const prepareNextTurn = (game) => {
|
|
1335
|
-
const updatedOrder = definePlayerOrder2({ state: game });
|
|
1336
|
-
const updateDraw = draw2({ state: updatedOrder });
|
|
1337
|
-
const updateTurn = startTurn2({ state: updateDraw });
|
|
1338
|
-
if (updateTurn.game.turn > updateTurn.game.maxTurns) {
|
|
1339
|
-
throw new Error("Game is over");
|
|
1590
|
+
if (!canPlaceAndDominoPickedIsDefined(currentLord)) {
|
|
1591
|
+
return err("Lord can't place");
|
|
1592
|
+
}
|
|
1593
|
+
const domino = currentLord.dominoPicked;
|
|
1594
|
+
const currentPlayer = game.players.find(
|
|
1595
|
+
(player) => player.id === currentLord.playerId
|
|
1596
|
+
);
|
|
1597
|
+
if (!currentPlayer) {
|
|
1598
|
+
return err("Player not found");
|
|
1599
|
+
}
|
|
1600
|
+
const updatedKingdom = placeDomino(
|
|
1601
|
+
currentPlayer.kingdom,
|
|
1602
|
+
position,
|
|
1603
|
+
orientation,
|
|
1604
|
+
rotation,
|
|
1605
|
+
domino
|
|
1606
|
+
);
|
|
1607
|
+
if (isErr(updatedKingdom)) {
|
|
1608
|
+
return updatedKingdom;
|
|
1609
|
+
}
|
|
1610
|
+
const updatedPlayers = game.players.map((player) => {
|
|
1611
|
+
if (player.id === currentPlayer.id) {
|
|
1612
|
+
player.kingdom = updatedKingdom.value;
|
|
1340
1613
|
}
|
|
1341
|
-
return
|
|
1342
|
-
};
|
|
1343
|
-
const
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1614
|
+
return player;
|
|
1615
|
+
});
|
|
1616
|
+
const maxTurns = game.rules.basic.maxTurns;
|
|
1617
|
+
const currentTurn = game.turn;
|
|
1618
|
+
const isLastTurn = currentTurn === maxTurns;
|
|
1619
|
+
const updatedLords = game.lords.map((lord) => {
|
|
1620
|
+
if (lord.id === currentLord.id) {
|
|
1621
|
+
if (isLastTurn) {
|
|
1349
1622
|
return {
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1623
|
+
...lord,
|
|
1624
|
+
turnEnded: true,
|
|
1625
|
+
hasPlace: true
|
|
1353
1626
|
};
|
|
1354
1627
|
}
|
|
1355
1628
|
return {
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
game
|
|
1629
|
+
...lord,
|
|
1630
|
+
hasPlace: true
|
|
1359
1631
|
};
|
|
1360
1632
|
}
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1633
|
+
return lord;
|
|
1634
|
+
});
|
|
1635
|
+
let updatedGame;
|
|
1636
|
+
const resultStep = {
|
|
1637
|
+
type: "step",
|
|
1638
|
+
step: gameSteps.result
|
|
1639
|
+
};
|
|
1640
|
+
if (isLastTurn && allLordsHavePlayed(updatedLords)) {
|
|
1641
|
+
updatedGame = {
|
|
1642
|
+
...game,
|
|
1643
|
+
lords: updatedLords,
|
|
1644
|
+
nextAction: resultStep
|
|
1645
|
+
};
|
|
1646
|
+
} else {
|
|
1647
|
+
updatedGame = {
|
|
1648
|
+
...game,
|
|
1649
|
+
lords: updatedLords,
|
|
1650
|
+
nextAction: nextLordWithAction(updatedLords)
|
|
1651
|
+
};
|
|
1652
|
+
}
|
|
1653
|
+
return ok(updatedGame);
|
|
1654
|
+
};
|
|
1655
|
+
|
|
1656
|
+
// src/core/useCases/startGame.ts
|
|
1657
|
+
var startGameUseCase = (deps) => (game) => {
|
|
1658
|
+
const { uuidMethod: uuidMethod2, shuffleMethod: shuffleMethod2 } = deps;
|
|
1659
|
+
const {
|
|
1660
|
+
rules: {
|
|
1661
|
+
basic: { lords: maxLords, dominoesPerTurn }
|
|
1662
|
+
},
|
|
1663
|
+
players,
|
|
1664
|
+
dominoes
|
|
1665
|
+
} = game;
|
|
1666
|
+
const numberOfPlayers = players.length;
|
|
1667
|
+
const newLords = [];
|
|
1668
|
+
for (let i2 = 0; i2 < numberOfPlayers; i2++) {
|
|
1669
|
+
for (let j = 0; j < maxLords; j++) {
|
|
1670
|
+
const lord = createLord(uuidMethod2(), players[i2].id);
|
|
1671
|
+
newLords.push(lord);
|
|
1382
1672
|
}
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1673
|
+
}
|
|
1674
|
+
const shuffledLords = shuffleMethod2(newLords);
|
|
1675
|
+
const dominoesCopy = [...dominoes];
|
|
1676
|
+
const dominoesDrawn = dominoesCopy.splice(0, dominoesPerTurn);
|
|
1677
|
+
dominoesDrawn.sort((a2, b2) => a2.number - b2.number);
|
|
1678
|
+
const nextAction = {
|
|
1679
|
+
type: "action",
|
|
1680
|
+
nextLord: shuffledLords[0].id,
|
|
1681
|
+
nextAction: playerActions.pickDomino
|
|
1682
|
+
};
|
|
1683
|
+
const newState = {
|
|
1684
|
+
...game,
|
|
1685
|
+
lords: shuffledLords,
|
|
1686
|
+
nextAction,
|
|
1687
|
+
dominoes: dominoesCopy,
|
|
1688
|
+
currentDominoes: dominoesDrawn.map((domino, index) => {
|
|
1386
1689
|
return {
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1690
|
+
domino,
|
|
1691
|
+
picked: false,
|
|
1692
|
+
lordId: null,
|
|
1693
|
+
position: index + 1
|
|
1390
1694
|
};
|
|
1391
|
-
}
|
|
1392
|
-
const nextLord = lords.find((lord) => !lord.hasPlace);
|
|
1393
|
-
return {
|
|
1394
|
-
nextLord: nextLord.id,
|
|
1395
|
-
nextAction: "place",
|
|
1396
|
-
game
|
|
1397
|
-
};
|
|
1398
|
-
};
|
|
1399
|
-
const endGame = (game) => {
|
|
1400
|
-
const players = game.players;
|
|
1401
|
-
const scores = [];
|
|
1402
|
-
for (let player of players) {
|
|
1403
|
-
const score = calculateScore2(player.kingdom);
|
|
1404
|
-
scores.push({
|
|
1405
|
-
playerId: player.id,
|
|
1406
|
-
playerName: player.name,
|
|
1407
|
-
details: score
|
|
1408
|
-
});
|
|
1409
|
-
}
|
|
1410
|
-
const finalResult = result(scores);
|
|
1411
|
-
return {
|
|
1412
|
-
result: finalResult,
|
|
1413
|
-
game
|
|
1414
|
-
};
|
|
1695
|
+
})
|
|
1415
1696
|
};
|
|
1697
|
+
return ok(newState);
|
|
1698
|
+
};
|
|
1699
|
+
|
|
1700
|
+
// src/adapterServerside/shuffle.ts
|
|
1701
|
+
var shuffleMethod = (array) => {
|
|
1702
|
+
for (let i2 = array.length - 1; i2 > 0; i2--) {
|
|
1703
|
+
const j = Math.floor(Math.random() * (i2 + 1));
|
|
1704
|
+
[array[i2], array[j]] = [array[j], array[i2]];
|
|
1705
|
+
}
|
|
1706
|
+
return array;
|
|
1707
|
+
};
|
|
1708
|
+
|
|
1709
|
+
// src/adapterServerside/uuid.ts
|
|
1710
|
+
import { randomUUID } from "crypto";
|
|
1711
|
+
var uuidMethod = () => {
|
|
1712
|
+
return randomUUID();
|
|
1713
|
+
};
|
|
1714
|
+
|
|
1715
|
+
// src/config.ts
|
|
1716
|
+
var configureEngine = (config) => {
|
|
1717
|
+
const modeRepository = config.modeRepository || jsonModes_default();
|
|
1718
|
+
const dominoesRepository = config.dominoesRepository || jsonDominoes_default();
|
|
1719
|
+
const ruleRepository = config.ruleRepository || jsonRules_default();
|
|
1720
|
+
const uuid = config.uuidMethod || uuidMethod;
|
|
1721
|
+
const shuffle = config.shuffleMethod || shuffleMethod;
|
|
1416
1722
|
return {
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1723
|
+
createGameHandler: createGameHandler(
|
|
1724
|
+
createGameUseCase({
|
|
1725
|
+
modeRepository,
|
|
1726
|
+
dominoesRepository,
|
|
1727
|
+
uuidMethod: uuid
|
|
1728
|
+
})
|
|
1729
|
+
),
|
|
1730
|
+
getModesHandler: getModesHandler(getModesUseCase({ modeRepository })),
|
|
1731
|
+
getExtraRulesHandler: getExtraRulesHandler(
|
|
1732
|
+
getExtraRulesUseCase({ ruleRepository })
|
|
1733
|
+
),
|
|
1734
|
+
addPlayersHandler: addPlayersHandler(
|
|
1735
|
+
addPlayersUseCase({
|
|
1736
|
+
uuidMethod: uuid,
|
|
1737
|
+
shuffleMethod: shuffle,
|
|
1738
|
+
ruleRepository
|
|
1739
|
+
})
|
|
1740
|
+
),
|
|
1741
|
+
addExtraRulesHandler: addExtraRulesHandler(
|
|
1742
|
+
addExtraRulesUseCase({ ruleRepository })
|
|
1743
|
+
),
|
|
1744
|
+
startGameHandler: startGameHandler(
|
|
1745
|
+
startGameUseCase({ uuidMethod: uuid, shuffleMethod: shuffle })
|
|
1746
|
+
),
|
|
1747
|
+
chooseDominoHandler: chooseDominoHandler(chooseDominoUseCase),
|
|
1748
|
+
placeDominoHandler: placeDominoHandler(placeDominoUseCase),
|
|
1749
|
+
discardDominoHandler: discardDominoHandler(discardDominoUseCase),
|
|
1750
|
+
getResultHandler: getResultHandler(getResultUseCase)
|
|
1427
1751
|
};
|
|
1428
1752
|
};
|
|
1429
|
-
var driver_default = gameEngine;
|
|
1430
1753
|
|
|
1431
1754
|
// src/index.ts
|
|
1432
|
-
var
|
|
1755
|
+
var createGameEngine = (config) => {
|
|
1756
|
+
const {
|
|
1757
|
+
createGameHandler: createGameHandler2,
|
|
1758
|
+
getModesHandler: getModesHandler2,
|
|
1759
|
+
getExtraRulesHandler: getExtraRulesHandler2,
|
|
1760
|
+
addPlayersHandler: addPlayersHandler2,
|
|
1761
|
+
addExtraRulesHandler: addExtraRulesHandler2,
|
|
1762
|
+
startGameHandler: startGameHandler2,
|
|
1763
|
+
chooseDominoHandler: chooseDominoHandler2,
|
|
1764
|
+
placeDominoHandler: placeDominoHandler2,
|
|
1765
|
+
discardDominoHandler: discardDominoHandler2,
|
|
1766
|
+
getResultHandler: getResultHandler2
|
|
1767
|
+
} = configureEngine(config);
|
|
1768
|
+
return {
|
|
1769
|
+
getModes: (command) => getModesHandler2(command),
|
|
1770
|
+
getExtraRules: (command) => getExtraRulesHandler2(command),
|
|
1771
|
+
createGame: (command) => createGameHandler2(command),
|
|
1772
|
+
addPlayers: (command) => addPlayersHandler2(command),
|
|
1773
|
+
addExtraRules: (command) => addExtraRulesHandler2(command),
|
|
1774
|
+
startGame: (command) => startGameHandler2(command),
|
|
1775
|
+
chooseDomino: (command) => chooseDominoHandler2(command),
|
|
1776
|
+
placeDomino: (command) => placeDominoHandler2(command),
|
|
1777
|
+
discardDomino: (command) => discardDominoHandler2(command),
|
|
1778
|
+
getResults: (command) => getResultHandler2(command)
|
|
1779
|
+
};
|
|
1780
|
+
};
|
|
1781
|
+
var engine = createGameEngine({});
|
|
1782
|
+
var a = engine.createGame({ mode: "standard" });
|
|
1783
|
+
var b = engine.getModes({});
|
|
1784
|
+
var c = engine.getExtraRules({ mode: "standard", players: 2 });
|
|
1785
|
+
var d = engine.addPlayers({ game: a, players: ["player1"] });
|
|
1786
|
+
var e = engine.addExtraRules({ game: d, extraRules: ["rule1"] });
|
|
1787
|
+
var f = engine.startGame({ game: e });
|
|
1788
|
+
var g = engine.chooseDomino({
|
|
1789
|
+
game: f,
|
|
1790
|
+
lordId: "player1",
|
|
1791
|
+
dominoPick: 1
|
|
1792
|
+
});
|
|
1793
|
+
var h = engine.discardDomino({ game: g, lordId: "player1" });
|
|
1794
|
+
var i = engine.placeDomino({
|
|
1795
|
+
game: g,
|
|
1796
|
+
lordId: "player1",
|
|
1797
|
+
position: { x: 1, y: 1 },
|
|
1798
|
+
orientation: "horizontal",
|
|
1799
|
+
rotation: 0
|
|
1800
|
+
});
|
|
1801
|
+
if (isGameWithNextAction(i)) {
|
|
1802
|
+
const j = engine.chooseDomino({
|
|
1803
|
+
game: i,
|
|
1804
|
+
lordId: "player1",
|
|
1805
|
+
dominoPick: 1
|
|
1806
|
+
});
|
|
1807
|
+
}
|
|
1808
|
+
if (!isGameWithNextAction(i)) {
|
|
1809
|
+
const j = engine.getResults({ game: i });
|
|
1810
|
+
}
|
|
1433
1811
|
export {
|
|
1434
|
-
|
|
1812
|
+
createGameEngine
|
|
1435
1813
|
};
|
|
1436
1814
|
//# sourceMappingURL=index.js.map
|