add runner wrapping game execution
This commit is contained in:
parent
1156752e0a
commit
ba87099e0e
1 changed files with 91 additions and 0 deletions
91
src/lib/runner.ts
Normal file
91
src/lib/runner.ts
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
import { assertExists } from "https://deno.land/std@0.224.0/assert/assert_exists.ts";
|
||||||
|
|
||||||
|
import { Guessing } from "./guesser.ts";
|
||||||
|
import { Gaming, GuessResult } from "./game/game.ts";
|
||||||
|
import { last, wait } from "./utils.ts";
|
||||||
|
|
||||||
|
export class Runner<Ga extends Gaming, Gu extends Guessing> {
|
||||||
|
game;
|
||||||
|
guesser;
|
||||||
|
delay_ms;
|
||||||
|
turns;
|
||||||
|
logging;
|
||||||
|
|
||||||
|
constructor(game: Ga, guesser: Gu, logging: LoggingStrategy, delay_ms = 0) {
|
||||||
|
this.game = game;
|
||||||
|
this.guesser = guesser;
|
||||||
|
this.delay_ms = delay_ms;
|
||||||
|
this.turns = [] as Turn[];
|
||||||
|
this.logging = logging;
|
||||||
|
}
|
||||||
|
|
||||||
|
async play_all() {
|
||||||
|
this.logging.on_start(this.game.length());
|
||||||
|
while (true) {
|
||||||
|
const result = await this.guesser.guess(async (guess, known) => {
|
||||||
|
const result = await this.game.guess(guess, known);
|
||||||
|
this.turns.push({ guess, result });
|
||||||
|
this.logging.on_guess(known, guess, result);
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
if (result !== null) break;
|
||||||
|
await wait(this.delay_ms);
|
||||||
|
}
|
||||||
|
this.logging.on_finish(this.turns);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Turn = { guess: string; result: GuessResult };
|
||||||
|
|
||||||
|
function format_result(result: GuessResult) {
|
||||||
|
if (result.kind === "success") return "success";
|
||||||
|
let line = "";
|
||||||
|
for (const info of result.informations) {
|
||||||
|
if (info.kind === "abscent") line += ".";
|
||||||
|
if (info.kind === "somewhere") line += "*";
|
||||||
|
if (info.kind === "there") line += "#";
|
||||||
|
}
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface LoggingStrategy {
|
||||||
|
on_start(length: number): void;
|
||||||
|
on_guess(known: string, guess: string, result: GuessResult): void;
|
||||||
|
on_finish(turns: Turn[]): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class VerboseLogging implements LoggingStrategy {
|
||||||
|
on_start(length: number) {}
|
||||||
|
|
||||||
|
on_guess(known: string, guess: string, result: GuessResult): void {
|
||||||
|
console.log(" Knows:", known);
|
||||||
|
console.log("Guessing:", guess);
|
||||||
|
console.log(" Got:", format_result(result));
|
||||||
|
console.log();
|
||||||
|
}
|
||||||
|
|
||||||
|
on_finish(turns: Turn[]): void {
|
||||||
|
const last_ = last(turns);
|
||||||
|
assertExists(last_);
|
||||||
|
console.log("Stopped on", last_.guess, ".");
|
||||||
|
console.log("With", last_.result.kind, ".");
|
||||||
|
console.log("In", turns.length, "steps");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class TableLogging implements LoggingStrategy {
|
||||||
|
on_start(length: number): void {
|
||||||
|
const pad = (title: string) => title.padEnd(length);
|
||||||
|
console.log(`${pad("known")}\t${pad("guess")}\t${pad("result")}`);
|
||||||
|
console.log();
|
||||||
|
}
|
||||||
|
on_guess(known: string, guess: string, result: GuessResult): void {
|
||||||
|
console.log(`${known}\t${guess}\t${format_result(result)}`);
|
||||||
|
}
|
||||||
|
on_finish(turns: Turn[]): void {
|
||||||
|
const last_ = last(turns);
|
||||||
|
assertExists(last_);
|
||||||
|
console.log();
|
||||||
|
console.log(last_.result.kind, "in", turns.length, "steps");
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue