Skip to content

Refactor Tracker Lifecycle and Game State Reset Flow#32

Merged
llsccm merged 4 commits into
devfrom
refactor/game-state
Jul 16, 2026
Merged

Refactor Tracker Lifecycle and Game State Reset Flow#32
llsccm merged 4 commits into
devfrom
refactor/game-state

Conversation

@llsccm

@llsccm llsccm commented Jul 16, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • 新功能
    • 更新“吉占”结果展示:大小判断与牌面数量统计。
  • 改进
    • 优化记牌器对局状态/座位同步与渲染刷新流程。
    • “严教”分牌按钮改为点击复制文案,减少分配交互干扰。
    • 暂停触发的部分技能效果,提升稳定性。
  • 文档
    • 重写项目架构与生命周期、记牌器流程及开发规范说明。
  • 测试
    • 扩充并参数化记牌器与牌堆/公区一致性测试。

@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

本次变更重构 Tracker 生命周期钩子与状态重置流程,调整开局和法术处理入口,停用部分交互与自动触发逻辑,扩展技能处理器,并同步更新测试、项目文档及仓库规则。

Changes

Tracker 生命周期与入口

Layer / File(s) Summary
GameState 生命周期钩子与重置流程
src/tracker/gameState.ts, src/tracker/Game.ts, src/tracker/Room.ts, tests/tracker/room.import.test.ts
GameState 新增生命周期钩子和集中式状态重置逻辑,BrowserGameState 改用受保护钩子,房间座位同步调用及对应生命周期测试同步调整。
Tracker 开局入口与生命周期文档
src/handler/StartGame.js, docs/agents/card_tracker.md, docs/agents/lifecycle.md
开局玩家注册固定使用当前用户标识;文档更新初始化、挂载、协议分发、卡牌移动及销毁流程。

法术与工具行为

