slop game oder so
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import { WAVES } from '../../app/static/js/config.js';
|
||||
import { createRng } from '../../app/static/js/logic/rng.js';
|
||||
import { WaveDirector } from '../../app/static/js/logic/waveDirector.js';
|
||||
|
||||
/** Minimaler Spielersatz: zählt gespawnte Gegner und lässt sie auf Befehl sterben. */
|
||||
function harness(cfgOverrides = {}) {
|
||||
const log = { spawned: 0, started: [], cleared: [] };
|
||||
let alive = 0;
|
||||
const director = new WaveDirector({
|
||||
rng: createRng(1),
|
||||
cfg: { ...WAVES, ...cfgOverrides },
|
||||
spawnGroup: (group) => {
|
||||
log.spawned += group.count;
|
||||
alive += group.count;
|
||||
},
|
||||
aliveCount: () => alive,
|
||||
onWaveStart: (plan) => log.started.push(plan.number),
|
||||
onWaveCleared: (n) => log.cleared.push(n),
|
||||
});
|
||||
return {
|
||||
director,
|
||||
log,
|
||||
killAll: () => {
|
||||
alive = 0;
|
||||
},
|
||||
get alive() {
|
||||
return alive;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/** Lässt die Zeit in 50-ms-Schritten laufen. */
|
||||
function run(director, from, until, step = 50) {
|
||||
let now = from;
|
||||
while (now < until) {
|
||||
now += step;
|
||||
director.update(now, step);
|
||||
}
|
||||
return now;
|
||||
}
|
||||
|
||||
describe('WaveDirector', () => {
|
||||
it('startet die erste Welle nach der Startverzögerung', () => {
|
||||
const { director, log } = harness();
|
||||
director.start(0);
|
||||
expect(director.state).toBe('intermission');
|
||||
run(director, 0, WAVES.firstWaveDelayMs - 50);
|
||||
expect(log.started).toEqual([]);
|
||||
run(director, WAVES.firstWaveDelayMs - 50, WAVES.firstWaveDelayMs);
|
||||
expect(log.started).toEqual([1]);
|
||||
expect(director.state).toBe('active');
|
||||
});
|
||||
|
||||
it('spawnt alle Gruppen der Welle nach Plan', () => {
|
||||
const { director, log } = harness();
|
||||
director.start(0);
|
||||
const now = run(director, 0, WAVES.firstWaveDelayMs);
|
||||
const planned = director.plan.totalEnemies;
|
||||
run(director, now, now + 60_000);
|
||||
expect(log.spawned).toBe(planned);
|
||||
expect(director.pendingEnemies).toBe(0);
|
||||
});
|
||||
|
||||
it('meldet eine Welle erst als geschafft, wenn alle Gegner besiegt sind', () => {
|
||||
const h = harness();
|
||||
h.director.start(0);
|
||||
let now = run(h.director, 0, 60_000);
|
||||
expect(h.log.cleared).toEqual([]);
|
||||
h.killAll();
|
||||
now = run(h.director, now, now + 100);
|
||||
expect(h.log.cleared).toEqual([1]);
|
||||
expect(h.director.state).toBe('intermission');
|
||||
expect(h.director.intermissionRemaining(now)).toBeGreaterThan(WAVES.intermissionMs - 200);
|
||||
});
|
||||
|
||||
it('startet nach der Pause die nächste, größere Welle', () => {
|
||||
const h = harness();
|
||||
h.director.start(0);
|
||||
let now = run(h.director, 0, 60_000);
|
||||
const firstSize = h.director.plan.totalEnemies;
|
||||
h.killAll();
|
||||
now = run(h.director, now, now + WAVES.intermissionMs + 200);
|
||||
expect(h.log.started).toEqual([1, 2]);
|
||||
run(h.director, now, now + 60_000);
|
||||
expect(h.director.plan.totalEnemies).toBeGreaterThan(firstSize);
|
||||
});
|
||||
|
||||
it('hält den Spawn-Ablauf an, solange zu viele Gegner leben', () => {
|
||||
const h = harness({ maxAliveEnemies: 3 });
|
||||
h.director.start(0);
|
||||
// Wellenstart plus ein Frame: Die erste Gruppe (≥4 Krabbler) überschreitet das Limit sofort.
|
||||
let now = run(h.director, 0, WAVES.firstWaveDelayMs + 50);
|
||||
const spawnedBefore = h.log.spawned;
|
||||
expect(h.alive).toBeGreaterThanOrEqual(3);
|
||||
now = run(h.director, now, now + 60_000);
|
||||
expect(h.log.spawned).toBe(spawnedBefore);
|
||||
h.killAll();
|
||||
run(h.director, now, now + 60_000);
|
||||
expect(h.log.spawned).toBeGreaterThan(spawnedBefore);
|
||||
});
|
||||
|
||||
it('tut vor dem Start nichts', () => {
|
||||
const { director, log } = harness();
|
||||
run(director, 0, 10_000);
|
||||
expect(log.started).toEqual([]);
|
||||
expect(director.pendingEnemies).toBe(0);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user