我创建了一个脚本,用户可以通过完成任务获得积分,然后获得的积分越多,获得奖励的机会就越大。 它就像抽奖活动一样。
我的问题是赢得胜利者。
我可以选择一个随机获胜者,其代码如下:
function selectWinners($count){
$select = mysql_query("SELECT first_name from `users` ORDER BY RAND() LIMIT {$count}");
$results = mysql_fetch_assoc($select);
echo "Winner is {$results[first_name]}";
}
但这完全是随机的,关于用户拥有多少点并不重要。
我相信我必须创建一个临时表,显示他们拥有的每个点的用户ID,然后使用类似的脚本来选择随机ID?
我不完全确定,只是一个猜测,我也不知道如何编码。
由于
答案 0 :(得分:9)
你要问的是一个统计问题,而不是一个编程问题。
您希望每个用户都有机会赢得他们所做的参赛作品数量(“积分”)。在现实世界中,这相当于将每个用户的名字放入帽子中,每次获得一个点,然后随机绘制一个名称。单张图画为获胜者命名。
通过编程,您可以选择一个介于0和所有用户的总分数减去1之间的随机数(如果您愿意,可以从1开始。但计算机使用零,这通常更容易)。然后,您遍历用户,将每个点的总数添加到运行总和中。当运行计数超过您选择的随机数时,您当前所在的用户就赢了。
想象一下,你有三个参赛者,名叫乔,鲍勃和爱丽丝:
Name Points
------------
Joe 3
Bob 8
Alice 2
名称的顺序无关紧要,概率无论如何都会起作用。
您可以选择0到12之间的随机数(12 = 3 + 8 + 2-1)。在0-2,乔获胜(2 = 3-1)。在3-10,鲍勃获胜(10 = 8 + 3-1)。在11-12,爱丽丝获胜(12 = 3 + 8 + 2-1)。请注意,每个范围中包含的值的数量等于点的数量 - 因此,选择给定个体的几率是(个人的点数/总点数),这是您想要的逻辑。
你检查获胜者的方式就像我上面所说的那样 - 在零开始一个总和,然后加3.如果3>随机值,乔赢了。然后添加8。如果新11大于随机值,则Bob获胜。然后添加2.现在该数字大于您的随机值(因为13高于您可以生成的最大值)。
理论上,这可以在一个数据库中完成 - 但它并不是一个真正适合的任务。这是应用程序逻辑,我建议在PHP中使用它(SQL只是所有用户的基本SELECT
,他们的点,也许是总点数。)
答案 1 :(得分:2)
为每个点创建一个临时表,每个成员都有一行。然后选择一个随机行。
这是我刚为我网站上的抽奖创建的存储过程。代码是从网上的不同帖子和mysql引用中挑选出来的:
CREATE PROCEDURE `getWinner` ()
BEGIN
-- Declare '_val' variables to read in each record from the cursor
DECLARE memberID_val INT DEFAULT 0;
DECLARE points_val INT DEFAULT 0;
-- Declare variables used just for cursor and loop control
DECLARE done INT DEFAULT 0;
DECLARE loop_cntr INT DEFAULT 0;
DECLARE num_rows INT DEFAULT 0;
-- Declare the cursor
DECLARE member_cur CURSOR FOR
SELECT id, points FROM member;
-- Declare 'handlers' for exceptions
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
DROP TEMPORARY TABLE IF EXISTS `raffle_table`;
CREATE TEMPORARY TABLE `raffle_table` (`id` int(10) unsigned NOT NULL AUTO_INCREMENT, `memberID` int(11) DEFAULT '0' ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
OPEN member_cur;
REPEAT
FETCH member_cur INTO memberID_val, points_val;
IF NOT done THEN
WHILE points_val > 0 DO
INSERT INTO raffle_table (memberID) values (memberID_val);
SET points_val = points_val - 1;
END WHILE;
END IF;
UNTIL done END REPEAT;
CLOSE member_cur;
SELECT memberID FROM `raffle_table` WHERE id >= (SELECT FLOOR( MAX(id) * RAND()) FROM `raffle_table` ) ORDER BY id LIMIT 1;
END $$
答案 2 :(得分:1)
用户及其点可以在2D数组中显示,如下所示(按用户点排序):
P %.......
o %.......
i %%......
n %%%.....
t %%%%%...
s %%%%%%%%
Users 0123456789
您尝试通过创建随机2d坐标来选择随机获胜者:(随机用户ID,0和最大用户点之间的随机用户点),并检查您是否“点击”某个点。非常伪代码:
$maxpoint = SELECT MAX(points) FROM users;
do{
$random_user = see for example http://www.greggdev.com/web/articles.php?id=6
$random_point = rand( 0, $maxpoints );
}while( $random_user->point >= $random_point ); // beware users with 0 point