Skip to content

moyunzero/foolish-you

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

42 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

傻了么 (Brainfool)

一款极简的每日益智移动应用:每天打开,系统会在 数独8×8 二进制谜题(Takuzu / Binairo)8×8 数绘(Nonogram / Picross)7×7 数回(Slitherlink) 中随机分配一局。玩完或认怂后,用带点毒舌的文案收尾;第二天 0 点自动换新题。

无社交、无排行榜、无填格提示——专注「今天这一局」。

给 AI / 协作者: 生产约束与分层规则见 AGENTS.md;验证、CR、手测清单见 docs/DEVELOPMENT.mddocs/TESTING.md;GSD 工作流见 CLAUDE.md


功能概览

能力 说明
每日一题 按本地自然日 + 种子确定题型与盘面,同一天多次打开内容一致
数独 9×9 标准数独,冲突高亮,完成 / 认怂
二进制谜题 8×8,每行每列各 4 个 0 与 4 个 1,禁止三连、行列不重复
数绘 8×8 Nonogram,行列提示填格,完成后校验,结果页揭示图案
数回 7×7 Slitherlink,点边画闭合单环,冲突高亮,结果页揭示回路
离线优先 谜题在设备端生成与校验,无需联网
进度持久化 AsyncStorage 保存今日状态,杀进程后可续玩
结果页 随机搞笑文案 + Reanimated 入场动效、「明天再来」提示
本局计时 游戏页显示 MM:SS 用时;前后台切换与系统时间校正(防计时回跳)
规则说明 游戏页标题旁 ? 弹窗查看玩法
v1.1 emoji 战报 结果页「拷贝战报」:emoji 网格 + 用时/连签,写入剪贴板(expo-clipboard
v1.1 结果统计卡 今日用时、本周完成天数、历史最长连签(三列小卡)
v1.1 评分引导 通关后按门槛延迟唤起系统应用商店评分(expo-store-review,可关闭、不阻塞流程)
v1.1 防御性保障 每日选题可解性校验 + 内置 fallback;快照损坏修复;completed 与残缺棋盘矛盾时剥离 playState
v1.2 系统语言 跟随设备 zh / en(英文品牌 Brainfool);双语隐私政策;正式版应用内语言设置
v2.0 数回 7×7 Slitherlink 加入每日随机;边线三态画环、冲突高亮、结果页揭示回路(无剧透战报)
v2.0 连签护盾 每周自动发放 1 张护盾(最多堆叠 2);漏玩 1 天时打开 App 自动消耗护盾续连签
v2.0 昨日错过召回 漏玩且未触发护盾时,游戏页标题下显示召回副文案(与护盾生效文案互斥)

仍不包含: 登录账号、每日推送提醒(规划 v2.1)、个人统计页(规划 v2.1)、填格提示、社交/排行榜/好友(见 路线图)。


技术栈

支持 iOSAndroid(托管工作流,未提交 ios/ / android/ 原生目录)。


环境要求

  • Node.js 22 LTS(与 CI 一致;仓库根目录 .nvmrc22
  • npm 11+(与 CI 一致;本项目以 package-lock.json 为准,请用 npm ci 安装)
  • iOS:Xcode + 模拟器(仅 macOS),或 Expo Go
  • Android:Android Studio 模拟器,或真机 + Expo Go

快速开始

# 克隆仓库
git clone https://github.com/moyunzero/foolish-you.git
cd foolish-you

# 安装依赖
npm install

# 启动开发服务器
npm start

在终端按 i 打开 iOS 模拟器,按 a 打开 Android 模拟器,或扫码用 Expo Go 连接。

若修改过 babel.config.js(如 Reanimated 插件)或原生依赖,请清缓存后启动:

npx expo start -c

常用命令

命令 说明
npm start 启动 Expo 开发服务器
npm run ios 在 iOS 模拟器/设备上运行(需预构建或 dev client)
npm run android 在 Android 上运行
npm run web Web 预览(非主要目标平台)
npm test 运行 Jest 单元 + RTL 测试(谜题、存储、Context、屏幕)
npm run test:migration 仅跑存储迁移黄金样例(与 CI 一致)
npm run typecheck TypeScript 严格检查(tsc --noEmit
npm run lint ESLint(expo lint

项目结构

完整目录与「新代码放哪」见 docs/DEVELOPMENT.md § Code layout。架构与数据流见 docs/ARCHITECTURE.md

foolish-you/
├── app/                    # expo-router 页面(无谜题算法)
├── components/
│   ├── grid/               # SudokuGrid、BinaryGrid、NonogramGrid、SudokuNumpad
│   ├── slitherlink/        # SlitherlinkBoard(边三态交互)
│   ├── game/               # 各题型 Section、Header/Footer、规则弹窗
│   ├── result/             # 徽章、统计卡、战报、数绘/数回揭示卡
│   ├── ui/ · legal/ · dev/
├── contexts/               # DailyGameContext、DevToolsUiContext
├── hooks/                  # 各题型 board hooks、useGameBoardSession、useElapsedTimer
├── lib/
│   ├── date/ · daily/ · puzzles/ · storage/ · streak/ · completion/
│   ├── share/ · stats/ · rating/ · time/ · copy/ · i18n/ · dev/ · platform/
├── locales/                # zh / en
├── constants/              # config、design、dev、legal
└── __tests__/              # lib/ · contexts/ · hooks/ · components/ · screens/

核心流程

  1. 启动DailyGameContext 读取或创建「今日档案」(dateKey + seed + gameType + 盘面)。
  2. 选题lib/puzzles/dailySelectorSafe.ts(可解性校验 + 必要时 fallback)根据日期种子在数独 / 二进制 / 数绘 / 数回间稳定随机,并生成可解盘面。
  3. 游玩app/game.tsx 根据 gameType 渲染对应网格与底栏;进度防抖写入本地。
  4. 结束 → 完成或认怂 → app/result.tsx 展示文案与动效;次日 dateKey 变化后自动新局。

开发调试

开发模式下(__DEV__)可在首页使用 开发者面板(重开今日、强制题型、设置占位预览语言等),配置见 constants/dev.ts

// constants/dev.ts
export const DEV_FORCE_GAME_TYPE: GameType | null = 'sudoku'; // null = 与线上一致随机;可选 'binary' | 'nonogram' | 'slitherlink'

正式 Release 构建不会包含该面板。


测试

npm test

当前覆盖:日期工具、RNG、每日选题与 safe 选题、数独/二进制/数绘/数回生成与校验、存储迁移/恢复、完成历史、战报与统计、评分门槛、连签、i18n(含 en-smoke)、Context 与主要屏幕 RTL(402 项)。另含 npm run test:migration 迁移黄金样例。UI 动效与真机布局以手测为主。


构建与发布(概要)

使用 EAS Build 或本地预构建:

# 需先安装 eas-cli 并登录 Expo 账号
npx eas build --platform ios
npx eas build --platform android

app.json 中已配置应用名 傻了么、Bundle ID com.moyunzero.foolish-you、深色界面。发布前请自行替换图标、签名与商店元数据。


版本与规划

详见内部 .planning/ROADMAP.md

设计宪法(红线 · 不可破)

  • 离线优先dateKey + seed 决定盘面,永不远程下发
  • 一天一局:不变成「每日 3 题」,今天的张力来自唯一性
  • 不做:排行榜、好友、IM、IAP、广告、提示按钮、可堆叠超过 2 的护盾
  • 毒舌幽默是品牌护城河,所有文案都要过这一关

北极星与节奏

阶段 D1 D7 D30 评分 完成 → 分享率
v1.0(已上架基线) 已公测 0%(无入口)
v1.1 目标(≈ 3 月) 32% 12% 5% ≥ 4.4 ≥ 3%
当前 v2.0(2.0.0,代码已交付) 待公测 待公测 待公测 目标 ≥ 4.5 目标 ≥ 5%
v2.0 后 ≈ 6 月 35%+ 15%+ 7%+ ≥ 4.5 ≥ 5%
12 月目标 38% 18% 9% 4.6 7%

目标是把「傻了么」从 Puzzle 子类中位推进到 Top 25%(行业 35/15/5 基准)。

版本路线

版本 状态 范围 关键押注(数据锚点)
v1.0 已发布 每日数独 / 二进制 / 数绘(不含数回)、本地进度、连签、结果动效、计时、规则弹窗
v1.1 已发布(1.1.x ① 结果页 emoji 战报拷贝(lib/share/ + expo-clipboard);② 评分引导(通关 + 完成局数等门槛,expo-store-review);③ 结果页三数据小卡(今日用时 / 本周完成 / 历史最长连签,historicalMax);④ 防御:selectDailyGameSafe、快照 recoverSnapshot、计时校正、迁移 + recovery 单测、Dev 恢复日志 Wordle 90→300K DAU 来自一键 emoji 分享
v1.2 已发布(1.2.0 系统语言 zh/en(expo-localization);英文品牌 Brainfoollocales/ + useI18n;双语隐私;DevTools 设置占位(不写存储,Release 无入口) 海外可读性 + 商店合规
v2.0 当前(2.0.0,代码已交付;商店发版收口见 closeout) 数回 7×7(Slitherlink:生成器、边线 UI、揭示卡/战报);✅ Streak Freeze(每周 1 张、最多堆 2、漏 1 天自动消耗);✅「昨日错过」召回副文案;⏳ 每日提醒 → v2.1;⏳ 个人统计页 → v2.1 Duolingo:streak 寿命 +48%;7 天 streak 用户次日留存 2.4×
v2.1 规划中 周节奏难度(仍每天 1 局);本月日历;月度数绘图鉴长图;每日提醒(原 v20-02);个人统计页(原 v20-03) NYT Mini/Midi 节奏
v3.0 规划中 iCloud / Google 端到端同步或 QR 导入导出;30 天历史归档 避免与「离线优先 / 无社交」冲突
v4.0 规划中 匿名挑战码;Year in 傻了么 年终长图 朋友间话题,无好友列表

完整决策依据、AB 实验设计与对照取舍见 .planning/ROADMAP.md(已加入 .gitignore,不随仓库公开)。


设计说明

视觉与交互约定见本地 DESIGN.md(已加入 .gitignore,不随 GitHub 公开)。


许可证

尚未指定开源许可证。若你 fork 或二次发布,请先与仓库维护者确认授权。


致谢

谜题算法与产品灵感来自经典数独与 Takuzu/Binairo 规则;由 Expo 与 React Native 生态驱动交付。

徽章

version

使用示例

玩家:完成今日一局

  1. 启动 App → app/index.tsx 根据今日档案跳转到 app/game.tsx
  2. 游戏页顶栏 GameScreenHeader 显示日期、本局用时、题型标题、连签副文案(streakLine),以及可选的护盾/召回副行(GameStreakSubline,护盾生效与昨日错过互斥)。
  3. 填完盘面后点底栏 完成今日GameScreenFooter)→ 校验通过则进入结果页;认怂不计入连签。
  4. 结果页可点 拷贝战报(需保留有效 playState;恢复后若棋盘已剥离则仅展示文案与统计)。
  5. 次日本地 dateKey 变更后自动换新题。

连签与护盾(通关入账)

  • 仅通关计入连签,认怂不调用 applyCheckIn(见 contexts/DailyGameContext.tsx)。
  • 逻辑:lib/streak/streakLogic.ts(连续自然日 +1,断档归零);持久化:lib/storage/streakStorage.ts(键 @foolish-you/streak-v1,schema v3,含 historicalMaxfreezeCount 等)。
  • 护盾(Streak Freeze)lib/streak/freezeLogic.ts — 每周 ISO 周首次打开发放 1 张(上限 2);若距上次入账恰好漏 1 天且无真实完成记录,hydrate 时自动消耗 1 张续连签。
  • 昨日错过召回lib/streak/missedYesterdayBanner.ts — 漏玩且未消耗护盾时,游戏页标题下显示召回文案(与护盾生效行互斥)。
  • 文案:顶栏连签 lib/copy/streak.ts;护盾/召回 lib/copy/freeze.tslib/copy/missedYesterday.ts;结果统计卡护盾后缀见 locales/*/copy.ts

开发者:提交前本地检查(与 CI 一致)

GitHub Actions 工作流 .github/workflows/ci.ymlmain / master 的 push 与 PR 上执行:

npm run typecheck        # tsc --noEmit
npm test                 # Jest:unit(*.test.ts)+ rtl(*.test.tsx)
npm run test:migration   # 存储迁移黄金样例
npm run lint             # expo lint
npm run lockfile:verify-eas  # npm 10 ci,EAS 构建前建议跑

可选拆分:

npm run test:unit   # 谜题、存储、连签等纯逻辑
npm run test:rtl    # Context 与屏幕级 RTL 测试

文档

文档 说明
AGENTS.md AI/协作者:生产约束、分层规则、验证入口
docs/ARCHITECTURE.md 架构、数据流、离线优先与持久化
docs/GETTING-STARTED.md 安装与首次运行
docs/DEVELOPMENT.md 日常开发、CI 校验、DevTools
docs/TESTING.md Jest 双项目与手测清单
docs/CONFIGURATION.md app.json、EAS、常量与存储键

About

傻了么 — 每日随机谜题,离线优先的 Expo 益智 App

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages