empire-cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +137 -0
- package/assets/gameplay-output.txt +117 -0
- package/dist/data/default-world-map.d.ts +3 -0
- package/dist/data/default-world-map.js +133 -0
- package/dist/engine/ai-turn-processor.d.ts +2 -0
- package/dist/engine/ai-turn-processor.js +75 -0
- package/dist/engine/army-manager.d.ts +28 -0
- package/dist/engine/army-manager.js +111 -0
- package/dist/engine/combat-resolver.d.ts +10 -0
- package/dist/engine/combat-resolver.js +73 -0
- package/dist/engine/resource-calculator.d.ts +22 -0
- package/dist/engine/resource-calculator.js +81 -0
- package/dist/game-types.d.ts +68 -0
- package/dist/game-types.js +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +320 -0
- package/dist/state/game-state-manager.d.ts +30 -0
- package/dist/state/game-state-manager.js +122 -0
- package/dist/ui/display-helpers.d.ts +8 -0
- package/dist/ui/display-helpers.js +80 -0
- package/package.json +27 -0
- package/src/data/default-world-map.ts +137 -0
- package/src/engine/ai-turn-processor.ts +76 -0
- package/src/engine/army-manager.ts +156 -0
- package/src/engine/combat-resolver.ts +92 -0
- package/src/engine/resource-calculator.ts +95 -0
- package/src/game-types.ts +80 -0
- package/src/index.ts +264 -0
- package/src/state/game-state-manager.ts +134 -0
- package/src/ui/display-helpers.ts +90 -0
- package/tsconfig.json +15 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// UI display helpers: icons, status, map, help text
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import type { GameState } from '../game-types.js';
|
|
4
|
+
import { findArmyInTerritory } from '../engine/army-manager.js';
|
|
5
|
+
|
|
6
|
+
export const ICONS: Record<string, string> = {
|
|
7
|
+
city: '🏰', forest: '🌲', mountain: '⛰️ ', plains: '🌾',
|
|
8
|
+
gold: '💰', food: '🍖', wood: '🪵', stone: '🪨',
|
|
9
|
+
army: '⚔️ ', skull: '💀', crown: '👑', shield: '🛡️ ',
|
|
10
|
+
flag: '🚩', peace: '🕊️ ', fire: '🔥',
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export function printLine(msg: string = ''): void {
|
|
14
|
+
console.log(msg);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function printSeparator(): void {
|
|
18
|
+
console.log(chalk.gray('─'.repeat(60)));
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function printStatus(state: GameState): void {
|
|
22
|
+
const player = state.factions.get(state.playerFactionId)!;
|
|
23
|
+
const colorFn = (chalk as any)[player.color] ?? chalk.white;
|
|
24
|
+
printSeparator();
|
|
25
|
+
printLine(colorFn(` ${ICONS.crown} ${player.name} — Turn ${state.turn}`));
|
|
26
|
+
printLine(` ${ICONS.gold} ${chalk.yellow(player.gold)} ${ICONS.food} ${chalk.green(player.food)} ${ICONS.wood} ${chalk.blue(player.wood)} ${ICONS.stone} ${chalk.gray(player.stone)}`);
|
|
27
|
+
printLine(` ${ICONS.army} Armies: ${player.totalArmies} | ${ICONS.flag} Territories: ${player.territories.length}/${state.territories.size}`);
|
|
28
|
+
printSeparator();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function printHelp(): void {
|
|
32
|
+
printLine(chalk.cyan('\n Commands:'));
|
|
33
|
+
printLine(' look — show world map');
|
|
34
|
+
printLine(' info <territory> — show territory details');
|
|
35
|
+
printLine(' status — show your resources');
|
|
36
|
+
printLine(' move <from> <to> [n] — move n units between territories (all if omitted)');
|
|
37
|
+
printLine(' recruit <territory> <n> — recruit n units (3💰 + 2🍖 each)');
|
|
38
|
+
printLine(' attack <from> <to> — attack enemy territory from yours');
|
|
39
|
+
printLine(' next — end turn (enemies act after this)');
|
|
40
|
+
printLine(' save [slot] — save game');
|
|
41
|
+
printLine(' quit — exit game');
|
|
42
|
+
printLine(' help — show this help');
|
|
43
|
+
printLine('');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function printMap(state: GameState): void {
|
|
47
|
+
const playerId = state.playerFactionId;
|
|
48
|
+
printLine(chalk.cyan('\n World Map:'));
|
|
49
|
+
printLine('');
|
|
50
|
+
for (const t of state.territories.values()) {
|
|
51
|
+
const ownerFaction = t.owner ? state.factions.get(t.owner) : null;
|
|
52
|
+
const ownerName = ownerFaction?.name ?? chalk.gray('Unclaimed');
|
|
53
|
+
const colorFn = ownerFaction ? ((chalk as any)[ownerFaction.color] ?? chalk.white) : chalk.gray;
|
|
54
|
+
const icon = ICONS[t.type] ?? '?';
|
|
55
|
+
const armies = t.armies > 0 ? ` ${ICONS.army} ${t.armies}` : '';
|
|
56
|
+
const yours = t.owner === playerId ? chalk.green(' ★') : '';
|
|
57
|
+
printLine(` ${icon} ${colorFn(t.name.padEnd(14))} ${colorFn(ownerName)}${armies}${yours}`);
|
|
58
|
+
const adjNames = t.adjacentTo.map((id) => state.territories.get(id)?.name ?? id).join(', ');
|
|
59
|
+
printLine(chalk.gray(` ↔ ${adjNames}`));
|
|
60
|
+
}
|
|
61
|
+
printLine('');
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Show detailed info about a specific territory
|
|
65
|
+
export function printTerritoryInfo(state: GameState, territoryName: string): void {
|
|
66
|
+
const t = [...state.territories.values()].find(
|
|
67
|
+
(t) => t.name.toLowerCase().includes(territoryName.toLowerCase())
|
|
68
|
+
);
|
|
69
|
+
if (!t) { printLine(chalk.red(`Territory "${territoryName}" not found.`)); return; }
|
|
70
|
+
|
|
71
|
+
const ownerFaction = t.owner ? state.factions.get(t.owner) : null;
|
|
72
|
+
const colorFn = ownerFaction ? ((chalk as any)[ownerFaction.color] ?? chalk.white) : chalk.gray;
|
|
73
|
+
const icon = ICONS[t.type] ?? '';
|
|
74
|
+
const playerId = state.playerFactionId;
|
|
75
|
+
|
|
76
|
+
printLine(`\n ${icon} ${colorFn(t.name)} (${t.type})`);
|
|
77
|
+
printLine(` Owner: ${ownerFaction?.name ?? 'Unclaimed'}`);
|
|
78
|
+
printLine(` ${ICONS.army} Armies: ${t.armies}`);
|
|
79
|
+
printLine(` Resources/turn: ${ICONS.gold}${t.resources.gold} ${ICONS.food}${t.resources.food} ${ICONS.wood}${t.resources.wood} ${ICONS.stone}${t.resources.stone}`);
|
|
80
|
+
printLine(` Neighbors:`);
|
|
81
|
+
for (const adjId of t.adjacentTo) {
|
|
82
|
+
const adj = state.territories.get(adjId)!;
|
|
83
|
+
const adjOwner = adj.owner ? state.factions.get(adj.owner)?.name ?? '?' : 'Unclaimed';
|
|
84
|
+
const adjIcon = ICONS[adj.type] ?? '';
|
|
85
|
+
const threat = adj.owner !== playerId && adj.armies > 0 ? chalk.red(` ${ICONS.army}${adj.armies}`) : '';
|
|
86
|
+
const friendly = adj.owner === playerId ? chalk.green(` ★`) : '';
|
|
87
|
+
printLine(` → ${adjIcon} ${adj.name} — ${adjOwner}${friendly}${threat}`);
|
|
88
|
+
}
|
|
89
|
+
printLine('');
|
|
90
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "NodeNext",
|
|
5
|
+
"moduleResolution": "NodeNext",
|
|
6
|
+
"outDir": "dist",
|
|
7
|
+
"rootDir": "src",
|
|
8
|
+
"strict": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"skipLibCheck": true,
|
|
11
|
+
"resolveJsonModule": true,
|
|
12
|
+
"declaration": true
|
|
13
|
+
},
|
|
14
|
+
"include": ["src/**/*"]
|
|
15
|
+
}
|