<?php
class
Prize {
# ID
public
$id
= null;
# 权重
public
$weight
= null;
# 奖品名
public
$name
= null;
# 权重范围区间起始值
protected
$start
= 0;
# 权重范围区间结束值
protected
$end
= 0;
public
function
__construct(
$id
,
$weight
,
$name
) {
if
(!
$id
) {
throw
new
Exception(
'奖品ID为空.'
);
}
$this
->id =
$id
;
$this
->weight =
$weight
?
$weight
: 0;
$this
->name =
$name
?
$name
:
'随机奖品'
.
$id
;
}
# id
public
function
getId() {
return
$this
->id;
}
# 权重
public
function
getWeight() {
return
$this
->weight;
}
# 设置权重范围区间
public
function
setRange(
$start
,
$end
) {
$this
->start =
$start
;
$this
->
end
=
$end
;
}
# 判断随机数是否在权重范围区间
public
function
inRange(
$num
) {
return
(
$num
>=
$this
->start) && (
$num
end
);
}
}
class
PrizePoll
implements
IteratorAggregate, Countable {
# 奖品集
protected
$items
=
array
();
# 加入奖品
public
function
addItem(Prize
$item
) {
$this
->items[
$item
->getId()] =
$item
;
return
$this
;
}
# 删除奖品
public
function
removeItem(
$itemId
) {
if
(isset(
$this
->items[
$itemId
])) {
unset(
$this
->items[
$itemId
]);
}
return
$this
;
}
# 更新奖品
public
function
updateItem(Prize
$item
) {
if
(isset(
$this
->items[
$item
->getId()])) {
$this
->items[
$item
->getId()] =
$item
;
}
return
$this
;
}
# 获取所有奖品
public
function
getItems() {
return
$this
->items;
}
# 所有所有可用奖品(如果权重为0,说明这个奖品永远不可能抽到)
public
function
getVisibleItems() {
$items
=
array
();
foreach
(
$this
->items
as
$item
) {
if
(
$item
->getWeight()) {
$items
[
$item
->getId()] =
$item
;
}
}
return
$items
;
}
# Countable::
count
public
function
count
() {
return
count
(
$this
->items);
}
# IteratorAggregate::getIterator()
public
function
getIterator() {
return
new
ArrayIterator(
$this
->items);
}
}
class
SimpleTurn {
# 奖池
protected
$poll
= null;
public
function
__construct(PrizePoll
$poll
) {
if
(
$poll
) {
$this
->setPoll(
$poll
);
}
}
# 抽奖
public
function
run(PrizePoll
$poll
) {
$poll
=
$poll
?
$poll
:
$this
->poll;
if
( !
$poll
) {
throw
new
Exception(
'奖池未初始化'
);
}
if
(
$poll
->
count
() getVisibleItems();
if
(
count
(
$items
) getWeight();
$end
=
$sum
;
# 设置奖品的权重范围区间
$item
->setRange(
$start
,
$end
);
}
# 随机数
$rand
=
$this
->getRandNum(1,
$sum
);
# 区间段判断
foreach
(
$items
as
$item
) {
if
(
$item
->inRange(
$rand
)) {
return
$item
;
}
}
return
null;
}
# 获取随机数
public
function
getRandNum(
$min
,
$max
) {
return
mt_rand(
$min
?
$min
: 1,
$max
);
}
# 设置奖池
public
function
setPoll(PrizePoll
$poll
) {
$this
->poll =
$poll
;
}
}
# 示例
try
{
$prizePoll
=
new
PrizePoll();
$prizePoll
->addItem(
new
Prize(1, 5))
->addItem(
new
Prize(2, 6))
->addItem(
new
Prize(3, 7))
->addItem(
new
Prize(4, 2));
$turn
=
new
SimpleTurn(
$prizePoll
);
$prize
=
$turn
->run();
var_dump(
$prize
);
}
catch
(Exception
$e
) {
print_r(
$e
);
}