58 lines
2 KiB
TypeScript
58 lines
2 KiB
TypeScript
// 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(),
|
|
}
|
|
}
|