2048 游戏结束判定:棋盘满了,还要看相邻格

举报
yd_298688312 发表于 2026/10/30 12:45:01 2026/10/30
【摘要】 用四种棋盘状态实测 2048 的游戏结束判定:满格仍可合并时应继续,跨行边界不能误判;结束后无效移动不会生成新数字。

做 2048 时,一个很容易写错的条件是“16 个格子都不为空,就显示游戏结束”。满格只说明没有空位;只要相邻的两个数字相同,玩家仍能通过合并继续玩。我检查了自己的单文件游戏《2048·数字漫游》,并在本地页面构造棋盘,核对了判断函数、页面提示和无效移动的行为。

这个版本把棋盘按行放进长度为 16 的数组。canMove 的规则只有三条:存在空格、同一行的右侧邻格相等,或同一列的下方邻格相等。只要其中一条成立,就还能继续。

function canMove(source) {
  return source.some(v => v === 0) || source.some((v, i) =>
    (i % 4 < 3 && v === source[i + 1]) ||
    (i < 12 && v === source[i + 4])
  );
}

这里的边界值得单独检查。i % 4 < 3 阻止把一行末尾和下一行开头误认成水平邻居;i < 12 阻止最后一行继续向下取值。两处比较只看右方和下方,是因为左方、上方的相邻关系会在遍历其他格子时覆盖。

我在 Edge 打开本地 HTML,把棋盘临时设成四种状态,再调用页面原有的 render()。结果如下:

棋盘状态 canMove 页面结束提示
2、4 交错排列的满盘,无相邻相同数字 false 显示“本局结束”
满盘,第一行有一组水平相邻的 2 true 不显示结束
满盘,第一列有一组垂直相邻的 2 true 不显示结束
留一个空格 true 不显示结束

交错满盘还有一个容易漏掉的细节:第一行末尾与第二行开头恰好都是 4,但它们隔着行边界,并不是相邻格。实际测试中该棋盘的四个方向都没有变化,canMove 正确返回 false。如果去掉取模的边界条件,这类棋盘就可能被错判为仍可合并。

我又在这个结束状态下尝试向左移动。页面保持 16 个格子和 128 分不变,结束提示仍在,“撤销一步”保持禁用。原因是 move() 先检查 nextBoard() 的 changed;没有变化便直接返回,不会生成新数字,也不会覆盖撤销快照。这样游戏结束后的方向键不会偷偷改变状态。

这组检查只覆盖了我手工构造的棋盘和本地浏览器页面,没有穷举所有可能局面,也没有修改已发布作品。它给我的实际启发是:对这类棋盘游戏,测试“满但能合并”“满且不能合并”和“有空位”三类状态,比只测试正常开局更容易发现边界错误。

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

评论(0)

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

全部回复

上滑加载中

设置昵称

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

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

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