<?php
namespace Cas\Module;

class Rank
{
	private $rankBase = array();
	private $rank = array() ;
	public function __construct()
	{
		$rank = array();
		# 注:目前的流量是按UV算的,具体流量请看:
		$rank[0] = 0.0295198432;
		$rank[1] = 0.0126163645;
		$rank[2] = 0.0062469378;
		$rank[3] = 0.0034909358;
		$rank[4] = 0.0034909358;
		$rank[5] = 0.0060019598;
		$rank[6] = 0.0099828515;
		$rank[7] = 0.0190470358;
		$rank[8] = 0.0401151396;
		$rank[9] = 0.0733096521;
		$rank[10] =0.0871509064;
		$rank[11] =0.0719010289;
		$rank[12] =0.0613669770;
		$rank[13] =0.0606932876;
		$rank[14] =0.0575085742;
		$rank[15] =0.0588559530;
		$rank[16] =0.0545688388;
		$rank[17] =0.0447084762;
		$rank[18] =0.0462395884;
		$rank[19] =0.0537726605;
		$rank[20] =0.0562224400;
		$rank[21] =0.0576923077;
		$rank[22] =0.0513841254;
		$rank[23] =0.0341131798;
		$this->rankBase = $rank;
	}

	/**
	 * 根据给定的开始与结束时段参数,动态设计$this->rank
	 *
	 * @param int $intHourStart
	 * @param int $intHourEnd
	 */
	private function setRank($intHourStart, $intHourEnd) {
	    if($intHourStart>0 || $intHourEnd<23) {
		    $arrRank = array_slice($this->rankBase, $intHourStart, ($intHourEnd-$intHourStart+1), true);
	        $intSum = array_sum($arrRank);
	        $this->rank = array_fill(0, 24, 0);
	        foreach($arrRank as $key => $val) {
	            $this->rank[$key] = $val/$intSum;
	        }
        } else {
        	$this->rank = $this->rankBase;
        }
	}

	/**
	 * @name getTimeValue
	 * @desc 获得每个时间段应该获得的奖品
	 * @param int $num
	 * @param int $intHourStart 从该小时开始。$intHourStart >=0 && $intHourStart <= 23
	 * @param int $intHourEnd 到该小时结果。$intHourEnd <= 23 && $intHourEnd >= $intHourStart
	 */
	public function getTimeValue($num, $intHourStart = 0, $intHourEnd = 23)
	{
		$this->setRank($intHourStart, $intHourEnd);
		$value = array();
		$value = array_fill(0, 24, 0);
		$dec = $num;
		for($intHour=$intHourStart;$intHour<=$intHourEnd;++$intHour) {
			$cur = floor($this->rank[$intHour] * $num) ;
            $dec -= $cur;
            $value[$intHour] = $cur;
		}
		while ($dec) {
			$value[rand($intHourStart, $intHourEnd)] ++ ;
			$dec-- ;
		}

		$total = 0 ;
	    for($intHour=$intHourStart;$intHour<=$intHourEnd;++$intHour) {
	    	$total += $value[$intHour] ;
	    	$value[$intHour] = $total;
        }
		return $value;
	}
	/**
	 * @name winnerCal
	 * @desc 计算是否胜出发奖品
	 */
	public function winnerCal($rank, $prized)
	{
		$hour = date('G');
		$should = $rank[$hour];

	    while($prized >= $should && $hour < 23) {
                $should += $rank[++$hour];
        }
		
	    if($should <= $prized) {//应发数小于等于实发数,则不胜出
            return false;
        }

        $now = $hour == date('G') ? time() : mktime($hour, 0, 0);

		$random = array();
		$max = mktime($hour, 0, 0) + 60 * 60;

		$intWillSend = $should - $prized;//应发-实发=将发

		# 获取循环次数
		$intSecondBetween = $max - $now + 1;//用于命中奖品的总秒数
		if($intWillSend/$intSecondBetween > 10) {//将发是用于命中奖品的总秒数的十倍以上时,直接返回当前秒
			return $now;
		}

		$intLoopTimes = $intWillSend;
		while ($intLoopTimes) {
			$random[] = rand($now, $max);
			$intLoopTimes -- ;
		}
		$min = self::getMinNum($random);
		return $min;
	}
	/**
	 * @name getMinNum
	 * @desc 获得数组中最小的数
	 */
	public function getMinNum($array)
	{
		$min = 0 ;
		foreach ($array as $v)
		{
			if($min == 0 || $min > $v)
			{
				$min = $v;
			}
		}
		return $min;
	}
}
?>