一.场景带入

抢红包在现实场景中经常见到,你知道如何通过代码来实现吗?

一种通常的思路是,一定金额的红包,只要有人过来抢,就在剩余数额内给他分配金额,直到所有钱都分陪完。

但是这样有一个问题,最先抢的人,抢到钱多的概率会更大。

比如有10块钱,有甲乙丙三个人按顺序抢,

甲开始抢,这时他抢红包的数额范围是0到10,平均是5云,假设甲抢了4元。

乙开始抢,这时他抢红包的数额范围是0到6元,平均是3元,假设乙抢了4元。

丙开始抢,他抢红包的数额范围是0到2元,平均是1,剩余钱归丙,2元。

看吧,这样谁先抢,谁占的便宜就更大。

问:有没有一种好的方法可以忽略抢红包的顺序呢?

答:剩余平均法

将剩余的钱除以剩余的红包数,然后再乘以2这个范围内取随机数就可以了。比如有100块钱,10个人抢,

第一个人抢的范围是100/10*2 =20,也就是[0,20],取平均是10,假设抢到了10元

第二个人抢的范围是90/9*2 =20,也就是[0,20],取平均是10,假设抢到了10元

第三个人抢的范围是80/8*2 =20,也就是[0,20],取平均是10

。。。。。。

他们抢的红包钱的概率是一样大的,这样可以姑且认为抢红包对他们来说都是公平的,没有先后顺序之分!

二.代码实现

上面原理懂了,代码实现起来就简单了,这里设置Player就是一个个抢红包的人,它是一个线程,谁先抢到完全由机器来定。

public class HongBao {  //红包类(HongBao)来实现红包的金额生成和返回剩余金额。private AtomicInteger total = new AtomicInteger(0);
    private AtomicInteger count = new AtomicInteger();
    private static Random random = new Random();

    public void setTotal(int total, int person) {this.total.set(total);
        this.count.set(person);
    }public int getPrice() {int countDown = count.get();
        if (countDown == 1) {  //如果红包还剩最后一个了,剩余的钱都给最后一个玩家
            return getRemainPrice();
        }int rand = (total.get() / count.get()) * 2;
        int price = random.nextInt(rand - 1) + 1; //取值是[1,2的平均值)
        total.set (total.get() - price);
        count.decrementAndGet();  //抢走了一个,个数要减一
        return price;  //返回本次抢的钱
    }public int getRemainPrice() {return total.get();
    }
}
public class Player implements Runnable {  //玩家(Player)是一个线程,主要是调用了获取红包的方法private HongBao hongBao;
    private String name;
    Player(HongBao hongBao, String name) {this.hongBao = hongBao;
        this.name = name;
    }@Override
    public void run() {int price = hongBao.getPrice();  //开始抢红包
        System.out.println("线程[" + name + "]" + "获得<" + price + ">");
    }
}
public class Game {  //游戏类(Game)负责红包的初始化和设置n个抢红包的玩家public static void main(String[] args) throws InterruptedException {        start();
    }public static void start() {HongBao hongBao = new HongBao();
        int total = 100;
        int count = 5;
        initHongBao(hongBao, total, count);  //初始化红包
        for (int i = 0; i < count; i++) {Player play = new Player(hongBao, String.valueOf(i));
            new Thread(play).start();
        }}/**
     * 初始化红包
      * @param hongBao  红包类
     * @param total 金额
     * @param count 总共多少个
     */
    private static void initHongBao(HongBao hongBao, int total, int count) {hongBao.setTotal(total, count);
    }
}

三.总结

到此,红包算法的设计就已经完毕了。设计红包算法,需要考虑到每个玩家至少在抢的时候获取钱的几率是一样的,当然实际情况并不是每个人都抢的一样。就这个算法,我的电脑统计的qps是1000,期待你有一个更好的方案!

