问下这种算法怎么实现?

有1分,1角,5角,1元的硬币作为游戏币种,若选定1分钱作为筹码,向游戏里面投1分钱,游戏投注记录会出现1分钱图标,每增加投1分钱,1分钱的图标会相应增加,投到10个1分钱图标的时候10个1分钱的图标会消失变成1个1角钱的图标。当点击取消投注的时候,取消上一次投注1分钱的操作,投的钱变成9分钱同时相应的1角钱的图标消失变成9个1分钱的图标。
以此类推。
这样怎么写个算法比较好?主要是图标比较难控制啊

阅读 3.9k
6 个回答

我觉得用取模的方法比较好处理。
假如现有总币151分,先用最大的100分(即1元)去取模,151%100 = 1 余51,得到单位为元的货币是1.
此时再用剩余的去和5角(即50分)去取模得1,余1.
此时再用1分去和1角取模,得0,所以有0个1角。
再用最小的单位1分取模,得1,余0。
所以每次取模结束后判断一下余数是否为0,if true则return;
最后结果1个(1元)1个(5角)0个(1角)1个(1分)

想到一个办法 。
1.用一个变量保存 当前投注情况 :

a代表1分 ,b代表1角,c代表5角,d代表1元
假如你现在是9分钱
就是s = [
    'a'=>9,'b'=>0, 'c'=>0, 'd'=>0
]

2.用一个队列来存入你的每次操作。

action = [ a, a,]
代表你投入了二次一分。

3.剩下的就很好解决了。每一次操作入一次队列,检查是否有进位就行了,然后更新一下你的状态,


第一次action :
s = ['a'=>0,'b'=>1, 'c'=>0, 'd'=>0]
第二次action :
s = ['a'=>1,'b'=>1, 'c'=>0, 'd'=>0]

4.每一次取消就是一次回退操作了。逆操作一下队列任务就行了。

第一次撤消:
查看action 队列,是a操作【+1分操作。】则逆操作为-a【-1分操作】,操作后变成
s = ['a'=>0,'b'=>1, 'c'=>0, 'd'=>0]
action = [a]

第二次撤消:
查看action 队列,是a操作【+1分操作。】则逆操作为-a【-1分操作】,操作后变成
s = ['a'=>9,'b'=>0, 'c'=>0, 'd'=>0]
action = []
此时经过两次撤消后,action操作已空,无法再继续撤消了。

public class Test {
    /**
     * 栈是用于撤销的经典数据结构
     */
    private Stack<Integer> stack = new Stack<Integer>();
    private int sum;


    public int add(int money) {
        if (money < 0) {
            throw new NoSuchElementException("上一步无操作");
        }
        sum += money;
        stack.push(money);
        show();
        return sum;
    }

    public void show() {
        int _yuan = sum / 100;
        int _5jiao = (sum - 100 * _yuan) / 50;
        int _1jiao = (sum - 100 * _yuan - 50 * _5jiao) / 10;
        int _1fen = (sum - 100 * _yuan - 50 * _5jiao - 10 * _1jiao);
        System.out.println("_yuan:" + _yuan + "\t_5jiao:"
                + _5jiao + "\t_1jiao:" + _1jiao + "\t_1fen:" + _1fen);
    }


    public int cancel() {
        if (stack.isEmpty()) {
            throw new NoSuchElementException("上一步无操作");
        }
        int money = stack.pop();
        sum -= money;
        show();
        return sum;
    }

    public static void main(String[] args) {
        Test t = new Test();
        t.add(100);
        t.add(50);
        t.add(3);
        t.cancel();
    }
}

还挺有意思的,我的思路是cur_num记录当前分数。投币的话,不管你投的什么币,都把它转换成分加到当前分数里。然后把当前分数转成元角分的形式。撤销的话,用last_price记录历史动作,可以无限记录,撤销次数也可以是所有操作的次数,撤销到0都行。想限制你可以自己设置。下面是模拟投币和撤销动作的整个程序。

#coding:utf-8
import random,time
pricelist=[1,10,50,100]
cur_num=0
last_price=[]
def touqian(price):
    global last_price,cur_num
    last_price.append(price)
    cur_num+=last_price[-1]
    print('投了',price,'分')
def chexiao():
    global last_price, cur_num
    if last_price!=[]:
        a=last_price.pop()
        cur_num-=a
        print('撤销一次,减了',a,'分')
        update_icon()
def update_icon():
    global cur_num
    sr=str(cur_num)
    a=int(cur_num/100)
    if len(sr)>=2:
        b=sr[-2]
    else:
        b='0'
    c=sr[-1]
    print(a,'元')
    print(b,'角')
    print(c,'分')
i=0
while True:
    i+=1
    time.sleep(1)
    touqian(pricelist[random.randint(0,3)])
    update_icon()
    if i%3==0:#每投币三次,撤销一次
        chexiao()

编辑,被踩了不知原因,请留评论让我好修改。

各种面额硬币并非实体,只有1分这个计量单位。
然后每次投钱或者去掉钱,自动把分换算成相应图标。

首先以1分作为基本单位,换算单位的话,1角=10分,5角=50分,1元=100分。
这场游戏应该有三个池,即用户手中余额,用户投注池,总用户投注池。
可以用三个变量代替,变量存储的数值是以1分为单位的

var user_coins, // 用户余额
    user_epoll_coins, // 用户投注金额
    all_user_coins; // 总用户投注金额

每次单位用户投注最少是1分,当用户投注时减少user_coins,增加user_epoll_coins,增加all_user_coins,页面显示效果的时候就根据这三个变量计算应该显示几个1分,几个1角。。
大概思路就这样,其中all_user_coins总用户投注池是需要ajax获取后台数据的

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题