Layer / File(s) Summary
法术处理器与注册表
src/handler/skills/*, src/handler/spellEffects.js, tests/tracker/spellEffects.test.ts
新增 JiZhan 和 YanXi 处理器,导出牌堆查询函数,并停用 3033、7016、7017 的注册项。
工具、活动与渲染逻辑
src/draw.js, src/logic.js, src/utils/index.js
停用严教分配交互和活动自动触发,统一使用共享的 setSuitRecord,并更新两项卡牌缩写。

验证与仓库说明

Layer / File(s) Summary
Tracker 参数化测试与一致性断言
tests/tracker/gameFlowState.test.ts, tests/tracker/hiddenMarkCandidates.test.ts, tests/tracker/pileDisplayOrder.test.ts, tests/tracker/viewDirtyRender.test.ts
测试改用参数化场景、共享辅助函数和公区一致性断言,覆盖牌堆展示、占位替换、隐藏标记、游戏流程及脏渲染状态。
仓库规则与项目说明
.gitignore, AGENTS.md, docs/agents/commands.md, docs/agents/overview.md, docs/agents/serena.md
新增 /plans 忽略规则,禁止文档绑定源码行号,并更新终端规范、项目范围和 Tracker 记忆条目。

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ProtocolHandler
  participant GameState
  participant BrowserGameState
  participant Room
  ProtocolHandler->>GameState: 调用 init/start/enter/record
  GameState->>BrowserGameState: 分发生命周期钩子
  ProtocolHandler->>Room: 注册玩家
  Room->>BrowserGameState: 同步房间座位
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 10.71% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title Check ✅ Passed Title check skipped as CodeRabbit has written the PR title.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/game-state

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot changed the title @pr Refactor Tracker Lifecycle and Game State Reset Flow Jul 16, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/tracker/gameState.ts (1)

213-219: 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

修复 start() 钩子因 isGameStart 被拦截的问题及相关测试。

由于 init() 已将 isGameStart 置为 true,导致后续的正常流程中调用 start() 时,必定触发 if (this.isGameStart) return 提前返回。这将导致 onStart() 钩子(以及子类中的 laya.init() 等核心副作用)在真实对局流中永远无法被执行。测试用例由于在 start() 前意外插入了 end() 而掩盖了此缺陷。

  • src/tracker/gameState.ts#L213-L219: 引入独立的防重入标志(如 this.hasTriggeredStart,并在 resetSessionState 中将其初始化为 false)来替代此处的 this.isGameStart 拦截条件。
  • tests/tracker/room.import.test.ts#L106-L108: 移除为绕过上述拦截而多余调用的 gameState.end()
  • tests/tracker/room.import.test.ts#L120-L120: 同步更新事件断言,移除数组中多余的首个 'end' 字符串,使测试匹配真实的 init -> start -> ... 执行流。
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/tracker/gameState.ts` around lines 213 - 219, Update gameState.ts lines
213-219 in start() to guard against repeated start hooks with a dedicated
hasTriggeredStart flag, initialized to false in resetSessionState, while
preserving isGameStart for game-state tracking. In
tests/tracker/room.import.test.ts lines 106-108, remove the unnecessary
gameState.end() call; at lines 120-120, remove the leading 'end' event assertion
so the expected sequence matches init -> start -> ... .
🧹 Nitpick comments (1)
src/handler/skills/JiZhan.js (1)

23-36: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider using template literals for better readability.

可以使用模板字符串(Template Literals)来替代多行字符串拼接,使 HTML 结构的构造更加直观清晰。

💡 可选的重构建议
-    updateResult(
-      '<span class="textRes">【吉占】猜' +
-        (g > l ? '大' : '小') +
-        '</span>' +
-        '<br><span class="textRes">跟' +
-        cardNum +
-        '比,' +
-        g +
-        '张大\t\t' +
-        l +
-        '张小\t\t' +
-        e +
-        '平</span>'
-    )
+    updateResult(
+      `<span class="textRes">【吉占】猜${g > l ? '大' : '小'}</span><br><span class="textRes">跟${cardNum}比,${g}张大\t\t${l}张小\t\t${e}平</span>`
+    )
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/handler/skills/JiZhan.js` around lines 23 - 36, Refactor the HTML message
construction passed to updateResult to use a template literal instead of chained
string concatenation, preserving the existing text, interpolation of g, l,
cardNum, and e, and rendered line-break and span structure.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/draw.js`:
- Around line 472-484: Remove or revise the automatic-allocation hint associated
with the disabled handlers in the surrounding draw logic, including the message
near the button setup. Ensure the UI no longer claims that clicking the numbers
performs automatic allocation, while preserving the current click behavior that
bubbles to the button and copies text.

In `@src/utils/index.js`:
- Around line 261-264: Update setSuitRecord to verify that document is available
before calling document.getElementById, returning early in non-DOM environments
while preserving the existing missing-element guard and rendering behavior.

---

Outside diff comments:
In `@src/tracker/gameState.ts`:
- Around line 213-219: Update gameState.ts lines 213-219 in start() to guard
against repeated start hooks with a dedicated hasTriggeredStart flag,
initialized to false in resetSessionState, while preserving isGameStart for
game-state tracking. In tests/tracker/room.import.test.ts lines 106-108, remove
the unnecessary gameState.end() call; at lines 120-120, remove the leading 'end'
event assertion so the expected sequence matches init -> start -> ... .

---

Nitpick comments:
In `@src/handler/skills/JiZhan.js`:
- Around line 23-36: Refactor the HTML message construction passed to
updateResult to use a template literal instead of chained string concatenation,
preserving the existing text, interpolation of g, l, cardNum, and e, and
rendered line-break and span structure.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: da76fb09-9d9f-479b-a248-44abbe16f1b0

📥 Commits

Reviewing files that changed from the base of the PR and between 4b956c8 and 7c26ede.

📒 Files selected for processing (23)
  • .gitignore
  • AGENTS.md
  • docs/agents/card_tracker.md
  • docs/agents/commands.md
  • docs/agents/lifecycle.md
  • docs/agents/overview.md
  • docs/agents/serena.md
  • src/draw.js
  • src/handler/StartGame.js
  • src/handler/skills/JiZhan.js
  • src/handler/skills/YanXi.js
  • src/handler/spellEffects.js
  • src/logic.js
  • src/tracker/Game.ts
  • src/tracker/Room.ts
  • src/tracker/gameState.ts
  • src/utils/index.js
  • tests/tracker/gameFlowState.test.ts
  • tests/tracker/hiddenMarkCandidates.test.ts
  • tests/tracker/pileDisplayOrder.test.ts
  • tests/tracker/room.import.test.ts
  • tests/tracker/spellEffects.test.ts
  • tests/tracker/viewDirtyRender.test.ts

Comment thread src/draw.js
Comment thread src/utils/index.js

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the game state management and skill handlers, and updates the project documentation. Specifically, it splits GameState into a pure base class and a browser-specific subclass using protected lifecycle hooks (onInit, onEnd, etc.), extracts the JiZhan and YanXi skill handlers into separate files, and cleans up unused utility functions. Additionally, the test suite has been refactored to use parameterized tests, and the documentation has been updated to remove fragile line-number anchors. The review feedback correctly points out that the newly extracted JiZhan and YanXi handlers are commented out and missing imports in spellEffects.js, and provides suggestions to register them and update the corresponding test assertions.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread src/handler/spellEffects.js
Comment thread tests/tracker/spellEffects.test.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (4)
src/tracker/gameState.ts (3)

213-219: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

确认 onStart 的触发时机是否符合预期。

目前 this.onStart() 被置于 this.isGameStart 保护判断之前调用,这意味着如果 start() 发生重复调用,onStart 生命周期钩子也会被多次触发。如果原本意图是仅仅在游戏初次开始时触发一次该钩子,建议将其移动到状态判断逻辑的下方。

♻️ 建议的修改(如果仅需触发一次)
   start(): void {
-    this.onStart()
     if (this.isGameStart) return
 
+    this.onStart()
     this.isGameStart = true
     this.isPassed = false
   }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/tracker/gameState.ts` around lines 213 - 219, 调整 GameState.start() 中
onStart() 的调用时机:先执行 isGameStart 的重复启动判断,仅在首次启动并完成状态更新后触发 onStart(),确保重复调用
start() 不会再次触发生命周期钩子。

259-260: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

移除注释掉的代码。

建议直接移除注释掉的无用代码,以保持代码库的整洁。

♻️ 建议的修改
-      // 第一轮开始时 检测开始状态
-      // if (turn === 1) this.start()
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/tracker/gameState.ts` around lines 259 - 260, Remove the commented-out
this.start() call beneath the first-round start-state comment in the
turn-handling logic, while leaving the surrounding active code and meaningful
comment unchanged.

101-110: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

删除 setTurn() 里的注释代码
src/tracker/gameState.ts:259-260 这段 // if (turn === 1) this.start() 已经不会执行,保留只会增加噪音。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/tracker/gameState.ts` around lines 101 - 110, Remove the obsolete
commented-out `if (turn === 1) this.start()` code from the `setTurn()` method in
`gameState.ts`, leaving the method’s active turn-handling logic unchanged.

Sources: Coding guidelines, Learnings

src/handler/skills/JiZhan.js (1)

24-24: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

建议替换 HTML 字符串中的 \t\t 以确保正确的视觉间距。

在标准的 HTML 渲染中,连续的空白字符(包括制表符 \t)通常会被折叠成一个普通的空格。如果使用 \t\t 是为了在 UI 上提供视觉层面的分隔,它在浏览器中实际上可能无法生效。建议使用 HTML 实体(如 &nbsp;)或通过外层 CSS 样式控制来实现间距。

🎨 建议的修复方案(使用 HTML 实体)
-      `<span class="textRes">【吉占】猜${g > l ? '大' : '小'}</span><br><span class="textRes">跟${cardNum}比,${g}张大\t\t${l}张小\t\t${e}平</span>`
+      `<span class="textRes">【吉占】猜${g > l ? '大' : '小'}</span><br><span class="textRes">跟${cardNum}比,${g}张大&nbsp;&nbsp;&nbsp;&nbsp;${l}张小&nbsp;&nbsp;&nbsp;&nbsp;${e}平</span>`
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/handler/skills/JiZhan.js` at line 24, Update the HTML string in the
JiZhan result rendering to replace the literal tab separators between the 大、小、平
counts with reliable HTML spacing, preferably using the appropriate
non-breaking-space entity. Preserve the existing text content and interpolation
logic.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/handler/skills/JiZhan.js`:
- Line 24: Update the HTML string in the JiZhan result rendering to replace the
literal tab separators between the 大、小、平 counts with reliable HTML spacing,
preferably using the appropriate non-breaking-space entity. Preserve the
existing text content and interpolation logic.

In `@src/tracker/gameState.ts`:
- Around line 213-219: 调整 GameState.start() 中 onStart() 的调用时机:先执行 isGameStart
的重复启动判断,仅在首次启动并完成状态更新后触发 onStart(),确保重复调用 start() 不会再次触发生命周期钩子。
- Around line 259-260: Remove the commented-out this.start() call beneath the
first-round start-state comment in the turn-handling logic, while leaving the
surrounding active code and meaningful comment unchanged.
- Around line 101-110: Remove the obsolete commented-out `if (turn === 1)
this.start()` code from the `setTurn()` method in `gameState.ts`, leaving the
method’s active turn-handling logic unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: f957ad3c-30ab-4cf9-9e35-23e2bd354a74

📥 Commits

Reviewing files that changed from the base of the PR and between 7c26ede and 7a680c3.

📒 Files selected for processing (5)
  • src/draw.js
  • src/handler/skills/JiZhan.js
  • src/tracker/Game.ts
  • src/tracker/gameState.ts
  • src/utils/index.js
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/draw.js
  • src/utils/index.js
  • src/tracker/Game.ts

@llsccm
llsccm merged commit 6f68329 into dev Jul 16, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant