名称大小 / 类型
build
29 项2.6 MB
css
2 项22 KB
functions
8 项15 KB
js
6 项33.3 MB
.gitattributes
164 BGITATTRIBUTES
.gitignore
99 BGITIGNORE
build-variant.mjs
15 KBJavaScript
deploy.sh
1.1 KBShell
diag-boot.py
1.7 KBPython
index.html
11 KBHTML
probe.py
1.6 KBPython
README.md
5.7 KBMarkdown
test-live.py
5.1 KBPython
test-online.py
18 KBPython
test-rank-parity.mjs
9.6 KBJavaScript
test-split.py
7.5 KBPython
wrangler.toml
82 BTOML
README.md
GuessWord
多语言语义猜词游戏(Semantle 类)。
- 玩法:猜一个单词,系统告诉你它和神秘词的语义距离排名(1 = 答案,越小越近),提示不限次,难度按等级区间选择。
- 六种语言:英语(牛津 CEFR A1–C2)、日语(JLPT N5–N1)、韩语(延世韩国语 1–6 册)、法语/德语/西班牙语(语料词频 6 档)。
- 词库:英语 21,376 词(已清理专名与语料垃圾、合并变形);日语 21,867(JLPT 7,608 谜底 + 扩展);韩语 6,411;法/德/西各约 3.9 万。
- 语义引擎:ConceptNet Numberbatch 19.08(CC BY-SA 4.0)多语言 300 维词向量,int8 量化的余弦相似度排名。
- 线上版(Pages Functions):排名与词典都在服务端(
functions/api/*)。浏览器只拉每种语言 ~200KB 的轻量词表,切换语言接近秒开、永不卡界面;谜底加密存放在签名 token 里,直到揭晓前不落到浏览器。 - 离线版(单文件 / 本地双击):没有后端,浏览器内嵌词向量、本地算排名(
buildRanks())。 - 两条路径的排名逐位一致(
node test-rank-parity.mjs会拿六种语言逐词比对)。线上引擎不可用时自动回退到本地模式(下载该语言词向量包)。
- 线上版(Pages Functions):排名与词典都在服务端(
- 变形自动归并(英语):复数/时态/比较级/英式拼写自动算作原形(cats→cat、went→go、colour→color),内嵌 6,630 条映射。
- 词典:Wiktionary 释义(CC BY-SA)+ 中文翻译;非英语语言附读音(日语假名等),点任意词可查。线上按词查询(服务端词典分桶,
/api/def),不再整包下载。 - 未完成的对局会全部自动存档(本地保存 token/棋盘),首页"继续上局"或历史记录里的"未完成"区随时可接着玩,切换语言也能恢复。
- 附加:生词本、历史记录(含语言标签)、明暗主题、音效、移动端适配。全程无 emoji,线条 SVG 图标。
直接玩
线上:https://guessword-173.pages.dev/ (同一 Pages 项目的自定义域名会自动同步)
本地:双击 index.html 即可(零依赖、不需要服务器)。仓库内嵌英语 + 日语 + 韩语数据;法/德/西三种语言的数据不在仓库里,需要 build-variant.mjs 生成部署版(或在线游玩)。
离线单文件版:node build/bundle.mjs 生成 dist/guessword.html(把 index.html + css + js 全部内联回单个文件,方便分发)。
仓库结构
index.html— 页面结构(拆出来的入口,引用下面这些文件)css/app.css— 全部样式js/app.js— 全部游戏逻辑(可读、可搜索;原来是 34MB 单文件里的一整块)js/data-en.js/js/data-ja.js/js/data-ko.js— 各语言词向量 + 词典数据(生成产物,改动用build/脚本)js/data-extra.js— 法/德/西数据的占位(真实数据在D:/gw-dl/lang/pack-<L>.json、dict-<L>.json,部署时由构建脚本注入)functions/api/— 线上排名的 Pages Functions(_engine.js共享引擎 +new/guess/hint/def.js四个路由);__GW_VER__由构建脚本注入build/compose.mjs— 把上面这些合成单文件形态(构建与打包共用)build-variant.mjs— 生成部署变体到site/:壳(~0.4MB)+ 每语言词表 meta + 词向量/词典分片(本地回退用)+ 词典 256 分桶(/api/def用)+functions/,并注入 loaderdeploy.sh— 两阶段发布到 Cloudflare Pages(需要CLOUDFLARE_API_TOKEN/CLOUDFLARE_ACCOUNT_ID,可放在 gitignore 的deploy.local.env里)build/— 数据管线脚本:- 词向量:
nb-extract.mjs/nb-fallback.mjs/nb-swap.mjs(英语),extract-multi.mjs(多语言单遍提取) - 词表手术:
extract-kaikki.py/plan-vocab.py/apply-vocab.mjs - 多语言:
build-lang-vocab.py(JLPT/延世/词频词表)→build-pack-lang.mjs(量化打包);extract-kaikki-lang.py+merge-vocab-dict.py(词典) - 维护工具:
split-master.py(把单文件母本拆成当前结构)、set-dict.mjs(词典数据改动后回写js/data-<L>.js)、bundle.mjs(离线单文件产物)
- 词向量:
- 测试:
test-rank-parity.mjs— 服务端引擎 vs 客户端buildRanks()逐词逐位一致(六语言,含 HTTP 层)test-online.py <url>— 线上版全链路(不下载词向量、答题/提示/查词、未完成存档与跨语言续玩、回退本地模式)test-split.py [url]/test-live.py/probe.py/diag-boot.py— patchright 无头浏览器验证(test-variant.py已被test-online.py取代删除)
site/— 构建产物(gitignore,随时可用 build-variant.mjs 重建)
数据管线注意事项
- 改了词向量/词典内容必须 bump
build-variant.mjs顶部的VER(分片 immutable 一年缓存,靠 URL 破缓存);纯逻辑改动不用。 - 大型原始数据(Wiktionary/kaikki jsonl、ECDICT sqlite、Numberbatch 向量)不在仓库里,管线脚本需要它们在位才能重跑。
- 词表手术的核心护栏:
plan-vocab.py里"有独立词义的词不合并"(thought/spoke/gone 这类)、"无证据不动谜底级词"、词频选最优词元(does→do 而非 does→doe)。 - 浏览器对超大单文件有实际限制(实测本机 ~46MB 可加载、81MB 崩溃),所以母本只内嵌三语;分片部署不受此限制。
- 服务端排名每次请求要跑一遍全词表余弦(约 50–90ms CPU)。Cloudflare Workers 免费版单次调用 CPU 上限 10ms,付费版 30s;本项目的请求是持续性的重计算,若账号在免费计划上会出现 1102 错误——此时客户端会自动回退到本地词库模式(这也是回退路径存在的原因)。