add move guesser interface
This commit is contained in:
parent
e2e2852739
commit
2e9c90dbca
6 changed files with 37 additions and 17 deletions
|
@ -1,12 +1,9 @@
|
||||||
import { assertExists } from "https://deno.land/std@0.224.0/assert/assert_exists.ts";
|
import { assertExists } from "https://deno.land/std@0.224.0/assert/assert_exists.ts";
|
||||||
|
|
||||||
import { Awaitable, enumerate, range } from "./utils.ts";
|
import { Awaitable, enumerate, range, zip } from "../utils.ts";
|
||||||
import { Dict } from "./dict.ts";
|
import { Dict } from "../dict.ts";
|
||||||
import { GuessResult } from "./game/game.ts";
|
import { GuessResult } from "../game/game.ts";
|
||||||
|
import { Guessing } from "./guesser.ts";
|
||||||
export interface Guessing {
|
|
||||||
guess(try_: (guess: string, known: string) => Awaitable<GuessResult>): Promise<GuessResult | null>;
|
|
||||||
}
|
|
||||||
|
|
||||||
type Knowledge = {
|
type Knowledge = {
|
||||||
letter: string;
|
letter: string;
|
||||||
|
@ -15,7 +12,7 @@ type Knowledge = {
|
||||||
not_at: Set<number>;
|
not_at: Set<number>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export class Guesser implements Guessing {
|
export class BaseGuesser implements Guessing {
|
||||||
length;
|
length;
|
||||||
dict;
|
dict;
|
||||||
informations;
|
informations;
|
||||||
|
@ -33,6 +30,9 @@ export class Guesser implements Guessing {
|
||||||
const res = this.expected_result();
|
const res = this.expected_result();
|
||||||
if (res.completed) return await try_(res.result, res.result);
|
if (res.completed) return await try_(res.result, res.result);
|
||||||
|
|
||||||
|
const possibilities = [...this.possible_words()];
|
||||||
|
if (possibilities.length === 1) return await try_(possibilities[0], res.result);
|
||||||
|
|
||||||
const words = [...this.dict.words.values()];
|
const words = [...this.dict.words.values()];
|
||||||
const scored = words.map((word) => [this.info_score_for(word), word] as const);
|
const scored = words.map((word) => [this.info_score_for(word), word] as const);
|
||||||
const best_score = scored.reduce((acc, [next]) => Math.max(acc, next), 0);
|
const best_score = scored.reduce((acc, [next]) => Math.max(acc, next), 0);
|
||||||
|
@ -93,8 +93,9 @@ export class Guesser implements Guessing {
|
||||||
if (information.exists === false) continue;
|
if (information.exists === false) continue;
|
||||||
if (information.at.has(index)) continue;
|
if (information.at.has(index)) continue;
|
||||||
if (information.not_at.has(index)) continue;
|
if (information.not_at.has(index)) continue;
|
||||||
if (information.exists === "unknown") total += this.length;
|
|
||||||
if (information.exists === true) total += this.length * this.length;
|
if (information.exists === "unknown") total += this.length ** 1;
|
||||||
|
if (information.exists === true) total += this.length ** 2;
|
||||||
}
|
}
|
||||||
const different_letters = new Set([...word]);
|
const different_letters = new Set([...word]);
|
||||||
total += different_letters.size;
|
total += different_letters.size;
|
||||||
|
@ -110,6 +111,19 @@ export class Guesser implements Guessing {
|
||||||
const completed = !result.includes(".");
|
const completed = !result.includes(".");
|
||||||
return { completed, result };
|
return { completed, result };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*possible_words() {
|
||||||
|
for (const word of this.dict.words.values()) if (this.matches_expected(word)) yield word;
|
||||||
|
}
|
||||||
|
|
||||||
|
matches_expected(word: string) {
|
||||||
|
const expected = this.expected_result();
|
||||||
|
for (const [act, exp] of zip(word, expected.result)) {
|
||||||
|
if (exp === ".") continue;
|
||||||
|
if (act !== exp) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function pick_random_common_word(bests: string[]) {
|
function pick_random_common_word(bests: string[]) {
|
6
src/lib/guesser/guesser.ts
Normal file
6
src/lib/guesser/guesser.ts
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
import { GuessResult } from "../game/game.ts";
|
||||||
|
import { Awaitable } from "../utils.ts";
|
||||||
|
|
||||||
|
export interface Guessing {
|
||||||
|
guess(try_: (guess: string, known: string) => Awaitable<GuessResult>): Promise<GuessResult | null>;
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
export { Dict } from "./dict.ts";
|
export { Dict } from "./dict.ts";
|
||||||
export { Guesser } from "./guesser.ts";
|
export { BaseGuesser } from "./guesser/base.ts";
|
||||||
export { Simulator } from "./game/simulator.ts";
|
export { Simulator } from "./game/simulator.ts";
|
||||||
export { ManualProxy } from "./game/proxy.ts";
|
export { ManualProxy } from "./game/proxy.ts";
|
||||||
export { Runner } from "./runner.ts";
|
export { Runner } from "./runner.ts";
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { assertExists } from "https://deno.land/std@0.224.0/assert/assert_exists.ts";
|
import { assertExists } from "https://deno.land/std@0.224.0/assert/assert_exists.ts";
|
||||||
|
|
||||||
import { Guessing } from "./guesser.ts";
|
import { Guessing } from "./guesser/guesser.ts";
|
||||||
import { Gaming, GuessResult } from "./game/game.ts";
|
import { Gaming, GuessResult } from "./game/game.ts";
|
||||||
import { last, wait } from "./utils.ts";
|
import { last, wait } from "./utils.ts";
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ interface LoggingStrategy {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class VerboseLogging implements LoggingStrategy {
|
export class VerboseLogging implements LoggingStrategy {
|
||||||
on_start(length: number) {}
|
on_start(_length: number) {}
|
||||||
|
|
||||||
on_guess(known: string, guess: string, result: GuessResult): void {
|
on_guess(known: string, guess: string, result: GuessResult): void {
|
||||||
console.log(" Knows:", known);
|
console.log(" Knows:", known);
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
import { Command } from "https://deno.land/x/cliffy@v1.0.0-rc.4/command/mod.ts";
|
import { Command } from "https://deno.land/x/cliffy@v1.0.0-rc.4/command/mod.ts";
|
||||||
|
|
||||||
import { Dict, Guesser, ManualProxy, Runner } from "./lib/lib.ts";
|
import { BaseGuesser, Dict, ManualProxy, Runner } from "./lib/lib.ts";
|
||||||
import { initialize_prompt } from "./lib/prompt.ts";
|
import { initialize_prompt } from "./lib/prompt.ts";
|
||||||
import { VerboseLogging } from "./lib/runner.ts";
|
import { VerboseLogging } from "./lib/runner.ts";
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ async function main() {
|
||||||
if (args.options.file !== undefined) dict = await Dict.from_text_file(args.options.file, init.length);
|
if (args.options.file !== undefined) dict = await Dict.from_text_file(args.options.file, init.length);
|
||||||
for (const [index, letter] of init.constraints) dict.constraint(index, letter);
|
for (const [index, letter] of init.constraints) dict.constraint(index, letter);
|
||||||
|
|
||||||
const guesser = new Guesser(dict);
|
const guesser = new BaseGuesser(dict);
|
||||||
const game = new ManualProxy(init.length);
|
const game = new ManualProxy(init.length);
|
||||||
|
|
||||||
const runner = new Runner(game, guesser, new VerboseLogging());
|
const runner = new Runner(game, guesser, new VerboseLogging());
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
import { Command } from "https://deno.land/x/cliffy@v1.0.0-rc.4/command/mod.ts";
|
import { Command } from "https://deno.land/x/cliffy@v1.0.0-rc.4/command/mod.ts";
|
||||||
|
|
||||||
import { Dict, Guesser, Runner, Simulator } from "./lib/lib.ts";
|
import { BaseGuesser, Dict, Runner, Simulator } from "./lib/lib.ts";
|
||||||
import { TableLogging } from "./lib/runner.ts";
|
import { TableLogging } from "./lib/runner.ts";
|
||||||
|
|
||||||
import { francais } from "../data/data.ts";
|
import { francais } from "../data/data.ts";
|
||||||
|
@ -28,7 +28,7 @@ async function main() {
|
||||||
let dict = Dict.from_lines(francais, args.options.length);
|
let dict = Dict.from_lines(francais, args.options.length);
|
||||||
if (args.options.file !== undefined) dict = await Dict.from_text_file(args.options.file, args.options.length);
|
if (args.options.file !== undefined) dict = await Dict.from_text_file(args.options.file, args.options.length);
|
||||||
|
|
||||||
const guesser = new Guesser(dict);
|
const guesser = new BaseGuesser(dict);
|
||||||
const game = Simulator.from_dict_rand(dict);
|
const game = Simulator.from_dict_rand(dict);
|
||||||
console.log("Target is", game.word);
|
console.log("Target is", game.word);
|
||||||
console.log();
|
console.log();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue