「侦探事务所」是一个逻辑推理网页游戏。如果你玩过"爱因斯坦的谜题"(也叫斑马谜题 / Zebra Puzzle)——「英国人住红房子,瑞典人养狗,斑马是谁的?」——本游戏就是它的侦探主题剧情版。
每天提供 3 道不同难度的「逻辑网格」谜题(简单 / 中等 / 困难),玩家化身侦探,根据线索还原案件全貌:谁负责哪桩案件、用了哪件证物、案发于何时何地、嫌疑人是谁。
由 AC-3 约束传播算法保证每道题都有唯一解、无需试错;配有 5 套主题包(经典刑侦 / 古代刑名 / 校园悬案 / 海盗谜局 / 太空惊魂),每天按日期轮换,长期游玩不腻。
- 🎲 每日轮换:每天 3 道题(4×4 简单、5×5 中等、6×6 困难),365 天不重样
- 🎭 5 套主题包:经典刑侦 · 古代刑名 · 校园悬案 · 海盗谜局 · 太空惊魂;同一天三档共享世界观
- 🧠 算法保障:AC-3 约束传播验证每道题都有唯一解、可由步步推理求得,绝不需要"试错猜测"
- 📅 年度贡献图:GitHub 风格的全年进度地图,记录每天战绩
- 🕒 权威时间门控:服务器统一以 Asia/Shanghai 时区计算"今天",加 6 小时安全窗照顾海外玩家
- 🌗 完整可访问性:浅色 / 暗色 / 跟随系统三档主题,色盲安全调色板,高对比度模式
- 💾 本地优先持久化:进度自动保存到 IndexedDB,刷新不丢;带版本化迁移机制和多标签同步
- 📱 响应式设计:移动端 / 桌面端无缝切换,矩阵 / 线索视图一键互换
生产环境:https://detective-bureau.vercel.app(部署后填入实际地址)
右侧是若干已知线索,左侧是逻辑网格——每对类别(如侦探 × 案件)的交叉表格。
目标:推断每个格子是否成立,让每行每列恰好有一个"确认"。
同一格子反复点击会循环切换状态:
| 操作 | 状态 | 含义 |
|---|---|---|
| 点一次 | ✕ | 排除该关系 |
| 再点一次 | ✓ | 确认该关系,系统自动排除同行同列其它格 |
| 再点一次 | ○ | 清除标记 |
| 类型 | 例子 |
|---|---|
| 直接正向 | 连环纵火案的现场发现了神秘纸条 |
| 直接负向 | 江宁没有前往地铁站台 |
| 时段范围 | 谢璟是在下午时段接到出警通知的 |
| 时序前后 | 珠宝失窃案的报案时间早于豪宅入室案 |
时段定义:上午 06:00-11:59 | 下午 12:00-17:59 | 晚上 18:00-23:59。正午 12 点归"下午",傍晚 6 点归"晚上"。
- ⌨️ 撤回 / 重做:
Ctrl+Z/Ctrl+Y(Mac 用⌘+Z/⌘+⇧+Z) - 🔁 重置:双击「重置」清空当前题(连带清当日同档及下游难度的战绩)
- 💾 自动保存:每次操作实时落盘 IndexedDB,跨标签自动同步
- 🎯 练习模式:在历史页选已完成的日期点「练习」,重新挑战且不影响今日战绩
- 简单 → 中等 → 困难 依次解锁
- 完成简单后自动倒计时 8 秒进入中等(可取消)
- 困难完成后显示「🎉 今日已完成全部案件」
| 类别 | 技术 |
|---|---|
| 前端框架 | Next.js 16 (App Router, Turbopack) |
| UI | React 19 + Tailwind CSS 4 |
| 状态管理 | Zustand |
| 本地存储 | IndexedDB(通过 idb) |
| 数据库 | Turso / LibSQL(生产);本地 SQLite(开发) |
| 生成算法 | AC-3 约束传播(scripts/themes/) |
| 类型系统 | TypeScript 5 |
| 托管 | Vercel |
.
├── data/ # 本地开发用 SQLite 题库
├── scripts/
│ ├── generate-puzzles.mjs # 一年 1095 道题的批量生成器
│ ├── seed.mjs # 把本地题库同步到 Turso
│ └── themes/ # 5 套主题包(素材池 + 文案模板)
│ ├── classic.mjs
│ ├── ancient.mjs
│ ├── school.mjs
│ ├── pirate.mjs
│ ├── space.mjs
│ └── index.mjs
├── src/
│ ├── app/
│ │ ├── api/
│ │ │ ├── puzzle/[date]/ # 题目接口(带日期门控)
│ │ │ └── time/ # 权威时间接口
│ │ ├── history/ # 历史贡献图页
│ │ ├── layout.tsx
│ │ └── page.tsx # 主游戏页
│ ├── components/
│ │ ├── game/ # 逻辑矩阵 / 线索面板 / 完成横幅
│ │ ├── history/ # 贡献图
│ │ ├── AppHeader.tsx
│ │ ├── SettingsModal.tsx
│ │ └── TutorialModal.tsx
│ ├── lib/
│ │ ├── db/ # IndexedDB 持久化 + Turso 适配
│ │ ├── engine/ # 矩阵推理引擎(验证 / 提示 / 完成检测)
│ │ ├── hooks/
│ │ ├── store/ # Zustand stores
│ │ └── time/ # 服务器时区门控 + 会话日期锁定
│ └── types/
└── package.json
git clone https://github.com/<your-account>/detective-bureau.git
cd detective-bureau
npm installnpm run generate这一步会在 data/puzzles.db(本地 SQLite)里生成全年 1095 道题。无需联网,纯本地算法。
npm run dev浏览器打开 http://localhost:3000 即可。
生产环境推荐用 Vercel 跑代码、Turso 跑数据库(都有免费额度)。
# 安装 Turso CLI
curl -sSfL https://get.tur.so/install.sh | bash
# 登录并创建数据库
turso auth login
turso db create detective-bureau
# 拿到连接信息
turso db show detective-bureau --url # → libsql://xxx.turso.io
turso db tokens create detective-bureau # → 生成 auth token# 在 .env.local 里写好两个变量(参见下一节)
TURSO_DATABASE_URL=libsql://xxx.turso.io \
TURSO_AUTH_TOKEN=eyJ... \
npm run seed把仓库 push 到 GitHub,然后在 Vercel:
- Import Project → 选你的仓库
- Environment Variables:
TURSO_DATABASE_URL=libsql://xxx.turso.ioTURSO_AUTH_TOKEN=eyJ...PUZZLE_MAX_DAYS_AHEAD(可选,默认 1)= 服务器最多放出未来几天的题,防御纵深
- Deploy
| 变量 | 必填 | 说明 |
|---|---|---|
TURSO_DATABASE_URL |
生产必填 | Turso 数据库连接 URL |
TURSO_AUTH_TOKEN |
生产必填 | Turso 访问 token |
PUZZLE_MAX_DAYS_AHEAD |
✗ | 服务器最多放出多少天后的题(默认 1)。即便时区算偏了,API 也最多放出 today + 1 天 |
不设这两个 Turso 变量时会自动回落到本地
local.dbSQLite,便于零配置开发。
npm run dev # 启动开发服务器(Turbopack)
npm run build # 构建生产包
npm run start # 启动生产服务器
npm run lint # ESLint
npm run generate # 生成题库
npm run seed # 同步题库到 Turso- 在 scripts/themes/ 新建一个
xxx.mjs,参照 classic.mjs 的结构定义素材池、文案模板、标题 - 在 scripts/themes/index.mjs 的
THEMES数组里 append(一定 append 不要 insert,否则历史日期对应的主题会偏移) npm run generate重新生成题库npm run seed同步到 Turso
- 生成器只接受
ambiguousCount === 0的线索集,即仅靠 AC-3 传播就能解到唯一,玩家全程无需"假设 + 反推" - 每题至少 2 种线索类型(多样性 tiebreaker)
- 涉及主类别(侦探 / 船长 / 宇航员 …)的模板每题至多 1 次,避免"X 名字 + 动作"重复
欢迎 Issue 和 PR。建议先开 Issue 描述需求 / 问题,再提 PR。
- 新增主题包(提供 15 套素材 + 完整文案模板即可)
- 多语言支持(i18n)
- 跨设备同步(账号体系 / 云端历史)
- 分享成绩(Wordle 风格 emoji 网格)
- 排行榜 / 段位
Dossier (侦探事务所) — A daily Einstein-style logic puzzle game, themed as detective mysteries with 5 rotating worlds.
Copyright (C) 2026 liWanr
This project is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0).
If you modify and deploy this project as a network service, you must make the complete corresponding source code available under AGPL-3.0.
See the LICENSE file for details.
Built with ❤️ for puzzle lovers.