#!/usr/bin/env -S deno run -A --unstable-temporal import { Command } from "https://deno.land/x/cliffy@v1.0.0-rc.4/command/mod.ts"; import { report, section, startup, tip, top, } from "https://git.barnulf.net/mb/profiterole/raw/commit/02d19fce2a0878abd176801cf8f2a663f6db6c16/mod.ts"; import { Dict, ExplorerGuesser, Guessing, LoggingStrategy, ReducingGuesser, Runner, Simulator, TableLogging, VerboseLogging, } from "./lib/lib.ts"; import { gutenberg } from "../data/data.ts"; import { last } from "./lib/utils.ts"; async function main() { const args = await new Command().name("simulation") .description( "Program to simulate TUSMO game with guesser controller.", ) .option( "-f, --file ", "Sets dictionnary to use words from (defaults to internal french dict).", ).option( "-n, --length ", "Length of the word to use from the dictionnary.", ).option( "-m, --max ", "Maximum number of iterations.", ).option( "-w, --wait ", "Time to wait between guesses, in ms.", { default: 0 }, ).option( "-t, --target ", "Target word to search for.", ).option( "-g, --guesser ", `Guesser to use, available are ${[...guessers.keys()]}.`, { default: "reducing" }, ) .option( "-l, --logger ", `Logger to use, available are ${[...loggers.keys()]}.`, { default: "verbose" }, ) .parse(Deno.args); const length = args.options.length ?? args.options.target?.length ?? 6; tip("dict"); let dict = Dict.from_lines(gutenberg, length); if (args.options.file !== undefined) dict = await Dict.from_text_file(args.options.file, length); top("dict"); const guesser = guessers.get(args.options.guesser)!(dict); let game = Simulator.from_dict_rand(dict); if (args.options.target !== undefined) game = new Simulator(validate_target(args.options.target, length)); console.log("Target is", game.word); console.log(); const runner = new Runner(game, guesser, new TableLogging(), args.options.wait, args.options.max); const result = last(await runner.play_all()); if (result === undefined) Deno.exit(1); if (result.result.kind === "failure") Deno.exit(1); report(); } function validate_target(target: string, length: number) { if (target.length !== length) throw new Error("Invalid target length"); return target.toLowerCase(); } const guessers = new Map Guessing>([ ["explorer", (dict: Dict) => new ExplorerGuesser(dict)], ["reducing", (dict: Dict) => new ReducingGuesser(dict)], ]); const loggers = new Map([ ["verbose", new VerboseLogging()], ["table", new TableLogging()], ]); if (import.meta.main) await main();