This commit is contained in:
icslucas
2025-10-26 22:52:39 +01:00
parent 077bce3380
commit fdbeec9bbe
17 changed files with 1610 additions and 1055 deletions
@@ -1,122 +0,0 @@
import { Game, GameMode, UnitType } from "../../../src/core/game/Game";
import { PlayerImpl } from "../../../src/core/game/PlayerImpl";
describe("NukeWars Unit Restrictions", () => {
let mg: jest.Mocked<Game>;
beforeEach(() => {
mg = {
config: jest.fn().mockReturnValue({
gameConfig: jest.fn().mockReturnValue({
gameMode: GameMode.NukeWars,
maxTimerValue: 5,
}),
isUnitDisabled: jest.fn().mockImplementation((unitType: UnitType) => {
const allowedUnits = [
UnitType.MissileSilo,
UnitType.SAMLauncher,
UnitType.AtomBomb,
UnitType.HydrogenBomb,
];
return !allowedUnits.includes(unitType);
}),
}),
width: jest.fn().mockReturnValue(100),
x: jest.fn(),
teams: jest.fn().mockReturnValue(["Team1", "Team2"]),
inSpawnPhase: jest.fn().mockReturnValue(true),
unitInfo: jest.fn().mockReturnValue({
cost: jest.fn().mockReturnValue(0n),
}),
} as unknown as jest.Mocked<Game>;
});
describe("Unit type restrictions", () => {
it.each([
[UnitType.MissileSilo, true],
[UnitType.SAMLauncher, true],
[UnitType.AtomBomb, true],
[UnitType.HydrogenBomb, true],
[UnitType.MIRV, false],
[UnitType.City, false],
[UnitType.DefensePost, false],
[UnitType.Port, false],
[UnitType.TransportShip, false],
[UnitType.Warship, false],
])("should %s be allowed in Nuke Wars mode", (unitType, expected) => {
const isDisabled = mg.config().isUnitDisabled(unitType);
expect(!isDisabled).toBe(expected);
});
});
describe("Spawn zone restrictions", () => {
let player: jest.Mocked<PlayerImpl>;
beforeEach(() => {
player = {
team: jest.fn().mockReturnValue("Team1"),
isAlive: jest.fn().mockReturnValue(true),
gold: jest.fn().mockReturnValue(1000n),
canBuild: jest.fn().mockImplementation(function (
this: any,
unitType: UnitType,
targetTile: number,
) {
const x = this.mg.x(targetTile);
const mapWidth = this.mg.width();
const midpoint = Math.floor(mapWidth / 2);
const onOwnSide = x < midpoint;
if (this.mg.inSpawnPhase()) {
return onOwnSide ? targetTile : false;
}
if (!onOwnSide) {
return [UnitType.AtomBomb, UnitType.HydrogenBomb].includes(unitType)
? targetTile
: false;
}
return this.mg.config().isUnitDisabled(unitType) ? false : targetTile;
}),
mg: mg,
} as unknown as jest.Mocked<PlayerImpl>;
});
describe("During spawn phase", () => {
beforeEach(() => {
mg.inSpawnPhase.mockReturnValue(true);
});
it("should allow building on own side", () => {
mg.x.mockReturnValue(20); // Left side
const canBuild = player.canBuild(UnitType.MissileSilo, 0);
expect(canBuild).not.toBe(false);
});
it("should prevent building on enemy side", () => {
mg.x.mockReturnValue(80); // Right side
const canBuild = player.canBuild(UnitType.MissileSilo, 0);
expect(canBuild).toBe(false);
});
});
describe("After spawn phase", () => {
beforeEach(() => {
mg.inSpawnPhase.mockReturnValue(false);
});
it("should allow missiles to cross midpoint", () => {
mg.x.mockReturnValue(80); // Right side
const canBuild = player.canBuild(UnitType.AtomBomb, 0);
expect(canBuild).not.toBe(false);
});
it("should prevent SAM launchers from crossing midpoint", () => {
mg.x.mockReturnValue(80); // Right side
const canBuild = player.canBuild(UnitType.SAMLauncher, 0);
expect(canBuild).toBe(false);
});
});
});
});
@@ -1,116 +0,0 @@
import { WinCheckExecution } from "../../../src/core/execution/WinCheckExecution";
import {
ColoredTeams,
Game,
GameMode,
Player,
Team,
} from "../../../src/core/game/Game";
describe("NukeWars Win Check", () => {
let winCheck: WinCheckExecution;
let mg: jest.Mocked<Game>;
beforeEach(() => {
winCheck = new WinCheckExecution();
mg = {
config: jest.fn().mockReturnValue({
gameConfig: jest.fn().mockReturnValue({
gameMode: GameMode.NukeWars,
maxTimerValue: 5,
}),
numSpawnPhaseTurns: jest.fn().mockReturnValue(0),
}),
players: jest.fn(),
numLandTiles: jest.fn(),
numTilesWithFallout: jest.fn(),
setWinner: jest.fn(),
ticks: jest.fn().mockReturnValue(0),
stats: jest.fn().mockReturnValue({
stats: jest.fn(),
}),
} as unknown as jest.Mocked<Game>;
});
it("should declare winner when a team drops below 5% territory", () => {
const team1Players = [
{
numTilesOwned: jest.fn().mockReturnValue(40),
team: jest.fn().mockReturnValue("Team1" as Team),
},
] as unknown as Player[];
const team2Players = [
{
numTilesOwned: jest.fn().mockReturnValue(4), // < 5% territory
team: jest.fn().mockReturnValue("Team2" as Team),
},
] as unknown as Player[];
mg.players.mockReturnValue([...team1Players, ...team2Players]);
mg.numLandTiles.mockReturnValue(100);
mg.numTilesWithFallout.mockReturnValue(0);
winCheck.init(mg, 0);
winCheck.checkWinnerNukeWars();
// Team1 should win since Team2 is below 5%
expect(mg.setWinner).toHaveBeenCalledWith("Team1", expect.anything());
});
it("should not declare bot team as winner", () => {
const botTeamPlayers = [
{
numTilesOwned: jest.fn().mockReturnValue(90),
team: jest.fn().mockReturnValue(ColoredTeams.Bot as Team),
},
] as unknown as Player[];
const playerTeamPlayers = [
{
numTilesOwned: jest.fn().mockReturnValue(4),
team: jest.fn().mockReturnValue("Team1" as Team),
},
] as unknown as Player[];
mg.players.mockReturnValue([...botTeamPlayers, ...playerTeamPlayers]);
mg.numLandTiles.mockReturnValue(100);
mg.numTilesWithFallout.mockReturnValue(0);
winCheck.init(mg, 0);
winCheck.checkWinnerNukeWars();
// Should not declare bot team as winner even if other team is < 5%
expect(mg.setWinner).not.toHaveBeenCalledWith(
ColoredTeams.Bot,
expect.anything(),
);
});
it("should declare winner with most territory when time runs out", () => {
const team1Players = [
{
numTilesOwned: jest.fn().mockReturnValue(60),
team: jest.fn().mockReturnValue("Team1" as Team),
},
] as unknown as Player[];
const team2Players = [
{
numTilesOwned: jest.fn().mockReturnValue(40),
team: jest.fn().mockReturnValue("Team2" as Team),
},
] as unknown as Player[];
mg.players.mockReturnValue([...team1Players, ...team2Players]);
mg.numLandTiles.mockReturnValue(100);
mg.numTilesWithFallout.mockReturnValue(0);
mg.ticks.mockReturnValue(5 * 60 * 10 + 1); // Just past time limit
winCheck.init(mg, 0);
winCheck.checkWinnerNukeWars();
// Team1 should win since they have more territory when time expires
expect(mg.setWinner).toHaveBeenCalledWith("Team1", expect.anything());
});
});