From 83eec17717c4f46948b15e328493239031bf1db1 Mon Sep 17 00:00:00 2001 From: Evan Date: Sat, 29 Mar 2025 15:24:11 -0700 Subject: [PATCH] add clan() function on playerinfo and Player --- src/core/game/Game.ts | 13 ++++- src/core/game/PlayerImpl.ts | 4 ++ tests/PlayerInfo.test.ts | 104 ++++++++++++++++++++++++++++++++++++ 3 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 tests/PlayerInfo.test.ts diff --git a/src/core/game/Game.ts b/src/core/game/Game.ts index 38a827aef..2bc965bc9 100644 --- a/src/core/game/Game.ts +++ b/src/core/game/Game.ts @@ -211,6 +211,8 @@ export interface MutableAlliance extends Alliance { } export class PlayerInfo { + public readonly clan: string | null; + constructor( public readonly flag: string, public readonly name: string, @@ -220,7 +222,15 @@ export class PlayerInfo { // TODO: make player id the small id public readonly id: PlayerID, public readonly nation?: Nation | null, - ) {} + ) { + // Compute clan from name + if (!name.startsWith("[") || !name.includes("]")) { + this.clan = null; + } else { + const clanMatch = name.match(/^\[([A-Z]{2,5})\]/); + this.clan = clanMatch ? clanMatch[1] : null; + } + } } // Some units have info specific to them @@ -349,6 +359,7 @@ export interface Player { // Either allied or on same team. isFriendly(other: Player): boolean; team(): Team | null; + clan(): string | null; incomingAllianceRequests(): AllianceRequest[]; outgoingAllianceRequests(): AllianceRequest[]; alliances(): MutableAlliance[]; diff --git a/src/core/game/PlayerImpl.ts b/src/core/game/PlayerImpl.ts index 03dab715b..57e5ac6c1 100644 --- a/src/core/game/PlayerImpl.ts +++ b/src/core/game/PlayerImpl.ts @@ -194,6 +194,10 @@ export class PlayerImpl implements Player { return this.playerInfo.playerType; } + clan(): string | null { + return this.playerInfo.clan; + } + units(...types: UnitType[]): UnitImpl[] { if (types.length == 0) { return this._units; diff --git a/tests/PlayerInfo.test.ts b/tests/PlayerInfo.test.ts new file mode 100644 index 000000000..9cb1275e2 --- /dev/null +++ b/tests/PlayerInfo.test.ts @@ -0,0 +1,104 @@ +import { PlayerInfo, PlayerType } from "../src/core/game/Game"; + +describe("PlayerInfo", () => { + describe("clan", () => { + test("should extract clan from name when format is [XX]Name", () => { + const playerInfo = new PlayerInfo( + "fr", + "[CL]PlayerName", + PlayerType.Human, + null, + "player_id", + ); + expect(playerInfo.clan).toBe("CL"); + }); + + test("should extract clan from name when format is [XXX]Name", () => { + const playerInfo = new PlayerInfo( + "fr", + "[ABC]PlayerName", + PlayerType.Human, + null, + "player_id", + ); + expect(playerInfo.clan).toBe("ABC"); + }); + + test("should extract clan from name when format is [XXXX]Name", () => { + const playerInfo = new PlayerInfo( + "fr", + "[ABCD]PlayerName", + PlayerType.Human, + null, + "player_id", + ); + expect(playerInfo.clan).toBe("ABCD"); + }); + + test("should extract clan from name when format is [XXXXX]Name", () => { + const playerInfo = new PlayerInfo( + "fr", + "[ABCDE]PlayerName", + PlayerType.Human, + null, + "player_id", + ); + expect(playerInfo.clan).toBe("ABCDE"); + }); + + test("should return null when name doesn't start with [", () => { + const playerInfo = new PlayerInfo( + "fr", + "PlayerName", + PlayerType.Human, + null, + "player_id", + ); + expect(playerInfo.clan).toBeNull(); + }); + + test("should return null when name doesn't contain ]", () => { + const playerInfo = new PlayerInfo( + "fr", + "[ABCPlayerName", + PlayerType.Human, + null, + "player_id", + ); + expect(playerInfo.clan).toBeNull(); + }); + + test("should return null when clan tag is not 2-5 uppercase letters", () => { + const playerInfo = new PlayerInfo( + "fr", + "[A]PlayerName", + PlayerType.Human, + null, + "player_id", + ); + expect(playerInfo.clan).toBeNull(); + }); + + test("should return null when clan tag contains non-uppercase letters", () => { + const playerInfo = new PlayerInfo( + "fr", + "[Abc]PlayerName", + PlayerType.Human, + null, + "player_id", + ); + expect(playerInfo.clan).toBeNull(); + }); + + test("should return null when clan tag is too long", () => { + const playerInfo = new PlayerInfo( + "fr", + "[ABCDEF]PlayerName", + PlayerType.Human, + null, + "player_id", + ); + expect(playerInfo.clan).toBeNull(); + }); + }); +});