Автор, если нужна 100% гарантия, ни один алгоритм получения случайного числа вам не поможет. Если у вас 1000 лотерейных билетов, а у меня 1, вероятность вашего выигрыша огромна, но не 100%-на. Создайте в таблице поле qty, каждому подарку вбейте в это поле столько, сколько в реале вы будете отправлять. При поиске подарка, сортируйте по этому полю по убыванию, и строке которую получили уменьшайте qty на 1. Или храните в отдельной таблице всю последовательность подарков.
Ну например подарок с шансом 90%, туда пишете 5000 штук, подарку с шансом 10% 50 штук. Далее при поиске, сортируйте по этому полю по убыванию, когда нашли, этому подарку уменьшайте это поле на 1. Или же как я дописал в том сообщении, храните в отдельной таблице всю последовательность подарков.
Это первое, что я предложил и это единственный вариант учёта реальных процентов шанса, но нужен ещё и период времени, за который сбудутся все хотелки ТС. Но увы и ах, ТС хочет гарантий, но упорно делает рандом.
Если каких-то призов, например дорогих, ограниченное кол-во, то при их выигрыше их исключают из розыгрыша (можно втихую, до оглашения окончательных результатов, чтобы раньше времени не снижать интерес к розыгрышу). Что касается вероятностей (шансов), в чем проблема снабдить каждый вид приза коэффициентом вероятности? Пример практической реализации вам уже подсказали. Генерируете «поверх» осн. таблицы доп. таблицу, в кот. кол-во записей для каждого вида приза пропорционально вероятности его выпадения. Можете, в качестве значения вероятности использовать, например, не долю единицы/проценты, а просто целое число, определяющее кол-во записей в доп. таблице для данного вида приза. Есть и др. способы. --- Добавлено --- Что это за условие/поле? Код (Text): `caseid`='{$id}'
Я не читал подробно что советуют. Но мне кажется казино работают так - прибыль должна быть больше расхода. Например у тебя 1000 у.е. Из них на подарки ты можешь потратить 40% от суммы прибыли. На старте у тебя прибыль 0. То есть изначально по логике ты в минусе. То есть ты можешь раздавать только самые дешевый подарки. Итак распределим иерархию подарков. 1. Подарки от 800 до 1000 у.е 2. Подарки от 600 до 800 у.е 3. Подарки от 400 до 600 у.е 4. Подарки от 200 до 400 у.е 5. Подарки от 100 до 200 у.е 6. Подарки от 10 до 100 у.е 7. Подарки от 2 до 9 у.е 8. Подарки от 1 до 2 у.е Самые дешевый у нас будут считаться 7,8. То есть ты не имеешь права дарить подарки выше. Допустим в течении часа от начала у тебя прибыль 2000 у.е 2000 - 40% = 800 у.е Теперь ты можешь уже дарить рандомно все подарки кроме 1 пункта. Но как только ты даришь подарок он вычитается и твоей прибыли. Вот и весь рандом. прибыль - 40% = максимальная возможность цены подарка. Все просто как три копейки. Смотря какая твоя жадность ты просто настраиваешь процент и все.
P.S. Записи в доп. таблице можно дополнительно не перемешивать. Они могут лежать «отрезками», соответствующими записям осн. таблицы. --- Добавлено --- ??? Это ответ на мой вопрос? --- Добавлено --- Чтобы выдрать в цитату фрагмент поста, выделите его и щелкните «Ответить» в появившейся всплывающей подсказке.
Да --- Добавлено --- Ну давайте коробку назовем категорией где можно выиграть определенный приз. У меня одна таблица для всех призов категорий.
По таблице это будет так Таблица прибыли: Код (Text): цена | тип_цены 10 | 1 8 | 0 11 | 1 20 | 1 1 | 1 100 | 1 20 | 0 0/1 - расход/прибыль Таблицы подарков Код (Text): id_подарка | название | цена 1 | машина | 2000 2 | ручка | 1 3 | пиво | 10 B обычным sql запросом считаешь сумму прибыли - 40% = 1 случайный подарок не больше расчетной цены.
Мне кажется топикстартер напрасно считает задачу сложной. Вполне естественно хранить все призы в таблице. Пусть там будет 10 дорогих, 100 средних и 500 дешёвых, это абсолютно не влияет на алгоритм. Там просто все призы. Хранить все экземпляры, а не типы призов. При выигрыше надо выбранный приз удалять или помечать как недоступный. Итого мы всегда имеем таблицу с доступными в данный момент призами. Вероятность поддерживается натуральным образом без специальных уловок: чем меньше осталось каких-то записей, тем меньше шансов, что будет выбрана именно такая запись. И абсолютно натуральным образом не получится выдать призов больше чем задумано изначально. Потому что они тупо кончатся и нечего будет выбирать! Остаётся решить как выбирать "случайную" запись. ORDER BY RAND() дорогая операция, но это не имеет значения если в таблице всего пяток строк. Временная перемешанная таблица поместится в кеше, в оперативной памяти сервера. Вот на больших таблицах уже надо трюкачить. Ещё раз: если у тебя число записей двух или трехзначное, то считай ты уже решил задачу, дальше не читай. - - - Трюк 1 с выборкой из большой таблицы тоже не rocket science У тебя есть первичный ключ, скорее всего автоинкремент. Один раз найди значение MAX(id). Вычисли на стороне PHP случайный "номер записи", $n = mt_rand(1, $maxId). Так как в нашей таблице будут "дырки", то запрос надо делать не на точное попадание, а на первую запись с ... WHERE id >= :n. Если вдруг нет такой записи (уже весь хвост выбрали), то повторить рандом и выборку. И так до момента пока не найдёшь подходящую запись или таблица не станет пустой. Трюк 2 с однократным перемешиванием тоже прост. Заполни таблицу в циклах 10 дорогих, 100 средних и 500 дешёвых или как там тебе надо, а потом сделай копию таблицы через INSERT INTO table2 ( SELECT * FROM table1 ORDER BY RAND() ) В запросе нет LIMIT и его надо выполнить только один раз! Выбирай из второй таблицы всегда первую доступную запись (с минимальным id) и удаляй / отмечай запись как недоступную. И так пока доступные записи не закончатся.