import type { WaitingGame } from "./types.js"; import { AgentSwarmGame } from "./games/agent-swarm.js"; import { HangmanGame } from "./games/hangman.js"; import { MinefieldGame } from "./games/minefield.js"; import { MoonRunnerGame } from "./games/moon-runner.js"; import { SnakeGame } from "./games/snake.js"; export type GameFactory = () => WaitingGame; export class ArcadeRegistry { private readonly games = new Map(); add(factory: GameFactory) { const game = factory(); if (this.games.has(game.id)) { throw new Error(`Arcade game already registered: ${game.id}`); } this.games.set(game.id, factory); } create(id: string) { const factory = this.games.get(id); if (!factory) { throw new Error(`Unknown arcade game "${id}". Run "logicsrc arcade list" to see available games.`); } return factory(); } list() { return Array.from(this.games.values()).map((factory) => { const game = factory(); return { id: game.id, title: game.title, description: game.description, controls: game.controls }; }); } choose(id: string | undefined, random = Math.random) { if (!id || id === "default") { return "hangman"; } if (id !== "random") { return id; } const games = this.list(); return games[Math.floor(random() * games.length)]?.id ?? "hangman"; } } export function createDefaultArcadeRegistry() { const registry = new ArcadeRegistry(); registry.add(() => new HangmanGame()); registry.add(() => new SnakeGame()); registry.add(() => new MoonRunnerGame()); registry.add(() => new MinefieldGame()); registry.add(() => new AgentSwarmGame()); return registry; } export function renderArcadeList(registry = createDefaultArcadeRegistry()) { const rows = registry.list(); const idWidth = Math.max(...rows.map((row) => row.id.length), 2); const titleWidth = Math.max(...rows.map((row) => row.title.length), 5); return [ "Waiting Arcade games", "", `${"id".padEnd(idWidth)} ${"title".padEnd(titleWidth)} description`, `${"-".repeat(idWidth)} ${"-".repeat(titleWidth)} ${"-".repeat(40)}`, ...(rows.length ? rows.map((row) => `${row.id.padEnd(idWidth)} ${row.title.padEnd(titleWidth)} ${row.description}`) : ["No games registered"]) ].join("\n"); }