// Partie für Trailer und Galerie vorab berechnen (läuft in Node, gebündelt von trailer.mjs). // Der Bot spielt die Tageskarte; danach wird die Partie beim besten Stand abgeschnitten (wie „End game“). import {BOTS} from '../../src/engine/core/bots.ts' import {Game} from '../../src/engine/core/Game.ts' import {starsOf} from '../../src/engine/core/goals.ts' import {mulberry32} from '../../src/engine/core/rng.ts' import type {UnitType} from '../../src/engine/core/units.ts' export {UNIT_TYPES} from '../../src/engine/core/units.ts' import {goalsOf} from '../../src/server/verify.ts' import {dailyBoard, dailyMap} from '../../src/shared/daily.ts' export interface Plan { day: string seed: number trait: string goals: {gold: number; lands: number} /** net = Gold-Saldo des Zugs (für die Wahl des Galeriebilds) */ moves: {unit: UnitType; cell: number; net: number}[] stars: number gold: number lands: number /** Partie endet von selbst (kein Zug mehr) statt per „End game“ */ natural: boolean } export function plan(day: string, seed: number): Plan { const map = dailyMap(new Date(`${day}T00:00:00Z`)) const goals = goalsOf(map) const game = new Game(dailyBoard(map), {undoLimit: 0}) const rng = mulberry32(seed) const all: Plan['moves'] = [] let best = {len: 0, key: -1} while (!game.isGameOver()) { const m = BOTS.smart(game, rng) const before = game.score game.place(m.unit, m.cell) all.push({unit: m.unit, cell: m.cell, net: game.score - before}) const s = starsOf(game, goals) const key = s.count * 100_000 + game.score if (key >= best.key) best = {len: all.length, key} } const moves = all.slice(0, best.len) const end = new Game(dailyBoard(map), {undoLimit: 0}) for (const m of moves) end.place(m.unit, m.cell) return { day, seed, trait: map.trait, goals: {gold: goals.gold, lands: goals.lands}, moves, stars: starsOf(end, goals).count, gold: end.score, lands: end.regionCounts()[0] ?? 0, natural: end.isGameOver(), } }