6.3 KiB
领域规则:三枚铜币与六爻
状态:MVP 强制规范 适用范围:所有起卦算法、显示模型、持久化模型和相关测试
本文件定义本项目唯一允许的计算规则。UI 文案、AI 输出和数据源都不能覆盖这些规则。
实现状态:coin-v1 纯 Kotlin 核心位于 app/src/main/java/brainwave/domain/casting/;.\gradlew.bat :app:test --offline 覆盖 8 种币面、4,096 种六爻、64 模式、已知夹具和 DTO 往返。记录时间与内容版本在确定性计算完成后附加。
1. 术语和类型
建议使用有语义的封闭类型,避免裸 Int 在层间传播:
enum class CoinSide(val value: Int) {
CHARACTER(2), // 字面
REVERSE(3), // 背面
}
enum class LineValue(val sum: Int, val polarity: Polarity, val moving: Boolean) {
OLD_YIN(6, Polarity.YIN, true),
YOUNG_YANG(7, Polarity.YANG, false),
YOUNG_YIN(8, Polarity.YIN, false),
OLD_YANG(9, Polarity.YANG, true),
}
enum class Polarity { YIN, YANG }
代码片段只表达契约,最终实现的包名和细节以系统架构为准。
2. 铜币计值约定
MVP 固定采用:
- 字面
CHARACTER计 2; - 背面
REVERSE计 3; - 每轮三枚相加,结果只可能是 6、7、8、9。
传统资料对“正/反”“阴/阳”与 2/3 的命名存在不同约定,因此界面不得只写含糊的“正面/反面”。首次使用和投币页必须始终显示当前计值:“字 2,背 3”。如果未来允许切换约定,约定必须在第一轮之前锁定并写入结果;不得在六轮中途改变。
3. 爻值映射
| 和值 | 名称 | 本卦爻形 | 是否动爻 | 之卦爻形 |
|---|---|---|---|---|
| 6 | 老阴 | 阴爻,断线 | 是 | 阳爻,实线 |
| 7 | 少阳 | 阳爻,实线 | 否 | 阳爻,实线 |
| 8 | 少阴 | 阴爻,断线 | 否 | 阴爻,断线 |
| 9 | 老阳 | 阳爻,实线 | 是 | 阴爻,断线 |
强制不变量:
- 偶数 6、8 为阴;奇数 7、9 为阳。
- 只有 6 和 9 为动爻。
- 之卦只翻转动爻;静爻保持不变。
- AI、网络、时间、问题文本和设备状态均不得影响上述映射。
4. 六次录入与顺序
数组和数据库中的标准顺序一律为 bottom-up:
| 数组索引 | 中文位置 | 投币轮次 |
|---|---|---|
| 0 | 初爻 | 1 |
| 1 | 二爻 | 2 |
| 2 | 三爻 | 3 |
| 3 | 四爻 | 4 |
| 4 | 五爻 | 5 |
| 5 | 上爻 | 6 |
绘制界面时可以从屏幕顶部先画上爻,但只能在展示适配层反转;领域对象、序列化数据和测试夹具不得改成 top-down。
一个有效投币过程必须满足:
- 恰好六轮;
- 每轮恰好三枚;
- 每枚只能是
CHARACTER或REVERSE; - 生成结果后保留原始 18 枚输入,便于复核和审计。
5. 本卦与之卦
CastResult 至少包含:
methodVersion
coinConvention
rounds[6][3]
lineValuesBottomUp[6]
primaryPatternBottomUp[6]
movingLinePositions[] // 1..6,升序
transformedPatternBottomUp[6]
primaryHexagramId // 文王卦序 1..64
transformedHexagramId // 文王卦序 1..64
contentVersion
createdAt // 只用于记录,不参与计算
卦号不能通过“二进制数 + 1”推断。文王卦序不是简单二进制顺序,必须使用经过校验的“上卦 × 下卦”映射表或完整六爻模式映射表。
算法顺序:
- 将每轮三枚计值相加为
LineValue。 - 按录入顺序形成 bottom-up 六爻。
- 从各爻阴阳形成本卦模式并查得本卦编号。
- 收集值为 6 或 9 的位置作为动爻。
- 仅翻转动爻阴阳,形成之卦模式并查得之卦编号。
- 先将全部原始输入和确定结果构造成不可变
CastComputation,再附加methodVersion、coinConvention、contentVersion与createdAt记录元数据,组成不可变CastResult;元数据不得反向影响步骤 1~5。
6. 读取内容的产品规则
MVP 采用透明而不过度裁决的显示策略:
- 始终显示本卦卦辞。
- 无动爻:明确显示“无动爻”;之卦与本卦相同,可弱化重复内容。
- 有动爻:按初爻到上爻显示本卦中所有实际动爻的爻辞,并显示之卦。
- 多个动爻:不由算法擅自选出“唯一主爻”,也不隐藏其他动爻。
- 乾卦六爻皆九、坤卦六爻皆六时,若采用的数据版本含“用九/用六”,应作为特殊文本额外展示;是否纳入 MVP 见决策记录。
AI 可以组织和解释这些材料,但不得改变显示集合。
7. 状态机
DRAFT(question)
└─ start → CASTING(confirmedRounds = 0..5)
├─ edit previous → CASTING
├─ confirm sixth → SEALED(CastResult)
└─ cancel → DRAFT
SEALED
├─ request local explanation → EXPLAINED_LOCAL
├─ consent + request AI → EXPLAINING_AI → EXPLAINED_AI | AI_FAILED
└─ explicit restart → DRAFT(newSessionId)
禁止从 EXPLAINING_AI 或 EXPLAINED_AI 回写 CastResult。重新起卦必须创建新的会话标识。
8. 必须存在的确定性测试
| 输入(初爻到上爻) | 本卦 | 之卦 | 动爻 |
|---|---|---|---|
7,7,7,7,7,7 |
乾 1 | 乾 1 | 无 |
8,8,8,8,8,8 |
坤 2 | 坤 2 | 无 |
9,9,9,9,9,9 |
乾 1 | 坤 2 | 1–6 |
6,6,6,6,6,6 |
坤 2 | 乾 1 | 1–6 |
7,8,8,8,8,8 |
复 24 | 复 24 | 无 |
9,8,8,8,8,8 |
复 24 | 坤 2 | 初爻 |
此外必须:
- 穷举 8 种三枚铜币排列,验证求和与
LineValue。 - 穷举 4⁶ = 4,096 种六爻数值组合,验证长度、动爻和变换不变量。
- 验证 64 种阴阳模式恰好映射到 64 个不重复卦号。
- 验证序列化再反序列化不改变任何确定字段。
9. 版本规则
- 初始算法版本建议为
coin-v1。 - 改变字/背计值、动爻规则、顺序或卦号映射都属于破坏性领域变更,必须新增版本和决策记录,不能静默覆盖历史结果。
- 内容措辞变化只提升
contentVersion,不得改变methodVersion。
参考资料仅用于交叉核验;仓库内上述规则才是实现事实源: