Move team renaming logic o assignTeams()

This commit is contained in:
Mattia Migliorini
2026-03-09 13:06:06 +01:00
parent c1df0897f7
commit a484f6a3fc
2 changed files with 56 additions and 57 deletions
+2 -56
View File
@@ -49,7 +49,7 @@ import { RailNetwork } from "./RailNetwork";
import { createRailNetwork } from "./RailNetworkImpl";
import { Stats } from "./Stats";
import { StatsImpl } from "./StatsImpl";
import { assignTeams, computeClanTeamName } from "./TeamAssignment";
import { assignTeams } from "./TeamAssignment";
import { TerraNulliusImpl } from "./TerraNulliusImpl";
import { UnitGrid, UnitPredicate } from "./UnitGrid";
@@ -214,61 +214,7 @@ export class GameImpl implements Game {
...this._nations.map((n) => n.playerInfo),
];
const playerToTeam = assignTeams(allPlayers, this.playerTeams);
// Only rename numbered teams (8+ team mode), not colored teams
const coloredTeamValues = Object.values(ColoredTeams);
const isNumberedTeams = !this.playerTeams.some((t) =>
coloredTeamValues.includes(t),
);
if (isNumberedTeams) {
// Build reverse map: team → assigned players
const teamToPlayers = new Map<Team, PlayerInfo[]>();
for (const [pi, team] of playerToTeam.entries()) {
if (team === "kicked") continue;
if (!teamToPlayers.has(team)) teamToPlayers.set(team, []);
teamToPlayers.get(team)!.push(pi);
}
// Compute candidate names
const renameMap = new Map<Team, Team>();
for (const [oldTeam, teamPlayers] of teamToPlayers.entries()) {
const newName = computeClanTeamName(teamPlayers);
if (newName !== null && newName !== oldTeam) {
renameMap.set(oldTeam, newName);
}
}
// Collision check: repeatedly remove renames that collide with existing
// team names or with each other until no more removals occur.
let changed = true;
while (changed) {
changed = false;
const existingNames = new Set(
this.playerTeams.filter((t) => !renameMap.has(t)),
);
const newNames = Array.from(renameMap.values());
for (const [oldTeam, newName] of renameMap.entries()) {
if (
existingNames.has(newName) ||
newNames.filter((n) => n === newName).length > 1
) {
renameMap.delete(oldTeam);
changed = true;
}
}
}
// Apply renames to playerTeams array (preserves index order for teamSpawnArea)
this.playerTeams = this.playerTeams.map((t) => renameMap.get(t) ?? t);
// Apply renames to playerToTeam
for (const [pi, team] of playerToTeam.entries()) {
if (team !== "kicked" && renameMap.has(team)) {
playerToTeam.set(pi, renameMap.get(team)!);
}
}
}
// this.playerTeams is updated in-place by assignTeams
for (const [playerInfo, team] of playerToTeam.entries()) {
if (team === "kicked") {
+54 -1
View File
@@ -1,6 +1,6 @@
import { PseudoRandom } from "../PseudoRandom";
import { simpleHash } from "../Util";
import { PlayerInfo, PlayerType, Team } from "./Game";
import { ColoredTeams, PlayerInfo, PlayerType, Team } from "./Game";
export function assignTeams(
players: PlayerInfo[],
@@ -84,6 +84,59 @@ export function assignTeams(
result.set(player, team);
}
// Only rename numbered teams (8+ team mode), not colored teams
const coloredTeamValues = Object.values(ColoredTeams);
const isNumberedTeams = !teams.some((t) => coloredTeamValues.includes(t));
if (isNumberedTeams) {
// Build reverse map: team → assigned players
const teamToPlayers = new Map<Team, PlayerInfo[]>();
for (const [pi, team] of result.entries()) {
if (team === "kicked") continue;
if (!teamToPlayers.has(team)) teamToPlayers.set(team, []);
teamToPlayers.get(team)!.push(pi);
}
// Compute candidate names
const renameMap = new Map<Team, Team>();
for (const [oldTeam, teamPlayers] of teamToPlayers.entries()) {
const newName = computeClanTeamName(teamPlayers);
if (newName !== null && newName !== oldTeam) {
renameMap.set(oldTeam, newName);
}
}
// Collision check: repeatedly remove renames that collide with existing
// team names or with each other until no more removals occur.
let changed = true;
while (changed) {
changed = false;
const existingNames = new Set(teams.filter((t) => !renameMap.has(t)));
const newNames = Array.from(renameMap.values());
for (const [oldTeam, newName] of renameMap.entries()) {
if (
existingNames.has(newName) ||
newNames.filter((n) => n === newName).length > 1
) {
renameMap.delete(oldTeam);
changed = true;
}
}
}
// Apply renames to teams array in-place (preserves index order for teamSpawnArea)
for (let i = 0; i < teams.length; i++) {
teams[i] = renameMap.get(teams[i]) ?? teams[i];
}
// Apply renames to result map
for (const [pi, team] of result.entries()) {
if (team !== "kicked" && renameMap.has(team)) {
result.set(pi, renameMap.get(team)!);
}
}
}
return result;
}