add abstracted guesser interface

This commit is contained in:
JOLIMAITRE Matthieu 2024-04-30 16:40:11 +02:00
parent 72c7373343
commit aa98d8805b

View file

@ -1,9 +1,13 @@
import { assertExists } from "https://deno.land/std@0.224.0/assert/assert_exists.ts";
import { enumerate, range } from "./utils.ts";
import { Awaitable, enumerate, range } from "./utils.ts";
import { Dict } from "./dict.ts";
import { GuessResult } from "./game/game.ts";
export interface Guessing {
guess(try_: (guess: string, known: string) => Awaitable<GuessResult>): Promise<GuessResult | null>;
}
type Knowledge = {
letter: string;
at: Set<number>;
@ -11,7 +15,7 @@ type Knowledge = {
not_at: Set<number>;
};
export class Gueser {
export class Guesser implements Guessing {
length;
dict;
informations;
@ -25,9 +29,9 @@ export class Gueser {
}
}
async next_guess(operation: (guess: string, known: string) => GuessResult | Promise<GuessResult>) {
async guess(try_: (guess: string, known: string) => Awaitable<GuessResult>) {
const res = this.expected_result();
if (res.completed) return operation(res.result, res.result);
if (res.completed) return await try_(res.result, res.result);
const words = [...this.dict.words.values()];
const scored = words.map((word) => [this.info_score_for(word), word] as const);
@ -35,8 +39,8 @@ export class Gueser {
const bests = scored.filter(([s]) => s === best_score).map(([_, word]) => word);
const guess = pick_random_common_word(bests);
const result = await operation(guess, res.result);
if (result.kind === "success") return guess;
const result = await try_(guess, res.result);
if (result.kind === "success") return result;
for (const [index, info] of enumerate(result.informations)) {
const letter = guess[index];
if (info.kind === "there") this.learn_letter_at(letter, index);
@ -46,6 +50,7 @@ export class Gueser {
this.learn_letter_not_at(letter, index);
}
}
return null;
}
learn_does_not_exist(letter: string) {