2048合并规则通过了,胜利按钮为什么仍然错:一次单文件游戏的独立验收

举报
yd_225778114 发表于 2026/10/22 10:50:09 2026/10/22
【摘要】 用码道辅助生成单文件2048后,独立测试发现胜利弹窗的备选按钮实际在继续游戏。本文记录失败证据、最小修正、8组回归测试与真实浏览器验收,区分算法、事件状态和部署完成。

为了准备华为云开放能力2048闯关活动,我用码道网页版辅助生成了一份单文件小游戏。页面不依赖npm、构建工具或CDN,键盘、触屏滑动和方向按钮共用一套移动逻辑。它有计分、最高分、撤销、游戏结束提示,以及合成2048之后的继续挑战。

这次最值得记录的结果,不是又做出一个2048,而是独立测试找到了一个容易被“算法测试全过”掩盖的问题:胜利弹窗里的“结束本局”按钮,实际上也在继续游戏。

本文只讨论本机取得的源码、实际测试和浏览器验证。写作时尚未创建活动沙箱或ECS,不能把本地能玩、AI总结完成、云端部署成功以及活动积分到账混成一个结论。

一、先明确一次移动到底发生什么

2048的一步可以拆成三个阶段:按方向压紧非零方块,相邻同值方块各合并一次,最后在有效移动后生成一个新方块。合并的顺序是规则,不只是实现细节。

例如左移一行:

移动前 移动后,不含随机新方块 本步得分
2,2,2,2 4,4,0,0 8
2,2,4,0 4,4,0,0 4
4,4,4,0 8,4,0,0 8
2,0,2,2 4,2,0,0 4

第二行尤其重要:两个2刚合成的4,不能在同一步又和原来的4合成8。只检查数字总和守恒,抓不住这种“同一步连续合并”错误,所以明确的规则样例与不变量检查缺一不可。

二、不要只测试另一份核心算法文件

生成的项目同时包含算法文件、测试脚本与内联HTML。如果测试只导入算法文件,即使全部通过,也不能证明网页内联的那份代码完全一致,更不能证明页面按钮接到了正确的状态转换上。

这次独立验收直接读取实际发布用的index.html,提取其中的内联脚本,在Node的vm隔离上下文中运行。测试提供最小DOM和本地存储替身,让脚本真实注册键盘、按钮与触屏事件,然后触发这些已经注册的回调。

为了构造接近胜利的棋盘,测试运行时向闭包注入一个只存在于测试中的夹具。它用于设置合成棋盘和读取状态,不写回HTML,也不把测试状态入口放进生产页面。这样可以把“最后一步合成2048”的验收稳定下来,不需要用几千次随机按键碰运气。

这里的DOM替身有明确边界:它能验证事件与状态逻辑,却不能证明浏览器布局、真实触屏手势或所有手机都正常。因此后面仍需用真实浏览器做单独检查。

三、失败证据是2048不等于0

回归用例先设置第一行1024、1024,其余位置为空,然后通过真正注册的ArrowLeft事件合成2048。确认胜利状态出现之后,再触发弹窗的备选按钮。

预期是新局:本局分数归零、胜利标记清除、棋盘只保留两个初始方块。实际测试却失败:

AssertionError: new round must reset the score
2048 !== 0

查到对应事件后,原因很清楚:两个选择最后都走向了继续游戏。备选按钮原来执行的是:

keepGoing = true;
render();

这段代码能正确关闭胜利遮罩,也不会抛异常。如果验收只看“点了以后弹窗消失”,很容易误判成功。但它没有清空分数,也没有重新生成棋盘,行为与文案不一致。

四、修正要小,对照要保留

修正没有重写合并算法,只把备选按钮文案改成“新开一局”,点击时调用已有的newGame()。主按钮仍然叫“继续挑战”,继续保留当前棋盘和分数。

测试也同时保留两条路径:备选按钮必须重置,主按钮必须不重置。如果只检查新局分数为零,却漏掉继续按钮,后续很可能把两个按钮一起接到newGame(),从一个错误变成另一个错误。

修正后的独立测试共8组,全通过。除胜利后的两条分支,还检查了单步合并、四方向映射、输入棋盘不被修改、无效移动不消耗随机数也不增加撤销记录、有效移动只加一个方块、撤销恢复棋盘和分数,以及触屏和屏幕方向按钮的事件接线。

其中一组枚举了由0、2、4、8、16组成的全部625种四格行,在四个方向上分别检查移动前后数字总和不变。它能覆盖很多压紧和方向转换错误,但不能替代前面的明确合并样例,也不能证明整个界面已经验收完毕。

五、再用真实浏览器补上界面这一层

在实际浏览器打开修正后的单文件页面,初始棋盘渲染16个格子和两个数字方块。通过方向键进行有效移动后,实际分数从0变为4;点击撤销后,本局分数恢复0,棋盘仍为16格。

这层检查证明了真实页面能加载、键盘能控制、分数能更新、撤销按钮能工作。它不等于已经在所有手机上测试,也不等于已经达到活动沙箱的公网部署要求。

一个有用的验收顺序是:先用确定性样例固定规则,再用不变量扩大输入覆盖,接着验证事件与状态转换,最后用真实浏览器确认界面和交互。每一层只回答自己的问题,不把上一层的绿色结果自动延伸成下一层的完成证明。

这份2048仍保留了最高分本地保存、最多20步撤销和继续挑战等功能;真正改进的是交付的可信度:一个“看起来完成”的按钮,现在有失败证据、最小修正和可重复运行的回归用例。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。