今天看了一个不错的抽奖小程序,记录下
参考文章:http://blog.csdn.net/yaoyuan_difang/article/details/8442310 (PHP概率算法(适用于抽奖、随机广告)
先来看概率算法
function getRand($arr){
$k = '';
$sum = array_sum($arr);
foreach ($arr as $key => $v) {
$rnum = mt_rand(1,$sum);
if($rnum < $v){
$k = $key;
break;
}else{
$sum -= $v;
}
}
return $k;
}
上述代码是一段经典的概率算法,$arr是一个预先设置的数组,假设数组为:array(100,200,300,400),开始是从1,1000这个概率范围内筛选第一个数是否在他的出现概率范围之内, 如果不在,则将概率空间,也就是k的值减去刚刚的那个数字的概率空间,在本例当中就是减去100,也就是说第二个数是在1,900这个范围内筛选的。这样筛选到最终,总会有一个数满足要求。就相当于去一个箱子里摸东西,第一个不是,第二个不是,第三个还不是,那最后一个一定是。这个算法简单,而且效率非常高,关键是这个算法已在我们以前的项目中有应用,尤其是大数据量的项目中效率非常棒。
每次前端页面的请求,PHP循环奖项设置数组,通过概率计算函数get_rand获取抽中的奖项id。将中奖奖品保存在数组$res['yes']中,而剩下的未中奖的信息保存在$res['no']中,最后输出json个数数据给前端页面。
$prize_arr = array(
"0" => array('id' => 1,'msg' => '平板电脑','v' => 3),
"1" => array('id' => 2,'msg' => '数码相机','v' => 5),
"2" => array('id' => 3,'msg' => '音箱设备','v' => 10),
"3" => array('id' => 4,'msg' => '4G优盘','v' => 12),
"4" => array('id' => 5,'msg' => '10Q币','v' => 20),
"5" => array('id' => 6,'msg' => '很遗憾,这次没有中奖','v' => 50),
);
foreach($prize_arr as $v){
$arr[$v['id']] = $v['v'];
}
$rid = getRand($arr);
//$res['flag'] = ($rid == 6) ? 0 : 1;
$res['yes'] = $prize_arr[$rid -1]['msg'];
unset($prize_arr[$rid-1]);
shuffle($prize_arr);
for($i=0; $i < count($prize_arr); $i++){
$handlePr[] = $prize_arr[$i]['msg'];
}
$res['no'] = $handlePr;
echo json_encode($res);
exit;
直接输出中奖信息就得了,为何还要把未中奖的信息也要输出给前端页面呢?请看后面的前端代码。
接下来,我们通过单击页面中的方块,来完成抽奖行为。
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
$("#repeat").click(function(){
window.location.reload();
});
$("#prize li").each(function(){
var p = $(this);
var c = $(this).attr('class');
p.css("background-color",c);
p.click(function(){
$.getJSON('prize.php',function(data){
var prize = data.yes;
p.html(prize);
p.css({"background-color":'#fff','color':'#000','font-size':'20px'});
p.attr("id","win");
$("#viewother").show();
$("#repeat").show();
$("#prize li").unbind("click").css("cursor","default").removeAttr('title');
$("#data").data("nomsg",data.no);
});
});
});
});
</script>
代码中先遍历6个方块,给每个方块初始化不同的背景颜色,单击当前方块后,使用$.getJSON向后台data.php发送ajax请求,请求成功后,调用flip插件实现翻转方块,在获取的中奖信息显示在翻转后的方块上,翻转结束后,标记该中奖方块id,同时冻结方块上的单击事件,即unbind('click'),目的就是让抽奖者只能抽一次,抽完后每个方块不能再翻动了。最后将未抽中的奖项信息通过data()储存在#data中。
其实到这一步抽奖工作已经完成,为了能查看其他方块背面究竟隐藏着什么,我们在抽奖后给出一个可以查看其他方块背面的链接。通过点击该链接,其他5个方块转动,将背面奖项信息显示出来。
$("#viewother").click(function(){
var nomsg = $("#data").data("nomsg");
$("#prize li").not($("#win")[0]).each(function(index){
var p = $(this);
p.css("background-color",'#ccc');
p.html(nomsg[index]);
$("#viewother").hide();
});
});
最终完成后的现实结果如下:(程序源码在www下的lottery里面)