选择抽奖券获奖者

发布于 2025-01-05 07:42:48 字数 493 浏览 1 评论 0原文

我创建了一个脚本,用户可以通过完成任务来获得积分,然后他们获得的积分越多,赢得奖品的机会就越高。 它的运作方式就像抽奖券竞赛。

我的问题是创造赢家。

我可以使用如下代码选择一个随机获胜者:

    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?

我不完全确定,只是猜测,我也不知道如何编码。

谢谢

I've created a script where users can get points by completing tasks and then the more points they get the higher chance they have of winning the prize.
It works like a raffle ticket competition.

My problem is generating winners.

I can choose a random winner with a code like this:

    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]}";
    }

But this is just completely random and doesn't matter at all as to how many points the users have.

I believe I've got to create a temporary table that shows the users ID for every point they have, then use a similar script to select a random ID?

I'm not entire sure, just a guess, I also don't have a clue how that would be coded.

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

将军与妓 2025-01-12 07:42:48

您所问的实际上更多是一个统计问题,而不是编程问题。

您希望每个用户都有机会根据其输入的数量(“积分”)成比例地获胜。在现实世界中,这相当于每个用户获得的每一分,都将其名字放入帽子中,然后随机抽取一个名字。单张图画命名获胜者。

通过编程方式,您可以通过在零和所有用户授予的总分减一之间选择一个随机数来实现此目的(如果您愿意,可以从一开始。但计算机使用零,这通常更容易)。然后,您遍历用户,将每个人的总积分添加到运行总和中。当运行计数超过您选择的随机数时,您当前所在的用户获胜。

想象一下,你有三个参赛者,名字分别是 Joe、Bob 和 Alice:

Name  Points
------------
Joe   3
Bob   8
Alice 2

无论名字的顺序如何,概率都会起作用。

您选择一个介于 0 到 12(含 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 > 则为 3。随机值,乔获胜。然后加上 8。如果新的 11 大于随机值,则 Bob 获胜。然后添加 2。现在该数字大于您的随机值(因为 13 高于您可以生成的最大值)。

理论上,这可以在数据库中完成 - 但这实际上并不是一个合适的任务。这是应用程序逻辑,我建议在 PHP 中进行(SQL 只是所有用户、他们的积分以及总积分的基本 SELECT)。

What you're asking is really more a statistics question than a programming one.

You want each user to have a chance to win proportional to the number of entries they made ("points"). In the real world, this is the equivalent of putting each user's name into a hat once for each point they get, then drawing one name at random. The single drawing names the winner.

Programmatically, you do this by choosing a random number between zero and the total number of points awarded across all users minus one (you could, if you wish, start at one. But computers use zero and that's generally easier). Then you iterate through the users, adding each one's point total to a running sum. When the running count exceeds the random number you've chosen, the user you're currently on has won.

Imagine you have three entrants, named Joe, Bob, and Alice:

Name  Points
------------
Joe   3
Bob   8
Alice 2

It doesn't matter what order the names are in, the probabilities will work anyhow.

You select a random number between zero and 12 inclusive (12=3+8+2-1). On a 0-2, Joe wins (2=3-1). On a 3-10, Bob wins (10=8+3-1). On an 11-12, Alice wins (12=3+8+2-1). Note that the number of values included in each range is equal to the number of points - thus, the odds of a given individual being selected are (individual's points / total points), the logic you desire.

The way you check the winner is as I said above - start a sum at zero, then add 3. If 3 > randomvalue, Joe wins. Then add 8 to that. If the new 11 is greater than the random value, Bob wins. Then add 2. Now the number is greater than your random value (since 13 is higher than the max you could generate).

This could, in theory, be done in a database - but it's not really an appropriate task there. This is application logic, and I'd recommend doing it in PHP (the SQL would just be a basic SELECT of all the users, their points, and perhaps the point total).

陪你到最终 2025-01-12 07:42:48

创建一个临时表,其中每个点的每个成员占一行。然后选择随机行。

这是我刚刚为我的网站上的抽奖活动创建的存储过程。该代码是从网络上的不同帖子和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 $

Create a temporary table with one row for each member for each point. Then select a random row.

Here is a stored procedure that I just created for a raffle on my site. The code is culled from different posts on the web, and mysql reference:

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 $
南…巷孤猫 2025-01-12 07:42:48

用户及其积分可以显示在 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

Users and their points can be shown in a 2D array, like this (sorted by user points):

    P %.......
    o %.......
    i %%......
    n %%%.....
    t %%%%%...
    s %%%%%%%%
Users 0123456789

You try to select a random winner by creating a random 2d coordinate: (random user id, random user point between 0 and maximum user point), and checking if you've 'hit' a point. Very pseudo code:

$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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文