95 lines
2.7 KiB
TypeScript
Executable file
95 lines
2.7 KiB
TypeScript
Executable file
#!/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 <path:string>",
|
|
"Sets dictionnary to use words from (defaults to internal french dict).",
|
|
).option(
|
|
"-n, --length <length:number>",
|
|
"Length of the word to use from the dictionnary.",
|
|
).option(
|
|
"-m, --max <max:number>",
|
|
"Maximum number of iterations.",
|
|
).option(
|
|
"-w, --wait <wait:number>",
|
|
"Time to wait between guesses, in ms.",
|
|
{ default: 0 },
|
|
).option(
|
|
"-t, --target <target:string>",
|
|
"Target word to search for.",
|
|
).option(
|
|
"-g, --guesser <guesser:string>",
|
|
`Guesser to use, available are ${[...guessers.keys()]}.`,
|
|
{ default: "reducing" },
|
|
)
|
|
.option(
|
|
"-l, --logger <logger:string>",
|
|
`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<string, (dict: Dict) => Guessing>([
|
|
["explorer", (dict: Dict) => new ExplorerGuesser(dict)],
|
|
["reducing", (dict: Dict) => new ReducingGuesser(dict)],
|
|
]);
|
|
|
|
const loggers = new Map<string, LoggingStrategy>([
|
|
["verbose", new VerboseLogging()],
|
|
["table", new TableLogging()],
|
|
]);
|
|
|
|
if (import.meta.main) await main();
|