教你代码实现抢红包功能相关推荐

  1. js微信抢红包脚本代码_如何利用JavaScript来实现微信抢红包功能的示例代码

    本文通过实例代码给大家介绍了基于JavaScript实现微信抢红包功能,金额随机,额度在0.01和(剩余平均值*2)之间,具体的实例代码大家参考下本文 金额随机:额度在0.01和(剩余平均值*2)之间 ...

  2. 300行代码实现 微信或QQ 抢红包功能

    每次看到别人发红包,但是没有抢到,这就很尴尬了.于是想着做一个红包插件,嘿嘿,再也不怕我反应迟钝了. 首先,想到做这个功能时,我联想到的是这个是不是lua写出来的脚本呢?但是条件不成立,因为可以不需要 ...

  3. js微信抢红包脚本代码_基于JavaScript实现微信抢红包功能

    金额随机:额度在0.01和(剩余平均值*2)之间. 0){ let num = scramble(remainAmount,remainPeople); remainAmount = remainAm ...

  4. java实现红包要多少钱_Java实现抢红包功能

    本文实例为大家分享了Java实现抢红包功能的具体代码,供大家参考,具体内容如下 关键思想: 1.抢红包涉及多人并发操作,需要做好同步保证多线程运行结果正确. 2.由于同时在线人数大,从性能方面考虑,玩 ...

  5. mysql抢红包功能_Laravel框架实现抢红包功能示例

    本文实例讲述了Laravel框架实现抢红包功能.分享给大家供大家参考,具体如下: 首先进行登录 {{csrf_field()}} 用户名: 密 码: 在登录时,我们会进行一些相应的验证:比如用户名,手 ...

  6. 基于redis实现抢红包功能(包括余额退回处理)

    本文将讲述使用redis实现抢红包功能,采用发红包时将红包拆好存储,解决红包金额平衡问题(两种算法).解决超发现象.将数据通过消息队列传递给另一个服务写入数据库,现阶段不考虑redis宕机的情况. - ...

  7. Android微信抢红包功能的实现

    快到过农历年了,微信红包也越来越多了,出现了好多红包外挂程序,就很好奇如何实现的,于是自己研究了一番,亲自写了个微信抢红包的APP.现在就一步一步来实现它. 实现思路 微信抢红包程序开启时候,他就可以 ...

  8. java实现qq抢红包_java抢红包功能实现

    这两天做了一个抢红包功能,收藏了一个不错的生成红包的算法,分享给大家 static Random random = new Random(); static { random.setSeed(Syst ...

  9. android 红包功能,[原创]实现某app的抢红包功能

    目录 内容摘要写这个插件的原因是因为经常使用这个app,而且每天早上这个app都会发红包,然而每次都抢不到,很懊恼,而最近也一直跟着 r0ysue 大佬在学习安卓逆向相关的知识,就突发奇想,所以就拿来 ...

最新文章

  1. [Javascript]怎么样让公告不间断的滚动显示
  2. 76 道 Oracle Goldengate 面试问题
  3. iis php win安装kangle_Win2008 R2 IIS7.5+PHP5(FastCGI)+MySQL5环境搭建教程
  4. android与mysql的交互,与Android中的外部SQLite数据库进行交互.
  5. mysql :The user specified ... does not exist 报错
  6. QT和MFC中怎么使用继承基类的自定义控件放置在界面上
  7. Linux下DMA添加两个channel,基于Linux嵌入式系统的ISA总线DMA的实现
  8. python利用什么写模块_python模块是什么?写法及作用分析
  9. javascript:控制一个元素高度始终等于浏览器高度
  10. andrioid 图像视频处理
  11. 《网络是怎样连接的》了解网络连接的全貌
  12. 学校年检计算机台账,电脑台账管理系统
  13. 如何免费制作表白二维码?
  14. 重生之我是赏金猎人-SRC漏洞挖掘(十三)-攻防对抗/梦中绝杀X脖代理商
  15. logo设计灵感的创意网站
  16. 哈希表解决冲突的两种方式
  17. 第九讲:因子分析(Factor analysis)
  18. Navicat自动备份数据库
  19. Java代码块(代码块与静态代码块使用细节及调用顺序)
  20. 早安心语优美的心情语录

热门文章

  1. FLASH2.0学习教程
  2. 科技有意思丨iPhone8新添AR功能?!你的肾还保得住吗
  3. 微信公众号企业号服务号订阅号个体号如何突破限制服务
  4. 电脑开始怎么设置计算机用户名,如何修改电脑登录用户名以及密码呢?5秒钟让你学会...
  5. 域名备案审核需要多长时间?企业网站需要准备哪些材料?
  6. 有趣的python代码系列四:小猪佩奇
  7. quill.js官方文档(六)【增量Delta】
  8. 广告买量支付方式 cpa cpc cps cpt
  9. 200+篇Graph4NLP文献集:图深度学习在NLP任务的应用
  10. windows 电脑终端查看历史记录命令