加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

不确定人数的抽奖方法

发布时间:2020-12-15 21:16:40 所属栏目:asp.Net 来源:网络整理
导读:很多年前就给前公司的年会做过年会抽奖,基本要求就是年会入场时签到,签到的员工都参与抽奖(也可以设置公司高管过滤,不参与抽奖),奖品是预设好的,到时候就是给所有签到员工编号,然后抽奖过程中不断生成一组随机数,这些随机数对应的编号的员工姓名和

很多年前就给前公司的年会做过年会抽奖,基本要求就是年会入场时签到,签到的员工都参与抽奖(也可以设置公司高管过滤,不参与抽奖),奖品是预设好的,到时候就是给所有签到员工编号,然后抽奖过程中不断生成一组随机数,这些随机数对应的编号的员工姓名和照片就显示出来,这是很容易想到的算法。

但是还要一种情况就是互联网模式的抽奖,有点像双十一之前,阿里派发红包一样,大家都可以在开始抽奖的时候去抽,奖品也是预设好的,比如1000W的奖金池,派发完毕就抽奖完毕,每个用户可以抽取多次。这种抽奖方式主要是应对抽奖人数不确定的情况,谁也不需要提前签到报名,到了抽奖时间只要注册用户都可以抽奖。

因为抽奖人数不确定,所以采用一人多次抽奖的方案是很好的,对用户来说也是,如果第一次没有抽中,还可以尝试第二次,第三次。具体算法上,其实更简单,因为用户点击抽奖的顺序是随机的,所以我们连随机数都不用用,直接给用户的一次抽奖请求编个自增的号,如果这个号满足中奖规则,那么就分配礼品,返回该抽奖请求中奖结果,如果不满足中奖规则,那么我们就返回未中奖。

为了避免用户频繁的点击,造成服务器过高的负担,我们可以在客户端设置一个动画过程,比如转盘抽奖,可以转几秒以后才请求服务器,看是否中奖,对用户来说也增加了趣味性。为了避免用户不通过客户端,直接发起频繁的HTTP请求来刷奖,我们甚至可以在服务器设置同一个用户的请求时间间隔。

下面贴出我写的一个示例代码部分,我设置了一个自增的整数Sequence ,每个正常的抽奖请求,则Sequence ++,另外设置默认的抽奖基数baseNumber=100,如果能够Sequence能够被baseNumber整除,那么就中奖,否则不中奖:

