Всем привет. Делаю игру, и мне надо сделать вот такой параметр как редкость у предмета. Что это такое? - Это параметр отвечающий за то, как часто или редко будет появляться. Есть 5 уровней: Очень часто, Часто, Нормально, Редко, Очень редко.
Так вот как это сделать то, я что то не пойму сути самой. Как это будет работать. Нужна помощь, заранее спасибо. New Games Studio --------------------------------------------------------------------------------------- Проекты: DeadDay - Online --- Мертвый день: Выживание
JackNazaryan, можно догадаться, что игра эта http://gcup.ru/forum/9-81849-1, а так как в JS генерировать не вариант, то код будет на PHP. Самый интересный вопрос в расстановке вероятностей. В Diablo-похожих играх уникальные только у боссов или за какие-то определённые действия, для остальных правильно подобранные коэффициенты.
Сообщение отредактировал Lertmind - Среда, 28 Сентября 2016, 10:02
URGINSAN, если честно, я про такой вариант тоже думал. Но он мне показался каким то не уместным. А почему я так решил, да из-за того, что в принципе не знал как это устроено. Но возможно со всеми доработками может и выберу. Тем более, то что, ты мне написал не сильно отличается от php.
Lertmind, я конечно не знаю с каким ты смыслом так сказал
Цитата
, можно догадаться, что игра эта http://gcup.ru/forum/9-81849-1,
Но да, это должно быть на php. При чем количество еденицы вероятности будет браться из БД.
Нет, вероятность выпода предмета будет у каждого действия в игре. Будь то это, бой, кража, обыск и т.д. New Games Studio --------------------------------------------------------------------------------------- Проекты: DeadDay - Online --- Мертвый день: Выживание
Но да, это должно быть на php. При чем количество еденицы вероятности будет браться из БД.
Так в чем проблема-то? Добавь поле с названием, например "rare" в таблицу предметов, в это поле записывает процент, например от 1 до 100 (это будут проценты). А дальше все просто, достаешь значение из этого поля и считаешь, следующим образом:
Код
$db_rareItem = 15; #Допустим это значение мы взяли из поля "rare" в таблице предметов $chance = rand(1, 100) + $db_rareItem; if ($chance >= 100){ echo "Предмет получен!"; }
Так что нет нужды в лишнем сложении. Замечу, что лучше хранить во float от 0 до 1, тогда можно легко задавать, допустим, 0.125%:
Код
if (random() < 0.00125) { "ok" }
По какой-то нелепости в php нет случайного числа для промежутка [0, 1) и приходится писать костыли, впрочем никогда не считал PHP нормальным языком.
Добавлено (29 сентября 2016, 00:46) --------------------------------------------- DeadDay, вот тебе вариант: 1. В БД указываешь не вероятность, а редкость (5 возможных значений). 2. Когда происходит событие (бой, кража, ...) случайно определяешь выпадет ли предмет вообще. 3. Для каждой редкости свои вероятности, значит выбираешь редкость предмета с помощью алгоритма выбора предметов с разными вероятностями. Этот алгоритм известен всем, например вариант у Unity:
Код
float Choose (float[] probs) { float total = 0;
foreach (float elem in probs) { total += elem; }
float randomPoint = Random.value * total;
for (int i= 0; i < probs.Length; i++) { if (randomPoint < probs[i]) { return i; } randomPoint -= probs[i]; } return probs.Length - 1; }
import random def random_pick(some_list, probabilities): x = random.uniform(0, 1) cumulative_probability = 0.0 for item, item_probability in zip(some_list, probabilities): cumulative_probability += item_probability if x < cumulative_probability: break return item
4. Случайно выбираешь предмет с выбранной редкостью.
Нет, не равносилен, логика абсолютно разная. И нужда, как раз была обусловлена необходимостью из за логики вычеслений.
ЦитатаLertmind ()
Замечу, что лучше хранить во float от 0 до 1, тогда можно легко задавать, допустим, 0.125%: Код if (random() < 0.00125) { "ok" } По какой-то нелепости в php нет случайного числа для промежутка [0, 1)
Замечайте после того, как вникните в особенности языка. А не сначала напишу, а потом пойму что зря написал, костыли нужны только там, где они выражены необходимостью, в данном случае можно и с целыми числами работать и не прибигать к тому, что потом вылезит боком.
ЦитатаLertmind ()
Для каждой редкости свои вероятности, значит выбираешь редкость предмета с помощью алгоритма выбора предметов с разными вероятностями.
А если он захочет на конкретный предмет выставить определнный процент выпадания? Делать еще одно поле, городить запросы в базу, в пустую, что в совокупности, без понимания построения рбд для высоконагруженных систем, приведет к беде и отдаче ответа пользователю через 30-40 секунд. Все ваши примеры - для стендалона, но никак не для браузерки.
Нет, не равносилен, логика абсолютно разная. И нужда, как раз была обусловлена необходимостью из за логики вычеслений.
Я не учёл, что твой код предполагает под $db_rareItem = 0 вероятность 1%, а под $db_rareItem = 99 вероятность 100% (оператор '>=' запутывает) и подумал, что ты ошибся, поэтому я рассчитывал на [0, 100]. Если брать твой код как есть, то равносильный код:
Проверил статистически, можно доказать и математически. Если не понимаешь, почему код равносилен, советую изучить матчасть.
Цитатаmaker-rus ()
Замечайте после того, как вникните в особенности языка
В библиотеках нормальных языков есть random() для промежутка [0, 1). Лучше воспринимать как шутку, так как для С и C++ такое недоразумение также присутствует.
Цитатаmaker-rus ()
в данном случае можно и с целыми числами работать и не прибигать к тому, что потом вылезит боком.
Для меня так удобней, а генерировать числа от 0 до 99999 чтобы задать вероятность 0.125% считаю нелепым, хотя и возможным. Не знаю про какие проблемы ты намекаешь.
Цитатаmaker-rus ()
А если он захочет на конкретный предмет выставить определнный процент выпадания?
* Во-первых, редкость намекает, что вероятность для каждой категории одинаковая. В "4. Случайно выбираешь предмет с выбранной редкостью." я не указал, но предполагается, что будет применён фильтр или вычисления характеристик предмета, чтобы игрок 5-ого уровня не получил предмет для 40-ого. * Во-вторых, как я написал, это один из вариантов и конечно он зависит от механики, так что нет смысла добавлять мысленно к моему алгоритму функционал, который сам же решаешь неэффективным методом, и жаловаться на это. Не говоря о том, что сам автор ещё не понимает как у него будет организована система предметов или не счёл важным нас посвятить в неё. * В-третьих, если ты разбираешься в высоконагруженных приложениях, то почему не предложил нормальный вариант? В логике твоего совета мы знаем какой предмет надо выкинуть, но не знаем частоту выпадения и обращаемся за ней в базу. Может ты предполагал, что будет выбор по всем предметам базы на основе их вероятностей, но твой код и слова на это не указывают.
Сообщение отредактировал Lertmind - Четверг, 29 Сентября 2016, 19:59
Для меня так удобней, а генерировать числа от 0 до 99999 чтобы задать вероятность 0.125% считаю нелепым, хотя и возможным. Не знаю про какие проблемы ты намекаешь.
Почти любой костыль, в php выходит боком в производительность, а так же размер потребляемой памяти, в идеале лучше использовать целые расчеты, чем использовать математику с дробными при каждом запросе, что приведет к несоизмеримому сжиранию производительности, погугли мат.тесты на php, в среднем при выполнении 100 мат.операций (косинус,синус,тангенс и тд, кроме rand()) (512 мб / 1 ядро), скорость отдачи страницы доходит до 3 секунд, что при многопользовательской игре с онлайном например, в 1000 игроков вырастет в 5-6 раз. Тут я понятно объяснил?
Цитата
* Во-первых, редкость намекает, что вероятность для каждой категории одинаковая. В "4. Случайно выбираешь предмет с выбранной редкостью." я не указал, но предполагается, что будет применён фильтр или вычисления характеристик предмета, чтобы игрок 5-ого уровня не получил предмет для 40-ого.
Нет. В хороших играх, коэффициент выпадания для каждой вещи уникален, но никак не обобщен. Подсказывать примеры я надеюсь не надо...
Цитата
Во-вторых, как я написал, это один из вариантов и конечно он зависит от механики, так что нет смысла добавлять мысленно к моему алгоритму функционал, который сам же решаешь неэффективным методом, и жаловаться на это. Не говоря о том, что сам автор ещё не понимает как у него будет организована система предметов или не счёл важным нас посвятить в неё.
Решаю не эффективным способом? Бред. В данном случае, я привел самое элементарное, что будет делать автор в данной ситуации. А по факту, при любом подходе, здесь не избежать дополнительных "пустых" запросов, потому что ваша архитектура заведомо провальная, для браузерки. Дергать эти данные из хэш-таблиц итд != делать доп. "пустые" запросы в рбд, которая и без того будет страдать.
ЦитатаLertmind ()
В-третьих, если ты разбираешься в высоконагруженных приложениях, то почему не предложил нормальный вариант? В логике твоего совета мы знаем какой предмет надо выкинуть, но не знаем частоту выпадения и обращаемся за ней в базу. Может ты предполагал, что будет выбор по всем предметам базы на основе их вероятностей, но твой код и слова на это не указывают.
Нет, я предполагал, что выбор будет по вероятностям и редкости предмета и все это будет, в одном запросе. То есть получаем процент удачи получения редкой вещи, например от 1 до 10 включительно. Если удача больше 5, то получаем редкую шмотку, если больше 8, то 2 редкие шмотки, если 10, то целых три шмотки. Дальше получаем коэффициент выпадения. Определяем список вещей, которые можно получить персонажу и только потом отправляем запрос в базу, который будет содержать следующее: нам нужны перечисленные шмотки + в зависимости от удачи еще несколько, редких, у которых коэффициент +-1 = нашему, естественно все это ищется по индексам, далее, другим запросом все наши вещички отправляем в базу. В итоге база обходится легким испугом. А мы сильно не захламляем ее бесполезными запросами и бесполезно не лочим строки.
Сообщение отредактировал maker-rus - Понедельник, 03 Октября 2016, 22:06