筹码组合算法

玩过棋牌游戏的同学应该都知道,有一排筹码去,里面有各种面值的筹码,比如1,2,5,10,20,50,100,200,500,1000,2000,5000,10000,20000,50000,100000等,每个面值的筹码对应一个筹码图标,当然图标可以重复利用,比如500的筹码可以跟500的筹码用同一个图标,我们自己下注的时候,我们会主动去选择对应的筹码,然后根据选择的筹码,点击的次数生成对应的筹码堆垛,但是如果这时有机器人下注,机器人下注的值我并不知道,不知道他要下多少,但是机器人下注完后,你得根据它下注的值生成筹码堆垛,下注的值不知道,怎么生成筹码呢?用那个图标呢,用多少个图标呢?

最开始我试着用穷举法,比如机器人下注230,我就硬生生的将230拆成200+20+10,但是如果231呢,232呢,233呢,每次都穷举的话,这活儿是没法干的,你得写多少,可以说无穷无尽,不知道什么时候终止,因为你也不知道机器人下注的范围,最大值多少,最小值多少,就算知道了,这种做法也非常不现实。

然后在网上找了相关的算法,说什么标记数组,位运算,数组映射,掩码运算,看不懂,先拿过来凑合用吧,比如从【10,20,30,50,100】中找出和为70的数,能找出来,是50+20或者30+30+10,但是有个问题,就是里面的每个数只能用一次,比如要找个和为220的值,这个时候就找不到了,因为220大于里面所有数之和,在每个数只能用一次的情况下,是找不到的,于是就试着自己改,改呀,改呀,改了好长时间,还是没改好,还是有问题,崩溃,死循环。。。。。。。

后来在跟同事讨论的时候,一个不经意的瞬间,找到灵感了,灵感来源于现实生活的人民币。我们的人民币有1分,2分,5分,1角,2角,5角,1元,2元,5元,10元,20元,50元,100元,就是任何额度,不管额度多大多小,都能用这些数字表示出来,只是这些数字用的次数不一样,于是带着这个思路,我也定义了一个叫数据模板的变量,里面存放的上上面的类似,比如

 每个值对应一个筹码图标,不论机器人下注了多少,我都能用这里面的表示出来,ConfigData.choumaTempleteData里面定义的多少,也就是数组的长度,决定了满足要求的个数,也就是筹码组合的个数,里面的值越小,越少,满足要求的筹码的个数就越多,表现上是筹码堆垛会堆得很高,里面定义的越多,越大,满足要求的筹码个数就越少,表现上是筹码堆垛会很小,在筹码组合的算法上也很简单,我是这样实现的:

比如机器人下注值A = 9990,然后在ConfigData.choumaTempleteData里找到一个<=9990的数V,这个数是V = 5000,然后得出5000这个筹码的数量B = Math.floor(A/V) = 1,将B存入result列表;9990分了5000,还是L = A%V = 9990%5000 = 4990,将L赋值给A,然后再重复上面操作,在ConfigData.choumaTempleteData里找到一个<=4990的数V,这个数是V = 2000,得出筹码2000的个数为B = Math.floor(A/V) = 2,即2000的筹码需要2个,将B存入result列表,此时 L  =A/V =  4990%2000 = 990,将L赋值给A;再次重复如上操作,在ConfigData.choumaTempleteData里找到一个<=990的数V,这个数V = 500,得出500的筹码需要B = Math.floor(A/V) = 1,将B存入result列表,此时L = A%V = 990%500 = 490 ,L赋值给A,。。。。。。。。,最终result里存放的是【5000,2000,2000,500,200,200,50,20,20】,这样就把最终的筹码组合求出来了。

以上表示算是伪代码,并不是真正的代码,就是表达了一个思路,一个意思。

其实算法很简单,用到的思想就是递归思想,就是每次拿下注的值A去模板数据里找一个<=下注的值B,找到了就用C = A%B,当前层的筹码个数D = A/B,存入列表E,用新的值C递归继续找,直到找到模板里找不到为止,返回的就是筹码堆垛的筹码集合E,再用这个集合E去生成筹码堆垛图标。

测试:

Utils.getChouMaCombinationList(9990);输出:

再随便输入一个53760 

Utils.getChouMaCombinationList(53760 );输出:

随机产生一个:

let random:number = Utils.random(90000,1000000);

Utils.getChouMaCombinationList(random);输出:

 

 

 测试正常,齐活儿。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

西溪漫步

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值