diff --git a/src/modules/doantu/README.md b/src/modules/doantu/README.md index eb3fafd..9416f6f 100644 --- a/src/modules/doantu/README.md +++ b/src/modules/doantu/README.md @@ -27,7 +27,9 @@ ignored (no cost, no stat inflation). Target words + similarity scores come from our self-hosted **phow2sim** instance (default: `https://phow2sim.sg.miti99.com`). Wraps two endpoints: -- `GET /random` — pick a secret Vietnamese word at round start. +- `GET /random` — pick a secret Vietnamese word at round start. Targets + are filtered to the top-frequency band (`min_rank=100`, `max_rank=1000`) + so rounds stay guessable for casual players. - `GET /similarity?a=…&b=…` — cosine similarity + canonical forms + `in_vocab_a` / `in_vocab_b` flags. diff --git a/src/modules/doantu/handlers.js b/src/modules/doantu/handlers.js index 539d52c..21233a2 100644 --- a/src/modules/doantu/handlers.js +++ b/src/modules/doantu/handlers.js @@ -19,6 +19,9 @@ import { renderBoard, renderGuess } from "./render.js"; import { clearGame, loadGame, loadStats, recordResult, saveGame } from "./state.js"; const UPSTREAM_FAIL = "⚠️ Upstream hiccup — try again in a few seconds."; +// Keep targets inside the top-frequency band so the game stays guessable. +// phow2sim ranks by corpus frequency; lower rank = more common. +const RANDOM_FILTERS = { min_rank: 100, max_rank: 1000 }; function getSubject(ctx) { const type = ctx.chat?.type; @@ -43,7 +46,7 @@ function logFail(stage, err) { } async function startFreshGame(db, client, subject) { - const picked = await client.randomWord(); + const picked = await client.randomWord(RANDOM_FILTERS); const target = String(picked?.word ?? "").toLowerCase(); if (!target) throw new UpstreamError("empty target from randomWord"); const fresh = { target, startedAt: null, solved: false, guesses: [] };