[RoutePrefix( </span><span style="color: #0000ff;"&gt;private</span> <span style="color: #0000ff;"&gt;static</span> <span style="color: #0000ff;"&gt;volatile</span> <span style="color: #0000ff;"&gt;int</span> Sequence = <span style="color: #800080;"&gt;1</span><span style="color: #000000;"&gt;; </span><span style="color: #0000ff;"&gt;private</span> <span style="color: #0000ff;"&gt;static</span> IList<<span style="color: #0000ff;"&gt;int</span>> winnerList=<span style="color: #0000ff;"&gt;new</span> List<<span style="color: #0000ff;"&gt;int</span>><span style="color: #000000;"&gt;(); </span><span style="color: #808080;"&gt;///</span> <span style="color: #808080;"&gt;<summary></span> <span style="color: #808080;"&gt;///</span><span style="color: #008000;"&gt; 抽奖开始标记,请通过StartNewLotteryRound打开 </span><span style="color: #808080;"&gt;///</span> <span style="color: #808080;"&gt;</summary></span> <span style="color: #0000ff;"&gt;private</span> <span style="color: #0000ff;"&gt;static</span> <span style="color: #0000ff;"&gt;bool</span> start = <span style="color: #0000ff;"&gt;false</span><span style="color: #000000;"&gt;; </span><span style="color: #808080;"&gt;///</span> <span style="color: #808080;"&gt;<summary></span> <span style="color: #808080;"&gt;///</span><span style="color: #008000;"&gt; 所有产品都被抽完了的标记 </span><span style="color: #808080;"&gt;///</span> <span style="color: #808080;"&gt;</summary></span> <span style="color: #0000ff;"&gt;private</span> <span style="color: #0000ff;"&gt;static</span> <span style="color: #0000ff;"&gt;bool</span> allPrizeOut = <span style="color: #0000ff;"&gt;false</span><span style="color: #000000;"&gt;; </span><span style="color: #808080;"&gt;///</span> <span style="color: #808080;"&gt;<summary></span> <span style="color: #808080;"&gt;///</span><span style="color: #008000;"&gt; 当前轮次ID </span><span style="color: #808080;"&gt;///</span> <span style="color: #808080;"&gt;</summary></span> <span style="color: #0000ff;"&gt;private</span> <span style="color: #0000ff;"&gt;static</span> <span style="color: #0000ff;"&gt;int</span> currentRoundId = <span style="color: #800080;"&gt;0</span><span style="color: #000000;"&gt;; </span><span style="color: #0000ff;"&gt;public</span> ILotteryAppService LotteryAppService { <span style="color: #0000ff;"&gt;get</span>; <span style="color: #0000ff;"&gt;set</span><span style="color: #000000;"&gt;; } </span><span style="color: #808080;"&gt;///</span> <span style="color: #808080;"&gt;<summary></span> <span style="color: #808080;"&gt;///</span><span style="color: #008000;"&gt; 抽奖基数,只要被该数整除就中奖 </span><span style="color: #808080;"&gt;///</span> <span style="color: #808080;"&gt;</summary></span> <span style="color: #0000ff;"&gt;private</span> <span style="color: #0000ff;"&gt;static</span> <span style="color: #0000ff;"&gt;int</span> baseNumber =<span style="color: #800080;"&gt;100</span><span style="color: #000000;"&gt;; </span><span style="color: #0000ff;"&gt;private</span> <span style="color: #0000ff;"&gt;static</span> IDictionary<<span style="color: #0000ff;"&gt;int</span>,DateTime> userDrawTime=<span style="color: #0000ff;"&gt;new</span> Dictionary<<span style="color: #0000ff;"&gt;int</span>,DateTime><span style="color: #000000;"&gt;(); </span><span style="color: #0000ff;"&gt;private</span> <span style="color: #0000ff;"&gt;bool</span> CheckUserDrawTime(<span style="color: #0000ff;"&gt;int</span><span style="color: #000000;"&gt; userId) { </span><span style="color: #0000ff;"&gt;if</span><span style="color: #000000;"&gt; (userDrawTime.ContainsKey(userId)) { </span><span style="color: #0000ff;"&gt;return</span> userDrawTime[userId].AddSeconds(<span style="color: #800080;"&gt;8</span>) < DateTime.Now;<span style="color: #008000;"&gt;//</span><span style="color: #008000;"&gt;8s后可以抽奖 </span>

<span style="color: #000000;"> }
<span style="color: #0000ff;">else<span style="color: #000000;">
{
<span style="color: #0000ff;">return <span style="color: #0000ff;">true<span style="color: #000000;">;
}
}
<span style="color: #808080;">/// <span style="color: #808080;">


<span style="color: #808080;">///<span style="color: #008000;"> 抽奖一次
<span style="color: #808080;">/// <span style="color: #808080;">

<span style="color: #808080;">///
<span style="color: #808080;"><param name="userId">

<span style="color: #808080;">///
<span style="color: #808080;">

