计算24点游戏精化算法剖析

很多人都玩过这个数学味儿很浓的益智游戏:抽出4张扑克牌,牌上的点数代表四个数字,花牌视为1点(有的把J、Q、K分别视为11、12、13点),玩家中谁最先运用加减乘除四则运算,由这四个数计算出24,谁就在这个回合中取胜,要求每个数字必须且只能使用一次。这个游戏称作“计算24点”或“计算24”,有的人也把它叫做“三八二十四”。
喜欢这个游戏的程序员可能都想过把它搬到电脑上。事实上,很多人已经这么做了。网上可搜索到这个游戏的多个版本及源代码。普通人玩这种游戏有时需要绞尽脑汁,不过对于电脑来说就是小菜一碟了。即使是用最笨的算法(当然,要正确)在当前最慢的电脑上运行,给出答案应该都是瞬间的事,如果有答案的话。因此,大概很少有程序员认为开发这样的游戏需要多少技巧。
不过,当您试着在网上下载这个游戏的各个版本来使用时就会发现,也许是免费软件的缘故,几乎所有的版本都只是“点到为止”,而且都是单人玩的。相对于直接玩扑克牌,软件形式的计算24点游戏唯一的优势是提供正确答案而已!
实际上这个答案往往也不是令人满意的。有的软件对每道题目仅提供一个答案,而不管实际的解法有多少种。而有的版本刚好相反,提供了答案的所有排列方式。这意味着,对于1、2、3、4这四个数,尽管只有1×2×3×4一种解法,而列出的答案包含4×3×2×1、2×1×4×3等多达24种!
一方面,如果有多种计算方式,我们应该提供所有答案,而不仅是其中一个答案;另一方面,我们应该避免重复提供相同答案的不同形式。给出所有答案是比较容易的,这里我们只讨论如何避免重复提供相同答案的不同形式。比如1、1、3、8这四个数,1×1×3×8与8×3×1×1应该等效的,答案中只需提供其中一个。那么如何认定两个式子是等效的呢?如果其中一个式子能通过若干次加法交换律和乘法交换律转换为另一个式子,则认为是等效的。因此1×1×3×8与8×3×1×1、1×3×1×8、1×8×3×1都是等效的,但与1-1+3×8不是等效的。减法、除法按与加法、乘法相似的方式处理,这样5+10×2-1与5-1+2×10,5×10÷2-1与10÷2×5-1分别也是等效的。
在明确等效规则后,还需要解决随之而来的两个问题:程序如果根据该规则对两个式子进行比较呢?软件应该选择哪一个式子作为提供给用户的标准答案呢?这两个问题可以用同一种方案解决,那就是建立一个排序规则,被比较的式子都按该排序规则使用加法交换律和乘法交换律进行转换,直到演化为一个“标准”的式子,最后看得到的结果是否一样。而提供给用户的答案,就是这个“标准”的式子。
怎样才算“标准”的式子呢?对用户而言,标准的式子应该比非标准的式子更自然。从小到大,先加后减,先乘后除符合大多数人的视觉习惯。在加法、乘法式子中,总是值小的数或式子的在前。即6×4经排序后得到4×6,3×6+3×2经排序后得到2×3+3×6。对于减法和除法,先减去或除以较小的值或式子。加法和减法一起时,先执行加法。乘法和除法一起时,先执行乘法。这样5-1+10×2经排序后得到5+2×10-1,(5-1+4)×3经排序后变成3×(4+5-1)。
需要指出的是,这个书写最自然的式子不一定是常人做题时最容易想到的式子。小的数字计算起来更方便,小的中间结果对后面的步骤更有利。在上面的例子1、2、5、10中,5-1+2×10可能比5+2×10-1更容易想到。另外对不少人来说,把最难的运算放在第一步更能使自己确信找到了答案,给出的答案最有可能是2×10+(5-1)。因此,很难说哪一个式子是最合适的。好在用户通常都不会这么较真,您只要给出其中一个式子就可以了。
如果您是计算24点的发烧友,您一定听说过1、5、5、5这个经典的计算24点考题。这道题的答案是(5-1÷5)×5,最大的特别之处运算中采用了分数,只有允许使用分数才能求解。其实这样的题目不下10道,如2、4、10、10,还有3、3、7、7等。游戏要支持分数运算,可以采用小数运算再取近似值的方式。不过这种方式不够优雅。最好是设计一个分数类,实现四则运算方法,是否要操作符重载就看您的个人偏好了。分数类有两个私有成员变量,一个是分子,一个是分母。当表示整数时,分母为1。在保存中间结果时,分子与分母不必互质。如果要互质,可参考经典的辗转相除法。
作为益智类游戏,最好为考题设立一个难度系数。这样不同水平的用户可以选择不同难度的考题。那这个难度怎样确定呢?笔者根据个人经验给出一些建议。根据游戏规则,玩家只需给出一个答案即可。因此,题目的解越多(如前所述,同一个答案的不同形式只算一个解),对用户越有利,可以认为难度越低。其次。大家对越小的数字越能得心应手,如果运算的中间结果是比较大的数,像4、4、10、10这样的题目会考倒不少人(没考倒您吧J)。另外,人们似乎在求解时有一种惯性,在尝试下一步时,会优先考虑上一步采用的方式。因此,对于1×2×3×4或3+6+7+10这样的答案很容易想到,如果需要用到四则混合运算便会增加难度,比如2、4、7、7这组题目。当然,只能用分数求解的题目,对绝大多数人是最难的了。
其实这个小软件最难的地方,是如何为玩家提供一个友好的界面。我不是指界面的华丽与否,而是如何方便用户的使用。如果只能用键盘输入算式,那这款软件就算不上是游戏了。不过由于涉及四个数、四中运算,让用户通过鼠标拖拽就能完成操作确实不太容易,需要软件设计者多多推敲。此外,也可以考虑简化步骤。四个数算出24需要三步,不过笔者觉得最后一步可以考虑由电脑自动完成,因为对大多数人而言,只要前两步成功了,最后一步应该不是问题。界面设计与您对软件的定位息息相关。如果您的目的是启发玩家求解,则需自动计算和记录中间结果,并支持撤销操作。而若采用过关斩将的方式,则速度是至关重要的,须提供用户快速输入结果的方式。
写好一个袖珍软件也不容易!您读到这里应该有同感了吧。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值