feat: add warship tests (#291)

This commit is contained in:
Ilan Schemoul
2025-03-19 04:35:31 +01:00
committed by GitHub
parent 6499569240
commit 40b7fe9833
5 changed files with 141 additions and 4 deletions
+109
View File
@@ -0,0 +1,109 @@
import {
Game,
Player,
PlayerInfo,
PlayerType,
UnitType,
} from "../src/core/game/Game";
import { SpawnExecution } from "../src/core/execution/SpawnExecution";
import { setup } from "./util/Setup";
import { constructionExecution } from "./util/utils";
let game: Game;
let player1: Player;
let player2: Player;
describe("Warship", () => {
beforeEach(async () => {
game = await setup("half_land_half_ocean", {
infiniteGold: true,
instantBuild: true,
});
const player_1_info = new PlayerInfo(
"us",
"boat dude",
PlayerType.Human,
null,
"player_1_id",
);
game.addPlayer(player_1_info, 1000);
const player_2_info = new PlayerInfo(
"us",
"boat dude",
PlayerType.Human,
null,
"player_2_id",
);
game.addPlayer(player_2_info, 1000);
const spawnTile = game.map().ref(0, 0);
game.addExecution(
new SpawnExecution(game.player(player_1_info.id).info(), spawnTile),
new SpawnExecution(game.player(player_2_info.id).info(), spawnTile),
);
while (game.inSpawnPhase()) {
game.executeNextTick();
}
player1 = game.player(player_1_info.id);
player2 = game.player(player_2_info.id);
});
test("Warship heals only if player has port", async () => {
const maxHealth = game.config().unitInfo(UnitType.Warship).maxHealth;
const port = player1.buildUnit(UnitType.Port, 0, game.ref(0, 0));
const warship = player1.buildUnit(UnitType.Warship, 0, game.ref(7, 7));
game.executeNextTick();
expect(warship.health()).toBe(maxHealth);
warship.modifyHealth(-10);
expect(warship.health()).toBe(maxHealth - 10);
game.executeNextTick();
expect(warship.health()).toBe(maxHealth - 9);
port.delete();
game.executeNextTick();
expect(warship.health()).toBe(maxHealth - 9);
});
test("Warship captures trade if player has port", async () => {
constructionExecution(game, player1.id(), 0, 0, UnitType.Port);
constructionExecution(game, player1.id(), 7, 7, UnitType.Warship);
// Warship need one more tick (for warship exec to actually build warship)
game.executeNextTick();
expect(player1.units(UnitType.Warship)).toHaveLength(1);
// Cannot buildExec with trade ship as it's not buildable (but
// we can obviously directly add it to the player)
const tradeShip = player2.buildUnit(UnitType.TradeShip, 0, game.ref(6, 6));
expect(tradeShip.owner().id()).toBe(player2.id());
// Let plenty of time for A* to execute
for (let i = 0; i < 10; i++) {
game.executeNextTick();
}
expect(tradeShip.owner().id()).toBe(player1.id());
});
test("Warship do not capture trade if player has no port", async () => {
constructionExecution(game, player1.id(), 0, 0, UnitType.Port);
constructionExecution(game, player1.id(), 7, 7, UnitType.Warship);
expect(player1.units(UnitType.Warship)).toHaveLength(1);
player1.units(UnitType.Port)[0].delete();
// Cannot buildExec with trade ship as it's not buildable (but
// we can obviously directly add it to the player)
const tradeShip = player2.buildUnit(UnitType.TradeShip, 0, game.ref(6, 6));
expect(tradeShip.owner().id()).toBe(player2.id());
// Let plenty of time for A* to execute
for (let i = 0; i < 10; i++) {
game.executeNextTick();
}
expect(tradeShip.owner().id()).toBe(player2.id());
});
});
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 96 B

+4 -2
View File
@@ -7,12 +7,13 @@ import { TestConfig } from "./TestConfig";
import { TestServerConfig } from "./TestServerConfig";
import { UserSettings } from "../../src/core/game/UserSettings";
import { Difficulty, GameType } from "../../src/core/game/Game";
import { GameConfig } from "../../src/core/Schemas";
export async function setup(mapName: string) {
export async function setup(mapName: string, _gameConfig: GameConfig = {}) {
// Load the specified map
const mapPath = path.join(__dirname, "..", "testdata", `${mapName}.png`);
const imageBuffer = await fs.readFile(mapPath);
const { map, miniMap } = await generateMap(imageBuffer);
const { map, miniMap } = await generateMap(imageBuffer, false);
const gameMap = await genTerrainFromBin(String.fromCharCode.apply(null, map));
const miniGameMap = await genTerrainFromBin(
String.fromCharCode.apply(null, miniMap),
@@ -30,6 +31,7 @@ export async function setup(mapName: string) {
infiniteGold: false,
infiniteTroops: false,
instantBuild: false,
..._gameConfig,
};
const config = new TestConfig(serverConfig, gameConfig, new UserSettings());
+23
View File
@@ -0,0 +1,23 @@
// Either someone can straight up call player.buildUnit. It's simpler and immediate (no tick required)
// Either someone can straight up call player.buildUnit. It's simpler and immediate (no tick required)
// However buildUnit do not create executions (e.g.: WarshipExecution)
// If you also need execution use function below. Does not work with things not
import { ConstructionExecution } from "../../src/core/execution/ConstructionExecution";
import { Game, PlayerID, UnitType } from "../../src/core/game/Game";
// built via UI (e.g.: trade ships)
export function constructionExecution(
game: Game,
playerID: PlayerID,
x: number,
y: number,
unit: UnitType,
) {
game.addExecution(new ConstructionExecution(playerID, game.ref(x, y), unit));
// Init
game.executeNextTick();
// Exec
game.executeNextTick();
game.executeNextTick();
}