From 9de072c0c6da918ba45f631b8453cb0a39af3a77 Mon Sep 17 00:00:00 2001 From: Evan Date: Fri, 18 Apr 2025 14:26:19 -0700 Subject: [PATCH] fix failing SAM test --- src/core/execution/SAMLauncherExecution.ts | 8 +- tests/SAM.test.ts | 87 ++++++++-------------- tests/util/utils.ts | 6 ++ 3 files changed, 43 insertions(+), 58 deletions(-) diff --git a/src/core/execution/SAMLauncherExecution.ts b/src/core/execution/SAMLauncherExecution.ts index af1317319..5e37cf9cd 100644 --- a/src/core/execution/SAMLauncherExecution.ts +++ b/src/core/execution/SAMLauncherExecution.ts @@ -15,7 +15,6 @@ import { SAMMissileExecution } from "./SAMMissileExecution"; export class SAMLauncherExecution implements Execution { private player: Player; private mg: Game; - private sam: Unit; private active: boolean = true; private target: Unit = null; @@ -32,7 +31,12 @@ export class SAMLauncherExecution implements Execution { constructor( private ownerId: PlayerID, private tile: TileRef, - ) {} + private sam: Unit | null = null, + ) { + if (sam != null) { + this.tile = sam.tile(); + } + } init(mg: Game, ticks: number): void { this.mg = mg; diff --git a/tests/SAM.test.ts b/tests/SAM.test.ts index 4f63f9274..b3600310b 100644 --- a/tests/SAM.test.ts +++ b/tests/SAM.test.ts @@ -1,4 +1,4 @@ -import { NukeExecution } from "../src/core/execution/NukeExecution"; +import { SAMLauncherExecution } from "../src/core/execution/SAMLauncherExecution"; import { SpawnExecution } from "../src/core/execution/SpawnExecution"; import { Game, @@ -7,32 +7,13 @@ import { PlayerType, UnitType, } from "../src/core/game/Game"; -import { TileRef } from "../src/core/game/GameMap"; import { setup } from "./util/Setup"; -import { constructionExecution } from "./util/utils"; +import { constructionExecution, executeTicks } from "./util/utils"; let game: Game; let attacker: Player; let defender: Player; -function attackerBuildsNuke( - source: TileRef, - target: TileRef, - initialize = true, -) { - game.addExecution( - new NukeExecution(UnitType.AtomBomb, attacker.id(), target, source), - ); - if (initialize) { - game.executeNextTick(); - game.executeNextTick(); - } -} - -function defenderBuildsSam(x: number, y: number) { - constructionExecution(game, defender.id(), x, y, UnitType.SAMLauncher); -} - describe("SAM", () => { beforeEach(async () => { game = await setup("Plains", { infiniteGold: true, instantBuild: true }); @@ -69,62 +50,56 @@ describe("SAM", () => { }); test("one sam should take down one nuke", async () => { - defenderBuildsSam(1, 1); - attackerBuildsNuke(game.ref(7, 7), game.ref(1, 1)); - expect(attacker.units(UnitType.AtomBomb)).toHaveLength(1); + const sam = defender.buildUnit(UnitType.SAMLauncher, 0, game.ref(1, 1)); + game.addExecution(new SAMLauncherExecution(defender.id(), null, sam)); + attacker.buildUnit(UnitType.AtomBomb, 0, game.ref(1, 1)); + + executeTicks(game, 3); - game.executeNextTick(); - game.executeNextTick(); expect(attacker.units(UnitType.AtomBomb)).toHaveLength(0); }); test("sam should only get one nuke at a time", async () => { - defenderBuildsSam(1, 1); - attackerBuildsNuke(game.ref(7, 7), game.ref(1, 1), false); - attackerBuildsNuke(game.ref(7, 7), game.ref(1, 1)); + const sam = defender.buildUnit(UnitType.SAMLauncher, 0, game.ref(1, 1)); + game.addExecution(new SAMLauncherExecution(defender.id(), null, sam)); + attacker.buildUnit(UnitType.AtomBomb, 0, game.ref(2, 1)); + attacker.buildUnit(UnitType.AtomBomb, 0, game.ref(1, 2)); expect(attacker.units(UnitType.AtomBomb)).toHaveLength(2); - game.executeNextTick(); - game.executeNextTick(); + executeTicks(game, 3); + expect(attacker.units(UnitType.AtomBomb)).toHaveLength(1); }); test("sam should cooldown as long as configured", async () => { - defenderBuildsSam(1, 1); - expect(defender.units(UnitType.SAMLauncher)[0].isCooldown()).toBeFalsy(); - attackerBuildsNuke(game.ref(7, 7), game.ref(1, 1)); - expect(attacker.units(UnitType.AtomBomb)).toHaveLength(1); + const sam = defender.buildUnit(UnitType.SAMLauncher, 0, game.ref(1, 1)); + game.addExecution(new SAMLauncherExecution(defender.id(), null, sam)); + expect(sam.isCooldown()).toBeFalsy(); + const nuke = attacker.buildUnit(UnitType.AtomBomb, 0, game.ref(1, 2)); - game.executeNextTick(); - game.executeNextTick(); - expect(attacker.units(UnitType.AtomBomb)).toHaveLength(0); + executeTicks(game, 3); + expect(nuke.isActive()).toBeFalsy(); for (let i = 0; i < game.config().SAMCooldown() - 2; i++) { game.executeNextTick(); - expect(defender.units(UnitType.SAMLauncher)[0].isCooldown()).toBeTruthy(); + expect(sam.isCooldown()).toBeTruthy(); } - game.executeNextTick(); - expect(defender.units(UnitType.SAMLauncher)[0].isCooldown()).toBeFalsy(); + executeTicks(game, 2); + + expect(sam.isCooldown()).toBeFalsy(); }); test("two sams should not target twice same nuke", async () => { - defenderBuildsSam(1, 1); - defenderBuildsSam(1, 2); - attackerBuildsNuke(game.ref(7, 7), game.ref(1, 1)); + const sam1 = defender.buildUnit(UnitType.SAMLauncher, 0, game.ref(1, 1)); + game.addExecution(new SAMLauncherExecution(defender.id(), null, sam1)); + const sam2 = defender.buildUnit(UnitType.SAMLauncher, 0, game.ref(1, 2)); + game.addExecution(new SAMLauncherExecution(defender.id(), null, sam2)); + const nuke = attacker.buildUnit(UnitType.AtomBomb, 0, game.ref(2, 2)); - expect(defender.units(UnitType.SAMLauncher)).toHaveLength(2); - expect(attacker.units(UnitType.AtomBomb)).toHaveLength(1); + executeTicks(game, 3); - game.executeNextTick(); - game.executeNextTick(); - - expect(attacker.units(UnitType.AtomBomb)).toHaveLength(0); - const sams = defender.units(UnitType.SAMLauncher); - // Only one sam must have shot - expect( - (sams[0].isCooldown() && !sams[1].isCooldown()) || - (sams[1].isCooldown() && !sams[0].isCooldown()), - ).toBe(true); + expect(nuke.isActive()).toBeFalsy(); + expect([sam1, sam2].filter((s) => s.isCooldown())).toHaveLength(1); }); }); diff --git a/tests/util/utils.ts b/tests/util/utils.ts index 34210b9d8..aa1b7a05d 100644 --- a/tests/util/utils.ts +++ b/tests/util/utils.ts @@ -28,3 +28,9 @@ export function constructionExecution( game.executeNextTick(); } } + +export function executeTicks(game: Game, numTicks: number): void { + for (let i = 0; i < numTicks; i++) { + game.executeNextTick(); + } +}