游戏机制重大bug!英雄返还底池出现错误
1. 重大bug实现
这段代码就是说明棋子和英雄池关系的函数。
游戏开始时、有玩家输了退出游戏或者玩家卖出棋子时,棋子要如何加入英雄池,
然而这段代码并不能正常工作,感谢网友王子之名帮助测试。实际删除3星棋子返还底池并不是4个或9个,而是2个或者3个!
- 图中tusk1也就是2星海民删除后,会正常返回3个1星海民,但是tusk11删除后只返回3个,正常情况下应该返回9个。
- eh11 也就是3星魅惑魔女,删除后也只返回2个1星,正常情况下应该返回4个
2. 代码分析
1 | function AddAChessToChessPool(chess) |
比如tk是tinker也就是修补匠,那么tk是1型、tk1是2星而tk11就是3星。
- 第一个if判断,这个棋子是否为3星,如果也满足3星tp(大树)或者3星eh(小鹿),则最大maxcount =4.
- 在最后会执行一个循环,(for count = 1, maxcount do),如果maxcount=4,意思就是一个3星大树、或者小鹿被卖掉,则返回底池4个1级的德鲁伊。作者原意是如此。
但是我们来看看lua语言的执行机制,因为lua是顺序结构运行。 实际上,这一段程序对于出售一个3 *单位(或与一个单位输掉)只能退回3个单位(2个用于eh魅惑魔女,tp大树)而不是9个单位(或4个单位)。让我们看看为什么会产生这个Bug!
lua中 string.sub(string,a,b)这个语句的意思是从一段英文字符string里,截取第a个到第b个,b可以是负数,表示倒数第几个。我们来看看
chess = string.sub(chess,1,-2)执行后会发生什么
比如一个字符是123456,执行上面这一句以后就是12345;同理tp11执行以后剩下tp1, am11执行后身下am1。
明白这个以后就可以继续往下看了。
2.1 普通英雄
第一种情况,非德鲁伊,以tk11,3星修补匠为例
那么执行判断3,
chess = string.sub(chess,1,-2) 后得到
chess = tk1
maxcount = 9
由于目前chess =tk1,所以顺序执行后判断4成立,
chess = string.sub(chess,1,-2) 后得到
chess = tk
maxcount =3
这个maxcount覆盖了前面的那个值,现在只有3,所以执行 for循环, 结果只返回3个tk,也就是3星修补匠最后只返回3个1星修补匠
2.2 德鲁伊
第二种情况, tp11,3星德鲁伊
那么执行判断1
chess = string.sub(chess,1,-2) 得到
chess = tp1
maxcount =4
由于目前chess=tp1,所以顺序执行后判断2成立,
chess = string.sub(chess,1,-2) 得到
chess = tp
maxcount =2
这个maxcount覆盖了前面的那个值,现在只有2,所以执行 for循环, 结果只返回2个tp,也就是3星大树最后只返回2个1星大树
2.3 先知(FH)和利爪德鲁伊(LD)呢
注意到这个判断里面并没有FH和LD
所以FH11和LD11会执行第三个普通英雄的判断,最后只返回3个英雄。
3.修复bug
我简单看了一下,大多数情况下把
chess = string.sub(chess,1,-2)
改成
chess = string.sub(chess,1,-3)
即可修复大部分bug。其他测试热心网友可以帮忙看看。