两年前写了一个贪吃蛇,算是十分简陋了。它有一个小漏洞,就是初始化时有一定的几率卡死,必须退出浏览器重进,我之前发现了这个问题,不过并未深究。

时至今日,我的编程能力突飞猛进之后,再保留这个 bug 就说不过去了。于是我开始定位 bug,很快就找到了无限循环的位置:

1
2
3
4
while(randSnakeHeadi - foodi < 5 && randSnakeHeadj - foodj < 5){
randSnakeHeadi = Math.floor(Math.random()*15)
randSnakeHeadj = Math.floor(Math.random()*15)
}

这里, randSnakeHeadirandSnakeHeadj 这两个变量用来表示新生成的贪吃蛇头的坐标, foodifoodj 表示的是食物坐标。判断当蛇头和食物的距离过近就重新生成贪吃蛇头的坐标,但我却犯了一个致命的错误,计算坐标的距离直接使用了减法,这样,当减号左边的量小于右边,就会得到负数!这是个不可原谅的错误。它会导致无限循环,食物坐标接近地图的边角,也就是数值最大(使用数组下标就是快接近数组长度),这个循环就没有结束条件了,只要生成的贪吃蛇坐标和食物的坐标距离在 5 以内,就会重新循环,一旦食物的坐标大于地图宽度 - 5,那么 randSnakeHeadi - foodi 便永远小于 5 , 无限循环。

解决办法也十分简单,计算距离的时候加上绝对值:

1
2
3
4
while(Math.abs(randSnakeHeadi - foodi) < 5 && Math.abs( randSnakeHeadj - foodj )< 5){
randSnakeHeadi = Math.floor(Math.random()*15)
randSnakeHeadj = Math.floor(Math.random()*15)
}

github 地址:js 小游戏

仅以此怀念那个在计算机之路上艰难求索的无知少年。