mirror of
https://github.com/profullstack/logicsrc.git
synced 2026-08-14 23:07:29 +00:00
75 lines
2.3 KiB
TypeScript
75 lines
2.3 KiB
TypeScript
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<string, GameFactory>();
|
|
|
|
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");
|
|
}
|