Выберите победителей лотерейных билетов

Я создал сценарий, в котором пользователи могут получить очки, выполнив задания, а затем больше очков, которые у них получат больше шансов получить выигрыш. Он работает как конкурс лотерейных билетов.

Моя проблема заключается в создании победителей.

Я могу выбрать случайного победителя с таким кодом:

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

Но это просто совершенно случайно и вообще не имеет значения, сколько очков у пользователей.

Я считаю, что мне нужно создать временную таблицу, которая показывает идентификатор пользователей для каждой точки, которую они имеют, а затем использовать аналогичный скрипт для выбора случайного идентификатора?

Я не совсем уверен, просто думаю, я также не знаю, как это будет закодировано.

благодаря

То, что вы спрашиваете, – это скорее статистический вопрос, чем программирующий.

Вы хотите, чтобы каждый пользователь имел шанс выиграть пропорционально количеству сделанных ими записей («баллы»). В реальном мире это эквивалентно помещению имени каждого пользователя в шляпу один раз для каждой точки, которую они получают, а затем нарисовать одно имя наугад. Единственный рисунок называет победителя.

Программно, вы делаете это, выбирая случайное число между нулем и общим количеством баллов, присваиваемых всем пользователям минус один (вы можете, если хотите, начать с одного. Но компьютеры используют ноль, и это вообще проще). Затем вы перебираете пользователей, добавляя общую сумму каждого из них к текущей сумме. Когда количество запусков превышает выбранный вами случайный номер, пользователь, которого вы в настоящее время выиграли, выиграл.

Представьте, что у вас трое абитуриентов, которых зовут Джо, Боб и Элис:

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

Неважно, в каком порядке находятся имена, вероятность будет работать в любом случае.

Вы выбираете случайное число от нуля до 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> randomvalue, Джо выигрывает. Затем добавьте 8 к этому. Если новый 11 больше случайного значения, выигрывает Боб. Затем добавьте 2. Теперь число больше вашего случайного значения (поскольку 13 больше максимального, которое вы могли бы сгенерировать).

Теоретически это можно было бы сделать в базе данных, но на самом деле это не совсем подходящая задача. Это логика приложения, и я бы рекомендовал сделать это в PHP (SQL будет просто базовым SELECT для всех пользователей, их точек и, возможно, итоговой суммы).

Создайте временную таблицу с одной строкой для каждого элемента для каждой точки. Затем выберите случайную строку.

Вот хранимая процедура, которую я только что создал для лотереи на моем сайте. Код отбирается из разных сообщений в Интернете и ссылается на 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 $$ 

Пользователи и их точки могут отображаться в 2D-массиве, например, (отсортированные по пользовательским точкам):

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

Вы пытаетесь выбрать случайного победителя, создав случайную координату 2d: (случайный идентификатор пользователя, случайный пользовательский пункт между 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