您的位置:首页 > 编程语言 > Java开发

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

2017-05-17 10:56 489 查看
抽奖活动

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]);

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: