CYBERSWAT / 开发部自由练习 · v0.4.1

U07 · 不看页面,也能知道游戏是否结束

v0.4 · 先修:数组、模块、手册 22 的测试基础;工作台。选题参考:Odin Battleship。本节规则为原创缩小版。

先做一个 5×5 的练习棋盘,放若干占一格的目标,点击格子判断是否命中。第一版只有单人清除全部目标,之后再增加两人轮流攻击;不同时做拖拽、联网和电脑策略。

动手路线:每一步都有文件和结果

先完成 统一启动与恢复手册 的首次准备。以下命令均在自己的练习根目录执行;原文中的 api/web/desktop 概念对应本节列出的现成文件,不需要猜测如何搭空项目。

  1. 打开 u07/starter/model.ts,按 createBoard → fire 的顺序逐个实现。下面第1节起解释规则;每完成一个函数就重跑样例/测试。
  2. 执行以下三条,分别核对样例、行为和类型。未完成的 TODO 应失败,全部实现后测试应为 fail 0:
node tools/try.mjs u07
node tools/check.mjs u07
npm run check
  1. 打开 runtime/web/u07.js,找到对自己规则函数的调用。先用一句话记录输入从哪里来、结果写到哪里;读不懂的语法回到本节先修对应章节。

  2. 构建并启动自己的作品:

node tools/build-app.mjs u07
node tools/lab.mjs start u07
  1. 实际操作:两人轮流操作同一页面。玩家1打0,0,玩家2打1,1,玩家1打1,1,玩家2打2,1;玩家2获胜,所有格子禁用;开始新局恢复25格。

  2. 解释与再做一次:命中后回合怎样改变?为何既要按钮禁用,也要规则拒绝重复和结束后攻击? 在自己的 LEARNING.md 先写答案,再选本节末尾的变式,列一个新失败例子后修改。保持原用例通过。仅跑通配套界面、没有完成规则与解释,记录为“参考演示已观察”,不记录为自己完成作品。

卡在规则时按“函数输入→分支条件→返回值→参考实现”逐级看提示;卡在运行时按 故障表 定位。若想单独观察参考成品,在构建命令后加 --reference;页面会明确标出参考演示。观察完再去掉该参数重建,继续自己的 starter。

1. 用坐标描述棋盘

打开 u07/starter/model.ts,Board 保存 size、ships、shots。坐标从 0 开始,5×5 的合法范围是 0–4。先在纸上画出 (1,1) 与 (2,1),预测 (5,0) 为什么不在棋盘内。字符串 x,y 只是内部索引,界面可以显示更友好的名称。

完成 createBoard:边长限 1–20 的整数,目标不能为空,坐标必须是范围内整数且不重叠。运行 node tools/try.mjs u07,得到两个目标与空攻击记录。创建棋盘不应偷偷发起一次攻击。

2. 一次攻击只改变一份状态

完成 fire:先检查越界、游戏是否已结束和是否重复攻击,再返回新棋盘、hit、over。命中数不用另存一份计数,可从目标与攻击集合判断。保留旧棋盘,方便比较前后差异。

执行 node tools/check.mjs u07。先读未命中→命中→全部击中的顺序,再主动在 sample.json 改成错误坐标。重复点已经攻击的格子必须拒绝,不能让一次命中累加成“击沉更多目标”。

3. 写一个最小页面

按手册 13/14 建页面,把 25 个 button 放在网格中,每个按钮保存坐标并有可读标签,例如“第 2 行第 3 列,未攻击”。点击后只调用 fire,再按新状态渲染。TS 规则接原生页面时先按工作台转为 JS,或使用手册 Vue/TS 工具链。

未攻击、未命中、命中除了颜色还要有文字或符号。键盘能到达每个可操作格子;已经攻击的按钮可禁用,但服务规则仍要能拒绝重复调用。胜利时显示结果并停止继续攻击。

4. 加回合时,先定义非法动作是否消耗回合

第二版准备两个独立棋盘和 currentPlayer。规定只有有效攻击才交换回合,重复/越界不消耗回合;结束以后不能再交换。先写一个不涉及页面的 nextTurn 测试,再接界面。

本机双人轮流时增加交接屏,交接前不展示对方目标位置。固定目标用于验证,随机放置作为后续功能,不让随机性影响基础测试。

5. 排错与自检

现象 优先检查
同一格两次都算命中 shots 是否在判断前已经检查;是否重复追加
边角格不可点或越界 页面行列编号是否与 0 起点模型一致
颜色变了但刷新渲染恢复 是否只改 DOM,未更新模型
输赢后仍可攻击 规则是否检查结束状态,而不只禁用按钮

完整检查需覆盖边界格、非整数、目标重叠、重复攻击、全部命中、结束后操作、双人合法/非法回合和键盘。核心测试只覆盖单棋盘规则,不覆盖第二版回合与页面。

6. 独立变式与停靠点

增加“重开一局”:目标布局相同,攻击历史和回合重置,原局记录可以作为只读复盘保留。先预测重开后再打同一格应允许,再实现。以后扩成长船时另定义连续性、方向与整船击沉,不能把本节单格目标直接冒称完整海战规则。

暂停时保存代码和测试,关闭页面即可。完成者可走 U08 学习另一种状态:随时间失效的缓存。