Rank.class.php 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. <?php
  2. namespace Cas\Module;
  3. class Rank
  4. {
  5. private $rankBase = array();
  6. private $rank = array() ;
  7. public function __construct()
  8. {
  9. $rank = array();
  10. # 注:目前的流量是按UV算的,具体流量请看:
  11. $rank[0] = 0.0295198432;
  12. $rank[1] = 0.0126163645;
  13. $rank[2] = 0.0062469378;
  14. $rank[3] = 0.0034909358;
  15. $rank[4] = 0.0034909358;
  16. $rank[5] = 0.0060019598;
  17. $rank[6] = 0.0099828515;
  18. $rank[7] = 0.0190470358;
  19. $rank[8] = 0.0401151396;
  20. $rank[9] = 0.0733096521;
  21. $rank[10] =0.0871509064;
  22. $rank[11] =0.0719010289;
  23. $rank[12] =0.0613669770;
  24. $rank[13] =0.0606932876;
  25. $rank[14] =0.0575085742;
  26. $rank[15] =0.0588559530;
  27. $rank[16] =0.0545688388;
  28. $rank[17] =0.0447084762;
  29. $rank[18] =0.0462395884;
  30. $rank[19] =0.0537726605;
  31. $rank[20] =0.0562224400;
  32. $rank[21] =0.0576923077;
  33. $rank[22] =0.0513841254;
  34. $rank[23] =0.0341131798;
  35. $this->rankBase = $rank;
  36. }
  37. /**
  38. * 根据给定的开始与结束时段参数,动态设计$this->rank
  39. *
  40. * @param int $intHourStart
  41. * @param int $intHourEnd
  42. */
  43. private function setRank($intHourStart, $intHourEnd) {
  44. if($intHourStart>0 || $intHourEnd<23) {
  45. $arrRank = array_slice($this->rankBase, $intHourStart, ($intHourEnd-$intHourStart+1), true);
  46. $intSum = array_sum($arrRank);
  47. $this->rank = array_fill(0, 24, 0);
  48. foreach($arrRank as $key => $val) {
  49. $this->rank[$key] = $val/$intSum;
  50. }
  51. } else {
  52. $this->rank = $this->rankBase;
  53. }
  54. }
  55. /**
  56. * @name getTimeValue
  57. * @desc 获得每个时间段应该获得的奖品
  58. * @param int $num
  59. * @param int $intHourStart 从该小时开始。$intHourStart >=0 && $intHourStart <= 23
  60. * @param int $intHourEnd 到该小时结果。$intHourEnd <= 23 && $intHourEnd >= $intHourStart
  61. */
  62. public function getTimeValue($num, $intHourStart = 0, $intHourEnd = 23)
  63. {
  64. $this->setRank($intHourStart, $intHourEnd);
  65. $value = array();
  66. $value = array_fill(0, 24, 0);
  67. $dec = $num;
  68. for($intHour=$intHourStart;$intHour<=$intHourEnd;++$intHour) {
  69. $cur = floor($this->rank[$intHour] * $num) ;
  70. $dec -= $cur;
  71. $value[$intHour] = $cur;
  72. }
  73. while ($dec) {
  74. $value[rand($intHourStart, $intHourEnd)] ++ ;
  75. $dec-- ;
  76. }
  77. $total = 0 ;
  78. for($intHour=$intHourStart;$intHour<=$intHourEnd;++$intHour) {
  79. $total += $value[$intHour] ;
  80. $value[$intHour] = $total;
  81. }
  82. return $value;
  83. }
  84. /**
  85. * @name winnerCal
  86. * @desc 计算是否胜出发奖品
  87. */
  88. public function winnerCal($rank, $prized)
  89. {
  90. $hour = date('G');
  91. $should = $rank[$hour];
  92. while($prized >= $should && $hour < 23) {
  93. $should += $rank[++$hour];
  94. }
  95. if($should <= $prized) {//应发数小于等于实发数,则不胜出
  96. return false;
  97. }
  98. $now = $hour == date('G') ? time() : mktime($hour, 0, 0);
  99. $random = array();
  100. $max = mktime($hour, 0, 0) + 60 * 60;
  101. $intWillSend = $should - $prized;//应发-实发=将发
  102. # 获取循环次数
  103. $intSecondBetween = $max - $now + 1;//用于命中奖品的总秒数
  104. if($intWillSend/$intSecondBetween > 10) {//将发是用于命中奖品的总秒数的十倍以上时,直接返回当前秒
  105. return $now;
  106. }
  107. $intLoopTimes = $intWillSend;
  108. while ($intLoopTimes) {
  109. $random[] = rand($now, $max);
  110. $intLoopTimes -- ;
  111. }
  112. $min = self::getMinNum($random);
  113. return $min;
  114. }
  115. /**
  116. * @name getMinNum
  117. * @desc 获得数组中最小的数
  118. */
  119. public function getMinNum($array)
  120. {
  121. $min = 0 ;
  122. foreach ($array as $v)
  123. {
  124. if($min == 0 || $min > $v)
  125. {
  126. $min = $v;
  127. }
  128. }
  129. return $min;
  130. }
  131. }
  132. ?>