<span style="color: #000000;"> [HttpGet]
[Route(
<span style="color: #800000;">"
<span style="color: #800000;">Draw/{userId}<span style="color: #800000;">"<span style="color: #000000;">)]
<span style="color: #0000ff;">public DrawResult Draw(<span style="color: #0000ff;">int<span style="color: #000000;"> userId)
{
<span style="color: #0000ff;">if (!<span style="color: #000000;">start)
{
<span style="color: #0000ff;">return <span style="color: #0000ff;">new DrawResult(<span style="color: #800080;">400,<span style="color: #800080;">0,<span style="color: #800000;">"<span style="color: #800000;">抽奖未开始<span style="color: #800000;">"<span style="color: #000000;">);
}
<span style="color: #0000ff;">if<span style="color: #000000;"> (allPrizeOut)
{
<span style="color: #0000ff;">return <span style="color: #0000ff;">new DrawResult(<span style="color: #800080;">400,<span style="color: #800000;">"<span style="color: #800000;">所有奖品已抽完<span style="color: #800000;">"<span style="color: #000000;">);
}
<span style="color: #0000ff;">if (!<span style="color: #000000;">CheckUserDrawTime(userId))
{
<span style="color: #0000ff;">return <span style="color: #0000ff;">new DrawResult(<span style="color: #800080;">400,<span style="color: #800000;">"<span style="color: #800000;">请求过于频繁,请稍后再试<span style="color: #800000;">"<span style="color: #000000;">);
}

      </span><span style="color: #0000ff;"&gt;int</span> myNumber = Sequence++<span style="color: #000000;"&gt;; 
      userDrawTime[userId] </span>= DateTime.Now;<span style="color: #008000;"&gt;//</span><span style="color: #008000;"&gt;记录用户这次抽奖的时间</span>

      <span style="color: #0000ff;"&gt;if</span> (myNumber%baseNumber == <span style="color: #800080;"&gt;0</span>) <span style="color: #008000;"&gt;//</span><span style="color: #008000;"&gt;中奖啦! </span>

<span style="color: #000000;"> {
<span style="color: #0000ff;">if<span style="color: #000000;"> (winnerList.Contains(userId))
{
<span style="color: #008000;">//<span style="color: #008000;">用户已经中奖,不用再抽
<span style="color: #0000ff;">return <span style="color: #0000ff;">new DrawResult(<span style="color: #800080;">200,<span style="color: #800000;">"<span style="color: #800000;">您已经中过奖了<span style="color: #800000;">"<span style="color: #000000;">);
}
<span style="color: #0000ff;">var result =<span style="color: #000000;"> LotteryAppService.WriteAWinner(userId,currentRoundId);

          </span><span style="color: #0000ff;"&gt;switch</span><span style="color: #000000;"&gt; (result.ExceptionType) 
          { 
              </span><span style="color: #0000ff;"&gt;case</span><span style="color: #000000;"&gt; LotteryExceptionType.NoException: 
              { 
                  winnerList.Add(userId);

                  </span><span style="color: #0000ff;"&gt;return</span> <span style="color: #0000ff;"&gt;new</span> DrawResult(<span style="color: #800080;"&gt;200</span>,result.PrizeId,<span style="color: #800000;"&gt;""</span><span style="color: #000000;"&gt;); 
              } 
              </span><span style="color: #0000ff;"&gt;case</span><span style="color: #000000;"&gt; LotteryExceptionType.AllPrizeOut: 
              { 
                  allPrizeOut </span>= <span style="color: #0000ff;"&gt;true</span><span style="color: #000000;"&gt;; 
                  </span><span style="color: #0000ff;"&gt;return</span> <span style="color: #0000ff;"&gt;new</span> DrawResult(<span style="color: #800080;"&gt;400</span>,<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;所有奖品已抽完</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;);

              } 
              </span><span style="color: #0000ff;"&gt;case</span><span style="color: #000000;"&gt; LotteryExceptionType.InvalidLotteryRound: 
              { 
                  </span><span style="color: #0000ff;"&gt;return</span> <span style="color: #0000ff;"&gt;new</span> DrawResult(<span style="color: #800080;"&gt;400</span>,<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;抽奖轮次无效</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;); 
              } 
              </span><span style="color: #0000ff;"&gt;default</span><span style="color: #000000;"&gt;: 
              { 
                  </span><span style="color: #0000ff;"&gt;return</span> <span style="color: #0000ff;"&gt;new</span> DrawResult(<span style="color: #800080;"&gt;400</span>,<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;当前用户无效</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;); 
              }

          }

      } 
      </span><span style="color: #0000ff;"&gt;return</span> <span style="color: #0000ff;"&gt;new</span> DrawResult(<span style="color: #800080;"&gt;200</span>,<span style="color: #800000;"&gt;""</span><span style="color: #000000;"&gt;);

  }


  </span><span style="color: #808080;"&gt;///</span> <span style="color: #808080;"&gt;<summary></span> 
  <span style="color: #808080;"&gt;///</span><span style="color: #008000;"&gt; 获得我的奖品对象 
  </span><span style="color: #808080;"&gt;///</span> <span style="color: #808080;"&gt;</summary></span> 
  <span style="color: #808080;"&gt;///</span> <span style="color: #808080;"&gt;<param name="userId"&gt;</param></span> 
  <span style="color: #808080;"&gt;///</span> <span style="color: #808080;"&gt;<returns></returns></span> 

<span style="color: #000000;"> [HttpGet]
[Route(<span style="color: #800000;">"<span style="color: #800000;">MyPrize/{userId}<span style="color: #800000;">"<span style="color: #000000;">)]
<span style="color: #0000ff;">public IList GetMyPrize(<span style="color: #0000ff;">int<span style="color: #000000;"> userId)
{
<span style="color: #0000ff;">return<span style="color: #000000;"> LotteryAppService.GetMyPrize(userId);
}

  </span><span style="color: #808080;"&gt;///</span> <span style="color: #808080;"&gt;<summary></span> 
  <span style="color: #808080;"&gt;///</span><span style="color: #008000;"&gt; 开始新一轮的抽奖 
  </span><span style="color: #808080;"&gt;///</span> <span style="color: #808080;"&gt;</summary></span> 
  <span style="color: #808080;"&gt;///</span> <span style="color: #808080;"&gt;<param name="roundId"&gt;</param></span> 

<span style="color: #000000;"> [HttpPost]
[Route(<span style="color: #800000;">"<span style="color: #800000;">StartNewLotteryRound<span style="color: #800000;">"<span style="color: #000000;">)]
[AbpApiAuthorize(PermissionNames.Admin)]
<span style="color: #0000ff;">public <span style="color: #0000ff;">bool StartNewLotteryRound(<span style="color: #0000ff;">int<span style="color: #000000;"> roundId)
{

      start </span>= <span style="color: #0000ff;"&gt;true</span><span style="color: #000000;"&gt;; 
      allPrizeOut </span>= <span style="color: #0000ff;"&gt;false</span><span style="color: #000000;"&gt;; 
      currentRoundId </span>=<span style="color: #000000;"&gt; roundId; 
      </span><span style="color: #0000ff;"&gt;return</span> <span style="color: #0000ff;"&gt;true</span><span style="color: #000000;"&gt;; 
  } 
  </span><span style="color: #808080;"&gt;///</span> <span style="color: #808080;"&gt;<summary></span> 
  <span style="color: #808080;"&gt;///</span><span style="color: #008000;"&gt; 获得当前轮次的奖品和获奖者 
  </span><span style="color: #808080;"&gt;///</span> <span style="color: #808080;"&gt;</summary></span> 
  <span style="color: #808080;"&gt;///</span> <span style="color: #808080;"&gt;<returns></returns></span> 

<span style="color: #000000;"> [HttpGet]
[Route(<span style="color: #800000;">""<span style="color: #000000;">)]
<span style="color: #0000ff;">public IList<span style="color: #000000;"> GetLotteries()
{
<span style="color: #0000ff;">return<span style="color: #000000;"> LotteryAppService.GetLotteries(currentRoundId);
}
<span style="color: #808080;">/// <span style="color: #808080;">


<span style="color: #808080;">///<span style="color: #008000;"> 获得所有的奖品和获奖者
<span style="color: #808080;">/// <span style="color: #808080;">

<span style="color: #808080;">/// <span style="color: #808080;">
<span style="color: #000000;"> [HttpGet]
[Route(<span style="color: #800000;">"<span style="color: #800000;">All<span style="color: #800000;">"<span style="color: #000000;">)]
<span style="color: #0000ff;">public IList<span style="color: #000000;"> GetAllLotteries()
{
<span style="color: #0000ff;">return LotteryAppService.GetLotteries(<span style="color: #800080;">0<span style="color: #000000;">);
}
<span style="color: #808080;">/// <span style="color: #808080;">
<span style="color: #808080;">///<span style="color: #008000;"> 清空中奖结果,各种缓存
<span style="color: #808080;">/// <span style="color: #808080;">

<span style="color: #808080;">/// <span style="color: #808080;">
<span style="color: #000000;"> [HttpPost]
[Route(<span style="color: #800000;">"<span style="color: #800000;">Clean<span style="color: #800000;">"<span style="color: #000000;">)]
[AbpApiAuthorize(PermissionNames.Admin)]
<span style="color: #0000ff;">public <span style="color: #0000ff;">bool<span style="color: #000000;"> Clean()
{
Sequence = <span style="color: #800080;">1<span style="color: #000000;">;
start = <span style="color: #0000ff;">false<span style="color: #000000;">;
winnerList.Clear();
LotteryAppService.CleanLotteries();
<span style="color: #0000ff;">return <span style="color: #0000ff;">true<span style="color: #000000;">;
}
<span style="color: #808080;">/// <span style="color: #808080;">
<span style="color: #808080;">///<span style="color: #008000;"> 获取是否显示抽奖图标
<span style="color: #808080;">/// <span style="color: #808080;">

<span style="color: #808080;">/// <span style="color: #808080;">
<span style="color: #000000;"> [HttpGet]
[Route(<span style="color: #800000;">"<span style="color: #800000;">ShowLotteryIcon<span style="color: #800000;">"<span style="color: #000000;">)]
<span style="color: #0000ff;">public <span style="color: #0000ff;">bool<span style="color: #000000;"> GetShowLotteryIcon()
{
<span style="color: #0000ff;">return<span style="color: #000000;"> LotteryAppService.ShowLotteryIcon;
}
<span style="color: #808080;">/// <span style="color: #808080;">
<span style="color: #808080;">///<span style="color: #008000;"> 设置是否显示抽奖图标
<span style="color: #808080;">/// <span style="color: #808080;">

<span style="color: #808080;">/// <span style="color: #808080;"><param name="show">
<span style="color: #808080;">/// <span style="color: #808080;">
<span style="color: #000000;"> [HttpPut]
[Route(<span style="color: #800000;">"<span style="color: #800000;">ShowLotteryIcon/{show}<span style="color: #800000;">"<span style="color: #000000;">)]
<span style="color: #0000ff;">public HttpResponseMessage SetShowLotteryIcon(<span style="color: #0000ff;">bool<span style="color: #000000;"> show)
{

      </span><span style="color: #0000ff;"&gt;try</span><span style="color: #000000;"&gt; 
      { 
          LotteryAppService.ShowLotteryIcon </span>=<span style="color: #000000;"&gt; show; 
          </span><span style="color: #0000ff;"&gt;return</span> Request.CreateResponse(HttpStatusCode.OK,<span style="color: #0000ff;"&gt;true</span><span style="color: #000000;"&gt;); 
      } 
      </span><span style="color: #0000ff;"&gt;catch</span><span style="color: #000000;"&gt; (Exception ex) 
      { 
          </span><span style="color: #0000ff;"&gt;var</span> resp = <span style="color: #0000ff;"&gt;new</span><span style="color: #000000;"&gt; HttpResponseMessage(HttpStatusCode.BadGateway) 
          { 
              Content </span>= <span style="color: #0000ff;"&gt;new</span> StringContent(<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;设置ShowLotteryIcon失败:</span><span style="color: #800000;"&gt;"</span> +<span style="color: #000000;"&gt; ex.Message),ReasonPhrase </span>= <span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;Gateway failed</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt; 
          }; 
          </span><span style="color: #0000ff;"&gt;throw</span> <span style="color: #0000ff;"&gt;new</span><span style="color: #000000;"&gt; HttpResponseException(resp); 
      } 
  }


  </span><span style="color: #808080;"&gt;///</span> <span style="color: #808080;"&gt;<summary></span> 
  <span style="color: #808080;"&gt;///</span><span style="color: #008000;"&gt; 设置Base Number 
  </span><span style="color: #808080;"&gt;///</span> <span style="color: #808080;"&gt;</summary></span> 
  <span style="color: #808080;"&gt;///</span> <span style="color: #808080;"&gt;<param name="number"&gt;</param></span> 
  <span style="color: #808080;"&gt;///</span> <span style="color: #808080;"&gt;<returns></returns></span> 

<span style="color: #000000;"> [HttpPut]
[AbpApiAuthorize(PermissionNames.Admin)]
[Route(<span style="color: #800000;">"<span style="color: #800000;">SetBaseNumber/{number}<span style="color: #800000;">"<span style="color: #000000;">)]
<span style="color: #0000ff;">public <span style="color: #0000ff;">bool SetBaseNumber(<span style="color: #0000ff;">int<span style="color: #000000;"> number)
{
baseNumber =<span style="color: #000000;"> number;
<span style="color: #0000ff;">return <span style="color: #0000ff;">true<span style="color: #000000;">;
}
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读