@gamepark/zenith 1.0.4 → 1.0.8
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/ZenithOptions.d.ts +0 -1
- package/dist/ZenithOptions.d.ts.map +1 -1
- package/dist/ZenithOptions.js.map +1 -1
- package/dist/ZenithSetup.d.ts +1 -1
- package/dist/ZenithSetup.d.ts.map +1 -1
- package/dist/ZenithSetup.js +9 -13
- package/dist/ZenithSetup.js.map +1 -1
- package/dist/material/Agents.js +1 -1
- package/dist/material/Agents.js.map +1 -1
- package/dist/rules/effect/AgentEffects.spec.js +99 -184
- package/dist/rules/effect/AgentEffects.spec.js.map +1 -1
- package/dist/rules/effect/DevelopTechnologyRule.js +2 -2
- package/dist/rules/effect/DevelopTechnologyRule.js.map +1 -1
- package/dist/rules/effect/EffectEdgeCases.spec.js +80 -129
- package/dist/rules/effect/EffectEdgeCases.spec.js.map +1 -1
- package/dist/rules/effect/GiveInfluenceRule.d.ts +1 -0
- package/dist/rules/effect/GiveInfluenceRule.d.ts.map +1 -1
- package/dist/rules/effect/GiveInfluenceRule.js +8 -0
- package/dist/rules/effect/GiveInfluenceRule.js.map +1 -1
- package/dist/tutorial/TutorialSetup.spec.js +47 -37
- package/dist/tutorial/TutorialSetup.spec.js.map +1 -1
- package/package.json +2 -2
|
@@ -90,7 +90,7 @@ class EffectTestSetup extends ZenithSetup {
|
|
|
90
90
|
this.setupInfluenceCards();
|
|
91
91
|
this.setupTeams();
|
|
92
92
|
this.setupLeaderBadge();
|
|
93
|
-
this.setupTechnologyBoard({ animodBoard: 'S', humanBoard: 'U', robotBoard: 'N',
|
|
93
|
+
this.setupTechnologyBoard({ animodBoard: 'S', humanBoard: 'U', robotBoard: 'N', players: [] });
|
|
94
94
|
this.setupTestBonuses();
|
|
95
95
|
}
|
|
96
96
|
setupTurnOrder() {
|
|
@@ -101,14 +101,16 @@ class EffectTestSetup extends ZenithSetup {
|
|
|
101
101
|
id: this.testAgent,
|
|
102
102
|
location: { type: LocationType.PlayerHand, player: player1 }
|
|
103
103
|
});
|
|
104
|
-
const fillers = agents.filter(a => a !== this.testAgent && !this.opponentInfluenceCards.includes(a) && !this.playerInfluenceCards.includes(a)).slice(0, 3);
|
|
104
|
+
const fillers = agents.filter((a) => a !== this.testAgent && !this.opponentInfluenceCards.includes(a) && !this.playerInfluenceCards.includes(a)).slice(0, 3);
|
|
105
105
|
for (const agent of fillers) {
|
|
106
106
|
this.material(MaterialType.AgentCard).createItem({
|
|
107
107
|
id: agent,
|
|
108
108
|
location: { type: LocationType.PlayerHand, player: player1 }
|
|
109
109
|
});
|
|
110
110
|
}
|
|
111
|
-
const p2Fillers = agents
|
|
111
|
+
const p2Fillers = agents
|
|
112
|
+
.filter((a) => a !== this.testAgent && !fillers.includes(a) && !this.opponentInfluenceCards.includes(a) && !this.playerInfluenceCards.includes(a))
|
|
113
|
+
.slice(0, 4);
|
|
112
114
|
for (const agent of p2Fillers) {
|
|
113
115
|
this.material(MaterialType.AgentCard).createItem({
|
|
114
116
|
id: agent,
|
|
@@ -121,9 +123,9 @@ class EffectTestSetup extends ZenithSetup {
|
|
|
121
123
|
this.testAgent,
|
|
122
124
|
...this.opponentInfluenceCards,
|
|
123
125
|
...this.playerInfluenceCards,
|
|
124
|
-
...agents.filter(a => a !== this.testAgent && !this.opponentInfluenceCards.includes(a) && !this.playerInfluenceCards.includes(a)).slice(0, 7)
|
|
126
|
+
...agents.filter((a) => a !== this.testAgent && !this.opponentInfluenceCards.includes(a) && !this.playerInfluenceCards.includes(a)).slice(0, 7)
|
|
125
127
|
]);
|
|
126
|
-
const remaining = agents.filter(a => !usedAgents.has(a));
|
|
128
|
+
const remaining = agents.filter((a) => !usedAgents.has(a));
|
|
127
129
|
let idx = 0;
|
|
128
130
|
for (let i = 0; i < this.deckCount && idx < remaining.length; i++, idx++) {
|
|
129
131
|
this.material(MaterialType.AgentCard).createItem({
|
|
@@ -218,7 +220,7 @@ class EffectTestSetup extends ZenithSetup {
|
|
|
218
220
|
}
|
|
219
221
|
}
|
|
220
222
|
function setupEffects(rules, effects) {
|
|
221
|
-
const expandedEffects = effects.map(e => ({
|
|
223
|
+
const expandedEffects = effects.map((e) => ({
|
|
222
224
|
...e,
|
|
223
225
|
effectSource: { type: MaterialType.AgentCard, value: Agent.Elisabeth }
|
|
224
226
|
}));
|
|
@@ -226,45 +228,40 @@ function setupEffects(rules, effects) {
|
|
|
226
228
|
}
|
|
227
229
|
function createRulesWithEffects(opts, effects) {
|
|
228
230
|
const setup = new EffectTestSetup(opts);
|
|
229
|
-
const game = setup.setup({ players: [{}, {}], animodBoard: 'S', humanBoard: 'U', robotBoard: 'N'
|
|
231
|
+
const game = setup.setup({ players: [{}, {}], animodBoard: 'S', humanBoard: 'U', robotBoard: 'N' });
|
|
230
232
|
const rules = new ZenithRules(game);
|
|
231
233
|
setupEffects(rules, effects);
|
|
232
234
|
return rules;
|
|
233
235
|
}
|
|
234
236
|
describe('WinInfluence edge cases', () => {
|
|
235
237
|
it('opponentSide with no planets on opponent side should skip effect', () => {
|
|
236
|
-
const rules = createRulesWithEffects({}, [
|
|
237
|
-
{ type: EffectType.WinInfluence, quantity: 1, opponentSide: true }
|
|
238
|
-
]);
|
|
238
|
+
const rules = createRulesWithEffects({}, [{ type: EffectType.WinInfluence, quantity: 1, opponentSide: true }]);
|
|
239
239
|
playConsequences(rules, { type: 'rule', id: RuleId.WinInfluence });
|
|
240
240
|
const result = resolveAllEffects(rules, player1);
|
|
241
241
|
expect(result.error).toBeUndefined();
|
|
242
242
|
});
|
|
243
243
|
it('differentPlanet with only 1 planet remaining should skip after first pull', () => {
|
|
244
|
-
const rules = createRulesWithEffects({}, [
|
|
245
|
-
{ type: EffectType.WinInfluence, quantity: 1, differentPlanet: true, resetDifferentPlanet: true }
|
|
246
|
-
]);
|
|
244
|
+
const rules = createRulesWithEffects({}, [{ type: EffectType.WinInfluence, quantity: 1, differentPlanet: true, resetDifferentPlanet: true }]);
|
|
247
245
|
const result = resolveAllEffects(rules, player1);
|
|
248
246
|
expect(result.error).toBeUndefined();
|
|
249
247
|
});
|
|
250
248
|
it('fromCenter with no planets at center should skip', () => {
|
|
251
249
|
const rules = createRulesWithEffects({
|
|
252
250
|
planetPositions: {
|
|
253
|
-
[Influence.Mercury]: 2,
|
|
254
|
-
[Influence.
|
|
251
|
+
[Influence.Mercury]: 2,
|
|
252
|
+
[Influence.Venus]: 2,
|
|
253
|
+
[Influence.Terra]: 2,
|
|
254
|
+
[Influence.Mars]: 2,
|
|
255
|
+
[Influence.Jupiter]: 2
|
|
255
256
|
}
|
|
256
|
-
}, [
|
|
257
|
-
{ type: EffectType.WinInfluence, quantity: 1, fromCenter: true }
|
|
258
|
-
]);
|
|
257
|
+
}, [{ type: EffectType.WinInfluence, quantity: 1, fromCenter: true }]);
|
|
259
258
|
const result = resolveAllEffects(rules, player1);
|
|
260
259
|
expect(result.error).toBeUndefined();
|
|
261
260
|
});
|
|
262
261
|
it('planet already at max position (x=4 for White) should still trigger capture', () => {
|
|
263
262
|
const rules = createRulesWithEffects({
|
|
264
263
|
planetPositions: { [Influence.Mars]: 3 }
|
|
265
|
-
}, [
|
|
266
|
-
{ type: EffectType.WinInfluence, influence: Influence.Mars, quantity: 1 }
|
|
267
|
-
]);
|
|
264
|
+
}, [{ type: EffectType.WinInfluence, influence: Influence.Mars, quantity: 1 }]);
|
|
268
265
|
playConsequences(rules, rules.play({ type: 'rule', id: RuleId.WinInfluence })[0] ?? { type: 'rule', id: RuleId.WinInfluence });
|
|
269
266
|
resolveAutoMoves(rules);
|
|
270
267
|
const result = resolveAllEffects(rules, player1);
|
|
@@ -275,93 +272,76 @@ describe('GiveInfluence edge cases', () => {
|
|
|
275
272
|
it('all planets at boundary (x=-4 for White push) should skip', () => {
|
|
276
273
|
const rules = createRulesWithEffects({
|
|
277
274
|
planetPositions: {
|
|
278
|
-
[Influence.Mercury]: -4,
|
|
279
|
-
[Influence.
|
|
275
|
+
[Influence.Mercury]: -4,
|
|
276
|
+
[Influence.Venus]: -4,
|
|
277
|
+
[Influence.Terra]: -4,
|
|
278
|
+
[Influence.Mars]: -4,
|
|
279
|
+
[Influence.Jupiter]: -4
|
|
280
280
|
}
|
|
281
|
-
}, [
|
|
282
|
-
{ type: EffectType.GiveInfluence }
|
|
283
|
-
]);
|
|
281
|
+
}, [{ type: EffectType.GiveInfluence }]);
|
|
284
282
|
const result = resolveAllEffects(rules, player1);
|
|
285
283
|
expect(result.error).toBeUndefined();
|
|
286
284
|
});
|
|
287
285
|
it('push planet to -4 should capture for opponent', () => {
|
|
288
286
|
const rules = createRulesWithEffects({
|
|
289
287
|
planetPositions: { [Influence.Mars]: -3 }
|
|
290
|
-
}, [
|
|
291
|
-
{ type: EffectType.GiveInfluence }
|
|
292
|
-
]);
|
|
288
|
+
}, [{ type: EffectType.GiveInfluence }]);
|
|
293
289
|
const result = resolveAllEffects(rules, player1);
|
|
294
290
|
expect(result.error).toBeUndefined();
|
|
295
291
|
});
|
|
296
292
|
it('except planet filter works', () => {
|
|
297
293
|
const rules = createRulesWithEffects({
|
|
298
294
|
planetPositions: { [Influence.Mars]: -4 }
|
|
299
|
-
}, [
|
|
300
|
-
{ type: EffectType.GiveInfluence, except: Influence.Mars }
|
|
301
|
-
]);
|
|
295
|
+
}, [{ type: EffectType.GiveInfluence, except: Influence.Mars }]);
|
|
302
296
|
const result = resolveAllEffects(rules, player1);
|
|
303
297
|
expect(result.error).toBeUndefined();
|
|
304
298
|
});
|
|
305
299
|
});
|
|
306
300
|
describe('Exile edge cases', () => {
|
|
307
301
|
it('exile with no influence cards should skip', () => {
|
|
308
|
-
const rules = createRulesWithEffects({}, [
|
|
309
|
-
{ type: EffectType.Exile }
|
|
310
|
-
]);
|
|
302
|
+
const rules = createRulesWithEffects({}, [{ type: EffectType.Exile }]);
|
|
311
303
|
const result = resolveAllEffects(rules, player1);
|
|
312
304
|
expect(result.error).toBeUndefined();
|
|
313
305
|
});
|
|
314
306
|
it('exile opponent with no opponent influence cards should skip', () => {
|
|
315
307
|
const rules = createRulesWithEffects({
|
|
316
308
|
playerInfluenceCards: [Agent.Pkd1ck]
|
|
317
|
-
}, [
|
|
318
|
-
{ type: EffectType.Exile, opponent: true }
|
|
319
|
-
]);
|
|
309
|
+
}, [{ type: EffectType.Exile, opponent: true }]);
|
|
320
310
|
const result = resolveAllEffects(rules, player1);
|
|
321
311
|
expect(result.error).toBeUndefined();
|
|
322
312
|
});
|
|
323
313
|
it('exile quantity=2 with only 1 card should exile 1 then skip', () => {
|
|
324
314
|
const rules = createRulesWithEffects({
|
|
325
315
|
playerInfluenceCards: [Agent.Pkd1ck]
|
|
326
|
-
}, [
|
|
327
|
-
{ type: EffectType.Exile, quantity: 2 }
|
|
328
|
-
]);
|
|
316
|
+
}, [{ type: EffectType.Exile, quantity: 2 }]);
|
|
329
317
|
const result = resolveAllEffects(rules, player1);
|
|
330
318
|
expect(result.error).toBeUndefined();
|
|
331
319
|
});
|
|
332
320
|
it('exile with specific influence filter and no matching cards should skip', () => {
|
|
333
321
|
const rules = createRulesWithEffects({
|
|
334
322
|
playerInfluenceCards: [Agent.Pkd1ck]
|
|
335
|
-
}, [
|
|
336
|
-
{ type: EffectType.Exile, influence: Influence.Venus }
|
|
337
|
-
]);
|
|
323
|
+
}, [{ type: EffectType.Exile, influence: Influence.Venus }]);
|
|
338
324
|
const result = resolveAllEffects(rules, player1);
|
|
339
325
|
expect(result.error).toBeUndefined();
|
|
340
326
|
});
|
|
341
327
|
});
|
|
342
328
|
describe('Transfer edge cases', () => {
|
|
343
329
|
it('transfer with no opponent influence cards should skip', () => {
|
|
344
|
-
const rules = createRulesWithEffects({}, [
|
|
345
|
-
{ type: EffectType.Transfer }
|
|
346
|
-
]);
|
|
330
|
+
const rules = createRulesWithEffects({}, [{ type: EffectType.Transfer }]);
|
|
347
331
|
const result = resolveAllEffects(rules, player1);
|
|
348
332
|
expect(result.error).toBeUndefined();
|
|
349
333
|
});
|
|
350
334
|
it('transfer quantity=2 with only 1 opponent card should skip (isPossible checks quantity)', () => {
|
|
351
335
|
const rules = createRulesWithEffects({
|
|
352
336
|
opponentInfluenceCards: [Agent.Pkd1ck]
|
|
353
|
-
}, [
|
|
354
|
-
{ type: EffectType.Transfer, quantity: 2 }
|
|
355
|
-
]);
|
|
337
|
+
}, [{ type: EffectType.Transfer, quantity: 2 }]);
|
|
356
338
|
const result = resolveAllEffects(rules, player1);
|
|
357
339
|
expect(result.error).toBeUndefined();
|
|
358
340
|
});
|
|
359
341
|
it('transfer with specific influence and matching opponent cards should not block', () => {
|
|
360
342
|
const rules = createRulesWithEffects({
|
|
361
343
|
opponentInfluenceCards: [Agent.Pkd1ck]
|
|
362
|
-
}, [
|
|
363
|
-
{ type: EffectType.Transfer, influence: Influence.Mercury }
|
|
364
|
-
]);
|
|
344
|
+
}, [{ type: EffectType.Transfer, influence: Influence.Mercury }]);
|
|
365
345
|
const result = resolveAllEffects(rules, player1);
|
|
366
346
|
expect(result.error).toBeUndefined();
|
|
367
347
|
});
|
|
@@ -370,18 +350,14 @@ describe('GiveCredit edge cases', () => {
|
|
|
370
350
|
it('give credits with 0 credits should skip', () => {
|
|
371
351
|
const rules = createRulesWithEffects({
|
|
372
352
|
playerCredits: 0
|
|
373
|
-
}, [
|
|
374
|
-
{ type: EffectType.GiveCredit, quantity: 3 }
|
|
375
|
-
]);
|
|
353
|
+
}, [{ type: EffectType.GiveCredit, quantity: 3 }]);
|
|
376
354
|
const result = resolveAllEffects(rules, player1);
|
|
377
355
|
expect(result.error).toBeUndefined();
|
|
378
356
|
});
|
|
379
357
|
it('give credits with insufficient credits should skip', () => {
|
|
380
358
|
const rules = createRulesWithEffects({
|
|
381
359
|
playerCredits: 2
|
|
382
|
-
}, [
|
|
383
|
-
{ type: EffectType.GiveCredit, quantity: 5 }
|
|
384
|
-
]);
|
|
360
|
+
}, [{ type: EffectType.GiveCredit, quantity: 5 }]);
|
|
385
361
|
const result = resolveAllEffects(rules, player1);
|
|
386
362
|
expect(result.error).toBeUndefined();
|
|
387
363
|
});
|
|
@@ -390,9 +366,7 @@ describe('StealCredit edge cases', () => {
|
|
|
390
366
|
it('steal credits from opponent with 0 credits should skip', () => {
|
|
391
367
|
const rules = createRulesWithEffects({
|
|
392
368
|
opponentCredits: 0
|
|
393
|
-
}, [
|
|
394
|
-
{ type: EffectType.StealCredit, quantity: 2 }
|
|
395
|
-
]);
|
|
369
|
+
}, [{ type: EffectType.StealCredit, quantity: 2 }]);
|
|
396
370
|
const result = resolveAllEffects(rules, player1);
|
|
397
371
|
expect(result.error).toBeUndefined();
|
|
398
372
|
});
|
|
@@ -401,9 +375,7 @@ describe('GiveZenithium edge cases', () => {
|
|
|
401
375
|
it('give zenithium with 0 zenithium should skip', () => {
|
|
402
376
|
const rules = createRulesWithEffects({
|
|
403
377
|
playerZenithium: 0
|
|
404
|
-
}, [
|
|
405
|
-
{ type: EffectType.GiveZenithium, quantity: 1 }
|
|
406
|
-
]);
|
|
378
|
+
}, [{ type: EffectType.GiveZenithium, quantity: 1 }]);
|
|
407
379
|
const result = resolveAllEffects(rules, player1);
|
|
408
380
|
expect(result.error).toBeUndefined();
|
|
409
381
|
});
|
|
@@ -412,18 +384,14 @@ describe('SpendCredit edge cases', () => {
|
|
|
412
384
|
it('spend credits with 0 credits should skip', () => {
|
|
413
385
|
const rules = createRulesWithEffects({
|
|
414
386
|
playerCredits: 0
|
|
415
|
-
}, [
|
|
416
|
-
{ type: EffectType.SpendCredit, quantities: [2, 4, 6], factors: [1, 2, 3] }
|
|
417
|
-
]);
|
|
387
|
+
}, [{ type: EffectType.SpendCredit, quantities: [2, 4, 6], factors: [1, 2, 3] }]);
|
|
418
388
|
const result = resolveAllEffects(rules, player1);
|
|
419
389
|
expect(result.error).toBeUndefined();
|
|
420
390
|
});
|
|
421
391
|
it('spend credits with insufficient for all tiers should skip', () => {
|
|
422
392
|
const rules = createRulesWithEffects({
|
|
423
393
|
playerCredits: 1
|
|
424
|
-
}, [
|
|
425
|
-
{ type: EffectType.SpendCredit, quantities: [2, 4, 6], factors: [1, 2, 3] }
|
|
426
|
-
]);
|
|
394
|
+
}, [{ type: EffectType.SpendCredit, quantities: [2, 4, 6], factors: [1, 2, 3] }]);
|
|
427
395
|
const result = resolveAllEffects(rules, player1);
|
|
428
396
|
expect(result.error).toBeUndefined();
|
|
429
397
|
});
|
|
@@ -432,9 +400,7 @@ describe('SpendZenithium edge cases', () => {
|
|
|
432
400
|
it('spend zenithium with 0 zenithium should skip', () => {
|
|
433
401
|
const rules = createRulesWithEffects({
|
|
434
402
|
playerZenithium: 0
|
|
435
|
-
}, [
|
|
436
|
-
{ type: EffectType.SpendZenithium, quantities: [1, 2], factors: [1, 2] }
|
|
437
|
-
]);
|
|
403
|
+
}, [{ type: EffectType.SpendZenithium, quantities: [1, 2], factors: [1, 2] }]);
|
|
438
404
|
const result = resolveAllEffects(rules, player1);
|
|
439
405
|
expect(result.error).toBeUndefined();
|
|
440
406
|
});
|
|
@@ -442,7 +408,7 @@ describe('SpendZenithium edge cases', () => {
|
|
|
442
408
|
describe('Discard edge cases', () => {
|
|
443
409
|
it('discard with empty hand should skip', () => {
|
|
444
410
|
const setup = new EffectTestSetup({});
|
|
445
|
-
const game = setup.setup({ players: [{}, {}], animodBoard: 'S', humanBoard: 'U', robotBoard: 'N'
|
|
411
|
+
const game = setup.setup({ players: [{}, {}], animodBoard: 'S', humanBoard: 'U', robotBoard: 'N' });
|
|
446
412
|
const rules = new ZenithRules(game);
|
|
447
413
|
const hand = rules.material(MaterialType.AgentCard).location(LocationType.PlayerHand).player(player1);
|
|
448
414
|
for (const index of hand.getIndexes()) {
|
|
@@ -457,12 +423,13 @@ describe('ResetInfluence edge cases', () => {
|
|
|
457
423
|
it('reset influence with no planets on player side should skip', () => {
|
|
458
424
|
const rules = createRulesWithEffects({
|
|
459
425
|
planetPositions: {
|
|
460
|
-
[Influence.Mercury]: -2,
|
|
461
|
-
[Influence.
|
|
426
|
+
[Influence.Mercury]: -2,
|
|
427
|
+
[Influence.Venus]: -1,
|
|
428
|
+
[Influence.Terra]: 0,
|
|
429
|
+
[Influence.Mars]: -1,
|
|
430
|
+
[Influence.Jupiter]: -2
|
|
462
431
|
}
|
|
463
|
-
}, [
|
|
464
|
-
{ type: EffectType.ResetInfluence }
|
|
465
|
-
]);
|
|
432
|
+
}, [{ type: EffectType.ResetInfluence }]);
|
|
466
433
|
const result = resolveAllEffects(rules, player1);
|
|
467
434
|
expect(result.error).toBeUndefined();
|
|
468
435
|
});
|
|
@@ -592,17 +559,20 @@ describe('Chained effect sequences', () => {
|
|
|
592
559
|
}, [
|
|
593
560
|
{ type: EffectType.WinInfluence, influence: Influence.Mars, quantity: 1 },
|
|
594
561
|
{
|
|
595
|
-
type: EffectType.Conditional,
|
|
562
|
+
type: EffectType.Conditional,
|
|
563
|
+
mandatory: true,
|
|
596
564
|
condition: { type: ConditionType.DoEffect, effect: { type: EffectType.Mobilize } },
|
|
597
565
|
effect: { type: EffectType.WinInfluence, quantity: 1 }
|
|
598
566
|
},
|
|
599
567
|
{
|
|
600
|
-
type: EffectType.Conditional,
|
|
568
|
+
type: EffectType.Conditional,
|
|
569
|
+
mandatory: true,
|
|
601
570
|
condition: { type: ConditionType.DoEffect, effect: { type: EffectType.Mobilize } },
|
|
602
571
|
effect: { type: EffectType.WinInfluence, quantity: 1 }
|
|
603
572
|
},
|
|
604
573
|
{
|
|
605
|
-
type: EffectType.Conditional,
|
|
574
|
+
type: EffectType.Conditional,
|
|
575
|
+
mandatory: true,
|
|
606
576
|
condition: { type: ConditionType.DoEffect, effect: { type: EffectType.Mobilize } },
|
|
607
577
|
effect: { type: EffectType.WinInfluence, quantity: 1 }
|
|
608
578
|
}
|
|
@@ -617,12 +587,14 @@ describe('Chained effect sequences', () => {
|
|
|
617
587
|
}, [
|
|
618
588
|
{ type: EffectType.WinInfluence, influence: Influence.Mars, quantity: 1 },
|
|
619
589
|
{
|
|
620
|
-
type: EffectType.Conditional,
|
|
590
|
+
type: EffectType.Conditional,
|
|
591
|
+
mandatory: true,
|
|
621
592
|
condition: { type: ConditionType.DoEffect, effect: { type: EffectType.Mobilize } },
|
|
622
593
|
effect: { type: EffectType.WinInfluence, quantity: 1 }
|
|
623
594
|
},
|
|
624
595
|
{
|
|
625
|
-
type: EffectType.Conditional,
|
|
596
|
+
type: EffectType.Conditional,
|
|
597
|
+
mandatory: true,
|
|
626
598
|
condition: { type: ConditionType.DoEffect, effect: { type: EffectType.Mobilize } },
|
|
627
599
|
effect: { type: EffectType.WinInfluence, quantity: 1 }
|
|
628
600
|
}
|
|
@@ -636,9 +608,7 @@ describe('Mobilize edge cases', () => {
|
|
|
636
608
|
const rules = createRulesWithEffects({
|
|
637
609
|
deckCount: 2,
|
|
638
610
|
discardCount: 0
|
|
639
|
-
}, [
|
|
640
|
-
{ type: EffectType.Mobilize, quantity: 2 }
|
|
641
|
-
]);
|
|
611
|
+
}, [{ type: EffectType.Mobilize, quantity: 2 }]);
|
|
642
612
|
const result = resolveAllEffects(rules, player1);
|
|
643
613
|
expect(result.error).toBeUndefined();
|
|
644
614
|
});
|
|
@@ -646,9 +616,7 @@ describe('Mobilize edge cases', () => {
|
|
|
646
616
|
const rules = createRulesWithEffects({
|
|
647
617
|
deckCount: 1,
|
|
648
618
|
discardCount: 0
|
|
649
|
-
}, [
|
|
650
|
-
{ type: EffectType.Mobilize, quantity: 3 }
|
|
651
|
-
]);
|
|
619
|
+
}, [{ type: EffectType.Mobilize, quantity: 3 }]);
|
|
652
620
|
const result = resolveAllEffects(rules, player1);
|
|
653
621
|
expect(result.error).toBeUndefined();
|
|
654
622
|
});
|
|
@@ -657,7 +625,8 @@ describe('Mobilize edge cases', () => {
|
|
|
657
625
|
deckCount: 5
|
|
658
626
|
}, [
|
|
659
627
|
{
|
|
660
|
-
type: EffectType.Conditional,
|
|
628
|
+
type: EffectType.Conditional,
|
|
629
|
+
mandatory: true,
|
|
661
630
|
condition: { type: ConditionType.DoEffect, effect: { type: EffectType.Mobilize, quantity: 2 } },
|
|
662
631
|
effect: { type: EffectType.WinInfluence, quantity: 1 }
|
|
663
632
|
}
|
|
@@ -668,39 +637,29 @@ describe('Mobilize edge cases', () => {
|
|
|
668
637
|
});
|
|
669
638
|
describe('WinCredit edge cases', () => {
|
|
670
639
|
it('perLevel1Technology with no techs should give 0 credits (not block)', () => {
|
|
671
|
-
const rules = createRulesWithEffects({}, [
|
|
672
|
-
{ type: EffectType.WinCredit, perLevel1Technology: [Faction.Human] }
|
|
673
|
-
]);
|
|
640
|
+
const rules = createRulesWithEffects({}, [{ type: EffectType.WinCredit, perLevel1Technology: [Faction.Human] }]);
|
|
674
641
|
const result = resolveAllEffects(rules, player1);
|
|
675
642
|
expect(result.error).toBeUndefined();
|
|
676
643
|
});
|
|
677
644
|
it('factorPerDifferentInfluence with no influence cards should give 0', () => {
|
|
678
|
-
const rules = createRulesWithEffects({}, [
|
|
679
|
-
{ type: EffectType.WinCredit, factorPerDifferentInfluence: 2 }
|
|
680
|
-
]);
|
|
645
|
+
const rules = createRulesWithEffects({}, [{ type: EffectType.WinCredit, factorPerDifferentInfluence: 2 }]);
|
|
681
646
|
const result = resolveAllEffects(rules, player1);
|
|
682
647
|
expect(result.error).toBeUndefined();
|
|
683
648
|
});
|
|
684
649
|
it('factorPerDifferentOpponentInfluence with no opponent cards should give 0', () => {
|
|
685
|
-
const rules = createRulesWithEffects({}, [
|
|
686
|
-
{ type: EffectType.WinCredit, factorPerDifferentOpponentInfluence: 2 }
|
|
687
|
-
]);
|
|
650
|
+
const rules = createRulesWithEffects({}, [{ type: EffectType.WinCredit, factorPerDifferentOpponentInfluence: 2 }]);
|
|
688
651
|
const result = resolveAllEffects(rules, player1);
|
|
689
652
|
expect(result.error).toBeUndefined();
|
|
690
653
|
});
|
|
691
654
|
});
|
|
692
655
|
describe('WinZenithium edge cases', () => {
|
|
693
656
|
it('perLevel1Technology with no techs should give 0 zenithium', () => {
|
|
694
|
-
const rules = createRulesWithEffects({}, [
|
|
695
|
-
{ type: EffectType.WinZenithium, perLevel1Technology: [Faction.Human] }
|
|
696
|
-
]);
|
|
657
|
+
const rules = createRulesWithEffects({}, [{ type: EffectType.WinZenithium, perLevel1Technology: [Faction.Human] }]);
|
|
697
658
|
const result = resolveAllEffects(rules, player1);
|
|
698
659
|
expect(result.error).toBeUndefined();
|
|
699
660
|
});
|
|
700
661
|
it('opponent=true should give zenithium to opponent', () => {
|
|
701
|
-
const rules = createRulesWithEffects({}, [
|
|
702
|
-
{ type: EffectType.WinZenithium, quantity: 1, opponent: true }
|
|
703
|
-
]);
|
|
662
|
+
const rules = createRulesWithEffects({}, [{ type: EffectType.WinZenithium, quantity: 1, opponent: true }]);
|
|
704
663
|
const result = resolveAllEffects(rules, player1);
|
|
705
664
|
expect(result.error).toBeUndefined();
|
|
706
665
|
});
|
|
@@ -709,21 +668,17 @@ describe('StealZenithium', () => {
|
|
|
709
668
|
it('should steal zenithium from opponent', () => {
|
|
710
669
|
const rules = createRulesWithEffects({
|
|
711
670
|
playerZenithium: 1
|
|
712
|
-
}, [
|
|
713
|
-
{ type: EffectType.StealZenithium, quantity: 1 }
|
|
714
|
-
]);
|
|
671
|
+
}, [{ type: EffectType.StealZenithium, quantity: 1 }]);
|
|
715
672
|
rules.game.rule = { id: RuleId.StealZenithium, player: player1 };
|
|
716
673
|
resolveAutoMoves(rules);
|
|
717
|
-
const totalZen = rules.material(MaterialType.ZenithiumToken)
|
|
718
|
-
.location(LocationType.TeamZenithium).getQuantity();
|
|
674
|
+
const totalZen = rules.material(MaterialType.ZenithiumToken).location(LocationType.TeamZenithium).getQuantity();
|
|
719
675
|
expect(totalZen).toBe(4);
|
|
720
676
|
});
|
|
721
677
|
it('should skip when opponent has no zenithium', () => {
|
|
722
678
|
const setup = new EffectTestSetup({});
|
|
723
|
-
const game = setup.setup({ players: [{}, {}], animodBoard: 'S', humanBoard: 'U', robotBoard: 'N'
|
|
679
|
+
const game = setup.setup({ players: [{}, {}], animodBoard: 'S', humanBoard: 'U', robotBoard: 'N' });
|
|
724
680
|
const rules = new ZenithRules(game);
|
|
725
|
-
const opponentZen = rules.material(MaterialType.ZenithiumToken)
|
|
726
|
-
.location(LocationType.TeamZenithium).player(TeamColor.Black);
|
|
681
|
+
const opponentZen = rules.material(MaterialType.ZenithiumToken).location(LocationType.TeamZenithium).player(TeamColor.Black);
|
|
727
682
|
if (opponentZen.length) {
|
|
728
683
|
playConsequences(rules, opponentZen.deleteItem());
|
|
729
684
|
}
|
|
@@ -734,16 +689,12 @@ describe('StealZenithium', () => {
|
|
|
734
689
|
});
|
|
735
690
|
describe('Technology board alternative effects', () => {
|
|
736
691
|
it('Board D level 4: WinInfluence pattern [1,1,1,1,1] should influence all planets', () => {
|
|
737
|
-
const rules = createRulesWithEffects({}, [
|
|
738
|
-
{ type: EffectType.WinInfluence, pattern: [1, 1, 1, 1, 1] }
|
|
739
|
-
]);
|
|
692
|
+
const rules = createRulesWithEffects({}, [{ type: EffectType.WinInfluence, pattern: [1, 1, 1, 1, 1] }]);
|
|
740
693
|
const result = resolveAllEffects(rules, player1);
|
|
741
694
|
expect(result.error).toBeUndefined();
|
|
742
695
|
});
|
|
743
696
|
it('Board O level 4: WinInfluence pattern [2,2] should influence 2 adjacent planets', () => {
|
|
744
|
-
const rules = createRulesWithEffects({}, [
|
|
745
|
-
{ type: EffectType.WinInfluence, pattern: [2, 2] }
|
|
746
|
-
]);
|
|
697
|
+
const rules = createRulesWithEffects({}, [{ type: EffectType.WinInfluence, pattern: [2, 2] }]);
|
|
747
698
|
const result = resolveAllEffects(rules, player1);
|
|
748
699
|
expect(result.error).toBeUndefined();
|
|
749
700
|
});
|
|
@@ -803,18 +754,18 @@ describe('Technology board alternative effects', () => {
|
|
|
803
754
|
describe('Board options', () => {
|
|
804
755
|
it('should use specified board sides', () => {
|
|
805
756
|
const setup = new EffectTestSetup({});
|
|
806
|
-
const game = setup.setup({ players: [{}, {}], animodBoard: 'S', humanBoard: 'U', robotBoard: 'N'
|
|
757
|
+
const game = setup.setup({ players: [{}, {}], animodBoard: 'S', humanBoard: 'U', robotBoard: 'N' });
|
|
807
758
|
const rules = new ZenithRules(game);
|
|
808
759
|
const boards = rules.material(MaterialType.TechnologyBoard).getItems();
|
|
809
|
-
const ids = boards.map(b => b.id).sort();
|
|
760
|
+
const ids = boards.map((b) => b.id).sort();
|
|
810
761
|
expect(ids).toEqual(['N', 'S', 'U']);
|
|
811
762
|
});
|
|
812
763
|
it('should use D/O/P sides when specified', () => {
|
|
813
764
|
const setup = new ZenithSetup();
|
|
814
|
-
const game = setup.setup({ players: [{}, {}], animodBoard: 'D', humanBoard: 'O', robotBoard: 'P'
|
|
765
|
+
const game = setup.setup({ players: [{}, {}], animodBoard: 'D', humanBoard: 'O', robotBoard: 'P' });
|
|
815
766
|
const rules = new ZenithRules(game);
|
|
816
767
|
const boards = rules.material(MaterialType.TechnologyBoard).getItems();
|
|
817
|
-
const ids = boards.map(b => b.id).sort();
|
|
768
|
+
const ids = boards.map((b) => b.id).sort();
|
|
818
769
|
expect(ids).toEqual(['D', 'O', 'P']);
|
|
819
770
|
});
|
|
820
771
|
it('should use random faces when no option specified', () => {
|
|
@@ -822,11 +773,11 @@ describe('Board options', () => {
|
|
|
822
773
|
const game = setup.setup({ players: [{}, {}] });
|
|
823
774
|
const rules = new ZenithRules(game);
|
|
824
775
|
const boards = rules.material(MaterialType.TechnologyBoard).getItems();
|
|
825
|
-
const ids = boards.map(b => b.id);
|
|
776
|
+
const ids = boards.map((b) => b.id);
|
|
826
777
|
expect(ids.length).toBe(3);
|
|
827
|
-
expect(['S', 'D']).toContain(ids.find(id => ['S', 'D'].includes(id)));
|
|
828
|
-
expect(['U', 'O']).toContain(ids.find(id => ['U', 'O'].includes(id)));
|
|
829
|
-
expect(['N', 'P']).toContain(ids.find(id => ['N', 'P'].includes(id)));
|
|
778
|
+
expect(['S', 'D']).toContain(ids.find((id) => ['S', 'D'].includes(id)));
|
|
779
|
+
expect(['U', 'O']).toContain(ids.find((id) => ['U', 'O'].includes(id)));
|
|
780
|
+
expect(['N', 'P']).toContain(ids.find((id) => ['N', 'P'].includes(id)));
|
|
830
781
|
});
|
|
831
782
|
});
|
|
832
783
|
//# sourceMappingURL=EffectEdgeCases.spec.js.map
|