Java 实现根据权重设置抽奖概率

来源:互联网 发布:python难找工作 编辑:程序博客网 时间:2024/06/08 02:52

抽奖活动

package com.wamei.activity;import com.wamei.common.ResourceUtils;import com.wamei.entity.AppUser;import com.wamei.entity.activity.LotteryAddress;import com.wamei.entity.activity.LotteryPrize;import com.wamei.entity.activity.LotteryRecord;import com.wamei.entity.activity.LotteryWinRecord;import com.wamei.service.AppUserService;import com.wamei.service.BaseService;import com.wamei.util.AjaxPostResponse;import com.wamei.util.DateToolUtils;import com.wamei.util.JsonResponseHelper;import net.sf.ehcache.Cache;import net.sf.ehcache.CacheManager;import org.apache.commons.lang3.StringUtils;import org.apache.log4j.Logger;import org.springframework.http.ResponseEntity;import org.springframework.stereotype.Controller;import org.springframework.web.bind.ServletRequestUtils;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.ResponseBody;import org.springframework.web.servlet.ModelAndView;import javax.annotation.Resource;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.text.DecimalFormat;import java.util.ArrayList;import java.util.Arrays;import java.util.Date;import java.util.List;import java.util.regex.Matcher;import java.util.regex.Pattern;/** * 总统竞选抽奖活动 Controller. * @author qixuan.chen * @version 1.0 */@Controller@RequestMapping({"/activity/lotteryController"})public class LotteryController extends AbstractController{    private final static Logger logger = Logger.getLogger(LotteryController.class);    private static String smsUrl = ResourceUtils.getValue("sms.httpUrl");    public static String pathUrl = ResourceUtils.getValue("sign.path");    public final static String ECID = "100148";    public final static String ECKEY = "3O9oOAuGZ0k=dMMSmPTJUUI=";    @Resource(name = "lotteryPrizeManager")    private BaseService<LotteryPrize> lotteryPrizeSrv;    @Resource(name = "lotteryRecordManager")    private BaseService<LotteryRecord> lotteryRecordSrv;    @Resource(name = "lotteryWinRecordManager")    private BaseService<LotteryWinRecord> lotteryWinRecordSrv;    @Resource(name = "lotteryAddressManager")    private BaseService<LotteryAddress> lotteryAddressSrv;    @Resource(name="appUserManager")    private AppUserService appUserSrv;    private static Cache validCodeCache;    static{        if (validCodeCache == null) {            validCodeCache = CacheManager.getInstance().getCache("govDataCache");        }    }    /**     * 主页视图     * @return     * @throws Exception     */    @RequestMapping(value = "/main", method ={RequestMethod.GET,RequestMethod.POST})    public ModelAndView lotteryMain(HttpServletRequest request) throws Exception {        ModelAndView mav = new ModelAndView("pages/activity/lottery/lottery");        String token = ServletRequestUtils.getStringParameter(request, "token", "");//用户ID        String loMark = "no";        if(StringUtils.isNotEmpty(token)){            AppUser user = appUserSrv.find(token);            if(null!=user){                //当天是否已参与过                String lrHql = " from LotteryRecord t where user.id=? and t.createTime>= ? and t.createTime <= ? ";                List<Object> param = new ArrayList<Object>();                Date startTime = DateToolUtils.getTodayStart();                Date endTime = DateToolUtils.getTodayEnd();                param.add(user.getId());                param.add(startTime);                param.add(endTime);                List<LotteryRecord> lrList = lotteryRecordSrv.list(lrHql,param.toArray());                if(null!=lrList && lrList.size()>0){                    loMark = "yes";                }                mav.addObject("token",user.getId());            }        }        mav.addObject("loMark",loMark);        //追加投票数        String id = "1005";        LotteryPrize mo = lotteryPrizeSrv.find(id);        String time = String.valueOf(System.currentTimeMillis());        String pr = time.substring(time.length()-1,time.length());        //利用时间戳最后一位来设置投票互斥事件        String[] p2={"1","3","5","7","9"};        int  lpCount = mo.getNum();        float mkCount = mo.getPrice();        if(Arrays.asList(p2).contains(pr)){            mo.setNum(lpCount+1);        }else{            mo.setPrice(mkCount+1);        }        lotteryPrizeSrv.update(mo);        //奖品列表        String hql = " from LotteryPrize t where t.status=1 ";        List<LotteryPrize> list = lotteryPrizeSrv.list(hql,null);        mav.addObject("prizeList",list);        mav.addObject("lpCount",lpCount);        mav.addObject("mkCount",(int)mkCount);        return mav;    }    /**     * 抽奖     * @param request     */    @RequestMapping(value = "/getprize", method={RequestMethod.POST,RequestMethod.GET})    public synchronized ResponseEntity<AjaxPostResponse> getprizesetting(HttpServletRequest request){        String token = ServletRequestUtils.getStringParameter(request, "token", "");//用户ID        try {            int result = 5;            int status = 0;            if(StringUtils.isNotEmpty(token)){                AppUser user = appUserSrv.find(token);                if (null != user) {                    synchronized(this) {                        //每天只能抽一次奖                        String lrHql = " from LotteryRecord t where user.id=? and t.createTime>= ? and t.createTime <= ? ";                        List<Object> param = new ArrayList<Object>();                        Date startTime = DateToolUtils.getTodayStart();                        Date endTime = DateToolUtils.getTodayEnd();                        param.add(user.getId());                        param.add(startTime);                        param.add(endTime);                        List<LotteryRecord> lrList = lotteryRecordSrv.list(lrHql,param.toArray());                        if(null!=lrList && lrList.size()>0){                            return this.errorResponse("");                        }else{//                            //IP限制(每个IP一天一次)//                            String ipHql = " from LotteryRecord t where userIp=? and t.createTime>= ? and t.createTime <= ? ";//                            List<Object> ipParam = new ArrayList<Object>();//                            ipParam.add(this.getIPAddress(request));//                            ipParam.add(startTime);//                            ipParam.add(endTime);//                            List<LotteryRecord> ipList = lotteryRecordSrv.list(ipHql,ipParam.toArray());//                            if(null!=ipList && ipList.size()>0){//                                return this.errorResponse("手气不佳,明天再来!");//                            }                            //添加抽奖记录                            LotteryRecord lotteryRecord = new LotteryRecord();                            lotteryRecord.setUser(user);                            lotteryRecord.setCreateTime(new Date());                            lotteryRecord.setUserIp(this.getIPAddress(request));                            lotteryRecord.setStatus(status);                            lotteryRecordSrv.create(lotteryRecord);                            //已经中过一次的用户,不能在中                            String lwrHql = " from LotteryWinRecord t where user.id=? ";                            List<Object> lwrParam = new ArrayList<Object>();                            lwrParam.add(user.getId());                            List<LotteryWinRecord> lwrList = lotteryWinRecordSrv.list(lwrHql,lwrParam.toArray());                            if(null!=lwrList && lwrList.size()>0){                                return this.errorResponse("手气不佳,明天再来!");                            }                            String time = String.valueOf(System.currentTimeMillis());                            String pr = time.substring(time.length()-1,time.length());                            Integer[] data = {2,4,6,8};//奖品参数                            //利用时间戳最后一位来设置外层概率,互斥事件                            //String[] p2={"0","1","2","3","4","5","6","7","8","9"};                            String[] p2={"1","3","5","8"};                            if(Arrays.asList(p2).contains(pr)){                                //进行抽奖                                List<LotteryPrize> prizeList = lotteryPrizeSrv.list();                                result = getPrizeIndex(prizeList);                                LotteryPrize prize = prizeList.get(result);                                String prizeName = "";                                if(null!=prize){                                    //中奖了                                    String msg = "手气不佳,明天再来!";                                    if("1001".equals(prize.getId())){                                        msg = "1台"+prize.getPrizename();                                        prizeName = prize.getPrizename();                                    }else if("1002".equals(prize.getId())){                                        msg = "1台"+prize.getPrizename();                                        prizeName = prize.getPrizename();                                    }else if("1003".equals(prize.getId())){                                        msg = "1张"+prize.getPrizename();                                        prizeName = "价值"+prize.getPrice()+"元的"+prize.getPrizename();                                    }else if("1004".equals(prize.getId())){                                        msg = "1张"+prize.getPrizename();                                        prizeName = "价值"+prize.getPrice()+"元的"+prize.getPrizename();                                    }else{                                        return this.errorResponse(msg);//手气不佳                                    }                                    if(prize.getNum()>=1){                                        prize.setNum(prize.getNum()-1);                                        lotteryPrizeSrv.update(prize);//更新剩余量                                        status = 1;                                        //添加中奖记录                                        LotteryWinRecord winRecord = new LotteryWinRecord();                                        winRecord.setUser(user);                                        winRecord.setPrizeId(prize.getId());                                        winRecord.setImgsrc(prize.getImgsrc());//奖品图片                                        winRecord.setPrizename(prizeName);//奖品名称                                        winRecord.setCreateTime(new Date());                                        winRecord.setUserIp(this.getIPAddress(request));                                        winRecord.setStatus(status);                                        lotteryWinRecordSrv.create(winRecord);                                        return this.okResponse(msg);                                    }                                }                            }else{                                return this.errorResponse("手气不佳,明天再来!");                            }                        }                    }                }else{                    return this.errorResponse("不存在该用户!");                }            }        } catch (Exception e) {            e.printStackTrace();            return this.errorResponse("手气不佳,明天再来!");        }        return this.errorResponse("手气不佳,明天再来!");    }    /**     * 我的奖品记录     * @param request     * @param response     */    @RequestMapping(value = "/myprizes", method={RequestMethod.POST,RequestMethod.GET})    public @ResponseBody void myprizesRecord(HttpServletRequest request, HttpServletResponse response){        String token = ServletRequestUtils.getStringParameter(request, "token", "");//用户ID        StringBuffer sb = new StringBuffer();        String result = "";        try {            if(StringUtils.isNotEmpty(token)) {                AppUser user = appUserSrv.find(token);                if (null != user) {                    String hql = " from LotteryWinRecord t where user.id=? ";                    List<Object> paramValues = new ArrayList<Object>();                    paramValues.add(token);                    List<LotteryWinRecord> lotteryWinRecords = lotteryWinRecordSrv.list(hql, paramValues.toArray());                    result = JsonResponseHelper.toJson(lotteryWinRecords).toString();                }            }            sb.append("{\"statusCode\":\"1\", \"msg\":\"\", \"errorCode\":\"\", \"result\":{\"data\":" + result + "}}");        } catch (Exception e) {            e.printStackTrace();            sb.append("{\"statusCode\":\"0\", \"msg\":\"获取失败!\", \"errorCode\":\"\", \"result\":{}}");        }        JsonResponseHelper.renderText(sb.toString(), response);    }    /**     * 获取奖品快递地址信息     * @param request     */    @RequestMapping(value = "/getAddress", method={RequestMethod.POST})    public ResponseEntity<AjaxPostResponse> getAddress(HttpServletRequest request){        String token = ServletRequestUtils.getStringParameter(request, "token", "");//用户ID        try {            if(StringUtils.isBlank(token)){                return this.errorResponse("请先登录!");            }            if(StringUtils.isNotEmpty(token)){                AppUser user = appUserSrv.find(token);                if (null != user) {                    String hql = " from LotteryAddress t where user.id=? ";                    List<Object> paramValues = new ArrayList<Object>();                    paramValues.add(token);                    List<LotteryAddress> list = lotteryAddressSrv.list(hql,paramValues.toArray());                    if(null!=list && list.size()>0){                        return this.okResponse(list.get(0));                    }else{                        return this.okResponse("");                    }                }else{                    return this.errorResponse("请先登录!");                }            }        } catch (Exception e) {            e.printStackTrace();        }        return this.errorResponse("获取失败!");    }    /**     * 保存奖品快递地址信息     * @param request     */    @RequestMapping(value = "/address", method={RequestMethod.POST})    public ResponseEntity<AjaxPostResponse> saveAddress(HttpServletRequest request){        String token = ServletRequestUtils.getStringParameter(request, "token", "");//用户ID        String truename = ServletRequestUtils.getStringParameter(request, "truename", "");//真实姓名        String telPhone = ServletRequestUtils.getStringParameter(request, "mobile", "");//联系方式        String city = ServletRequestUtils.getStringParameter(request, "city", "");//区域        String street = ServletRequestUtils.getStringParameter(request, "street", "");//街道        String address = ServletRequestUtils.getStringParameter(request, "address", "");//地址        try {            if(StringUtils.isBlank(token)){                return this.errorResponse("请先登录!");            }            if(StringUtils.isBlank(truename)){                return this.errorResponse("请输入真实姓名!");            }            if(StringUtils.isBlank(telPhone)){                return this.errorResponse("请输入联系方式!");            }            Pattern p = Pattern.compile("^((13[0-9])|(15[^4,\\D])|(18[0-9]))\\d{8}$");            Matcher m = p.matcher(telPhone);            if (false == m.matches()) {                return this.errorResponse("手机号格式不正确");            }            if(StringUtils.isBlank(city)){                return this.errorResponse("请输入区域地址!");            }            if(StringUtils.isBlank(street)){                return this.errorResponse("请输入街道地址!");            }            if(StringUtils.isNotEmpty(token)){                AppUser user = appUserSrv.find(token);                if (null != user) {                    String hql = " from LotteryAddress t where user.id=? ";                    List<Object> paramValues = new ArrayList<Object>();                    paramValues.add(token);                    List<LotteryAddress> list = lotteryAddressSrv.list(hql,paramValues.toArray());                    LotteryAddress mo = new LotteryAddress();                    mo.setUser(user);                    mo.setTruename(truename);                    mo.setTelPhone(telPhone);                    mo.setCity(city);                    mo.setStreet(street);                    mo.setPrizeId("");                    mo.setAddress(address);                    if(null!=list && list.size()>0){                        mo.setId(list.get(0).getId());                        mo.setCreateTime(list.get(0).getCreateTime());                        lotteryAddressSrv.update(mo);                    }else{                        mo.setCreateTime(new Date());                        lotteryAddressSrv.create(mo);                    }                    logger.info("userId="+token+",地址保存成功");                    return this.okResponse("保存成功!");                }else{                    return this.errorResponse("请先登录!");                }            }        } catch (Exception e) {            e.printStackTrace();        }        return this.errorResponse("保存失败!");    }    /**     * 根据Math.random()产生一个double型的随机数,判断每个奖品出现的概率     * @param prizes     * @return random:奖品列表prizes中的序列(prizes中的第random个就是抽中的奖品)     */    public int getPrizeIndex(List<LotteryPrize> prizes) {        DecimalFormat df = new DecimalFormat("######0.00");        int random = -1;        try{            //计算总权重            double sumWeight = 0;            for(LotteryPrize p : prizes){                sumWeight += p.getPrizeWeight();            }            //产生随机数            double randomNumber;            randomNumber = Math.random();            //根据随机数在所有奖品分布的区域并确定所抽奖品            double d1 = 0;            double d2 = 0;            for(int i=0;i<prizes.size();i++){                d2 += Double.parseDouble(String.valueOf(prizes.get(i).getPrizeWeight()))/sumWeight;                if(i==0){                    d1 = 0;                }else{                    d1 +=Double.parseDouble(String.valueOf(prizes.get(i-1).getPrizeWeight()))/sumWeight;                }                if(randomNumber >= d1 && randomNumber <= d2){                    random = i;                    break;                }            }        }catch(Exception e){            random =-1;            logger.info("生成抽奖随机数出错,出错原因:" +e.getMessage());        }        return random;    }    /**     * 测试     * @param args     */    public static void main(String args[]){        int i = 0;        int[] result=new int[5];        List<LotteryPrize> prizes = new ArrayList<LotteryPrize>();        LotteryPrize p1 = new LotteryPrize();        p1.setPrizename("iPhone7");        p1.setPrizeWeight(0);//奖品的权重设置成1        prizes.add(p1);        LotteryPrize p2 = new LotteryPrize();        p2.setPrizename("扫地机器人");        p2.setPrizeWeight(0);//奖品的权重设置成2        prizes.add(p2);        LotteryPrize p3 = new LotteryPrize();        p3.setPrizename("充电宝");        p3.setPrizeWeight(3);//奖品的权重设置成3        prizes.add(p3);        LotteryPrize p4 = new LotteryPrize();        p4.setPrizename("京东电子卡");        p4.setPrizeWeight(4);//奖品的权重设置成4        prizes.add(p4);        LotteryPrize p5 = new LotteryPrize();        p5.setPrizename("手气不佳");        p5.setPrizeWeight(100000);//奖品的权重设置成4        prizes.add(p5);        LotteryController a1 = new LotteryController();        //Thread t1 = new Thread(a1);        System.out.println("抽奖开始");        for (i = 0; i < 10000; i++)// 打印100个测试概率的准确性        {            int selected=a1.getPrizeIndex(prizes);            System.out.println("第"+i+"次抽中的奖品为:"+prizes.get(selected).getPrizename() +"=========="+selected);            result[selected]++;            System.out.println("--------------------------------");        }        System.out.println("抽奖结束");        System.out.println("每种奖品抽到的数量为:");        System.out.println("一等奖:"+result[0]);        System.out.println("二等奖:"+result[1]);        System.out.println("三等奖:"+result[2]);        System.out.println("四等奖:"+result[3]);        System.out.println("无等奖:"+result[4]);    }}



原创粉丝点击