Repository navigation
fix: 修复小游戏状态、推箱子生成与围棋搜索和 GPU 降级 - #5
Conversation
| long now = System.currentTimeMillis(); | ||
| boolean shouldRecalculate = ghostPath.isEmpty() || (now - lastPathFindTime > PATH_FIND_INTERVAL); | ||
| // 游走后旧路径的起点不再是当前位置,必须重新寻路,避免跳回旧路径。 | ||
| boolean shouldRecalculate = ghostPath == null || ghostPath.isEmpty() |
There was a problem hiding this comment.
SUGGESTION: ghostPath == null check bypasses PATH_FIND_INTERVAL cooldown when no path exists
If findPath() returns null (no path found), ghostPath becomes null. The ghostPath == null condition makes shouldRecalculate true every ghost move tick, ignoring the 1-second PATH_FIND_INTERVAL cooldown. This could cause excessive pathfinding attempts in disconnected areas (though the maze generator ensures connectivity, so this is unlikely in practice).
Consider: boolean shouldRecalculate = ghostPath == null || ghostPath.isEmpty() || ghostPath.get(0)[0] != ghostX || ghostPath.get(0)[1] != ghostY || (ghostPath != null && now - lastPathFindTime > PATH_FIND_INTERVAL);
Reply with @kilocode-bot fix it to have Kilo Code address this issue.
| int[] nextStep = ghostPath.get(1); | ||
| ghostX = nextStep[0]; | ||
| ghostY = nextStep[1]; | ||
| ghostPath.remove(0); // 消耗已离开的节点,让缓存起点跟随鬼魂。 |
There was a problem hiding this comment.
SUGGESTION: ghostPath.remove(0) only called in chase branch, not random walk branch
When the ghost takes a random walk (50% chance), the cached path is not consumed. The path's first element becomes stale (no longer matches ghost position), forcing a recalculation on the next chase attempt. This is functionally correct but wastes the cached path. Consider consuming the path step in both branches or clearing the path on random walk.
Reply with @kilocode-bot fix it to have Kilo Code address this issue.
| private static char[][] generateOnce(int size, int boxCount, int obstacleCount, | ||
| int levelNum, Random random) { | ||
| char[][] grid = emptyGrid(size); | ||
| for (int i = 0; i < obstacleCount; i++) { |
There was a problem hiding this comment.
WARNING: Obstacle placement silently fails after 30 retries per obstacle
The inner loop attempts up to 30 times to find an empty cell for each obstacle. If the grid becomes crowded (many obstacles + boxes), it may fail to place all requested obstacles and continues silently. This results in fewer obstacles than obstacleCount specifies, making levels easier than intended, especially at higher levels.
Consider logging a warning or reducing obstacleCount dynamically if placement fails.
Reply with @kilocode-bot fix it to have Kilo Code address this issue.
| playerY = nextY; | ||
| } | ||
|
|
||
| // 保留全部目标和箱子,要求开局至少有一个箱子未归位。 |
There was a problem hiding this comment.
SUGGESTION: Validation only checks for off-target box ($), not actual solvability
The generator returns the grid if any $ exists, assuming the reverse-pull algorithm guarantees solvability. While the reverse-pull approach mathematically produces solvable levels, the validation doesn't independently verify this (the test hasPushSolution does). Adding a solver check here would catch any algorithmic bugs, though it would increase generation time.
Reply with @kilocode-bot fix it to have Kilo Code address this issue.
| char floor = grid[playerY][playerX] == '*' ? '.' : ' '; | ||
| int boxX = playerX - DX[direction]; | ||
| int boxY = playerY - DY[direction]; | ||
| char behind = grid[boxY][boxX]; |
There was a problem hiding this comment.
SUGGESTION: Array access grid[boxY][boxX] without explicit bounds check
boxX/boxY are calculated as playerX - DX[direction] / playerY - DY[direction]. Since player only moves to ' ' or '.' (never borders), and borders are walls ('#'), boxX/boxY can reach border indices (0 or size-1) but not exceed them. The access is safe but relies on maze structure invariants. An explicit bounds check or assertion would improve robustness.
Reply with @kilocode-bot fix it to have Kilo Code address this issue.
| // a cold or one-iteration search stop immediately, regardless of | ||
| // the policy. Give a board move the first visit before endgame; | ||
| // subsequent visits can still evaluate and select PASS normally. | ||
| if ((node.children == null || node.children.isEmpty()) |
There was a problem hiding this comment.
SUGGESTION: Assumes PASS is the last element in untriedMoves
The logic checks isPass(node.untriedMoves.get(index)) where index = size - 1, assuming PASS was appended last. If future changes reorder untriedMoves (e.g., policy-based sorting moves PASS elsewhere), this could expand PASS prematurely or skip the board-move preference logic. Consider finding PASS by predicate instead of positional assumption.
Reply with @kilocode-bot fix it to have Kilo Code address this issue.
| if (closed) return; | ||
| closed = true; | ||
| available = false; | ||
| // No native handles exist when loading JNA itself failed. Avoid |
There was a problem hiding this comment.
SUGGESTION: Early return if cl == null may leak partially initialized resources
If cl was successfully loaded but a later init() step failed (context, queue, program creation), cl is non-null but other native handles may be null. The early return skips freeActs(), freeWeights(), and kernel/program/queue/context cleanup. Since cl is set first in init(), this scenario is unlikely, but a try/finally in init() or tracking initialization state would be more robust.
Reply with @kilocode-bot fix it to have Kilo Code address this issue.
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Files Reviewed (5 files)
Previous Review Summary (commit 7323a16)Current summary above is authoritative. Previous snapshots are kept for context only. Previous review (commit 7323a16)Status: 8 Issues Found | Recommendation: Address before merge Overview
Issue Details (click to expand)WARNING
SUGGESTION
Files Reviewed (14 files)
Reviewed by free · Input: 150.5K · Output: 16.2K · Cached: 90.7K |
小游戏在快速转向、重开、退出确认后切换窗口以及迷宫追逐时可能出现错误状态;推箱子随机生成也可能产生无解关卡。围棋单次搜索会优先展开 PASS,缺少可选 JNA 依赖时 OpenCL 清理异常会阻止失败冷却生效。本 PR 修复这些可复现问题,并补充算法回归测试。
修复内容
最新验证
gradlew test --rerun build --no-build-cache --no-daemon --offline --max-workers=1 --console=plain通过,34 套件、240 项回归,失败/错误/跳过均为 0。git diff --check通过;本地针对性测试、报告和原始日志在忽略的.bench/pr5-review-20261009/保存。最新成品 SHA256:
31356784a00da537ae4ee3f8ad99fd8e074ce50a15e4ca22bb5cd49bdc2d05aa。审查建议评估
此前全局压力基线
初始修复提交
7323a16的成品此前通过 20,760 次重复测试方法检查、16 workers 下 640 万次联机会话调用逐项断言、2,000 局斗地主、128 局象棋及 120 局五子棋。RTX 2060 的 10 轮压力通过:30,720 次并发推理、60 次原生上下文生命周期、360 个变长批次和 120 次训练更新与 CPU 比较一致。32 款游戏共 640 次创建/关闭的界面弱引用全部回收;9 款游戏正常节奏运行 1,800 tick、89.957 秒,无声道耗尽。以上全局压力属于初始修复提交的验证;最新追加改进执行了本节上方的完整回归、生成压力和迷宫客户端检查,没有重复全部旧全局负载。测试未覆盖数小时耐久运行、真实双客户端网络对局或 KataGo/Pikafish 外部引擎。