Механика party random

  • Автор темы Автор темы 5ergiu5
  • Дата начала Дата начала

5ergiu5

Путник
VIP
Сообщения
7
Розыгрыши
0
Репутация
0
Реакции
0
Баллы
14
Подскажите, пожалуйста, если в пати несколько человек, то в каком порядке мемберы получают дроп относительно выпадающего случайного числа?

Пример, если в пати 3 человека, и GetRandomNumber(0.0, 100.0), то тот кто создал пати получит дроп, если число выпадет от 0 до 33.3, первым кого пригласили получит дроп, если число выпадет от 33.3 до 66.6, второго кого пригласили от 66.6 до 100? Или это как-то иначе работает?

GetRandomNumber(0.0, 100.0) взял от сюда:

пытался найти ответ в интернете и на форумах по ключевым словам party random GetRandomNumber member minmembers l2 и т.п. Не получилось
 

Самый обычный рандом. Никаких дополнительных манипуляций с шансом не производится:
C++:
User* CParty::DistributeItemToRandomMember(User* requester, CCreature* item, int itemCount) {
    const float PICKUP_RANGE = 1500.0f;

    std::vector<User*> allMembers;
    GetAllPartyMembers(allMembers, item);

    std::vector<User*> eligibleMembers;
    
    for (User* member : allMembers) {
        if (!member || !member->IsAlive() || !member->IsInRange(requester, PICKUP_RANGE)) {
            continue;
        }

        if (member->IsTrading()) {
            member->CancelTrade();
        }

        if (member->CanPerformActions() && member->GetInventory()->CanAddItem(item->GetID(), itemCount)) {
            eligibleMembers.push_back(member);
        }
    }

    User* winner = nullptr;
    if (!eligibleMembers.empty()) {
        int randomIndex = rand() % eligibleMembers.size();
        winner = eligibleMembers[randomIndex];
    }

    FreeMemory(allMembers.data());
    FreeMemory(eligibleMembers.data());

    return winner;
}
 
Самый обычный рандом. Никаких дополнительных манипуляций с шансом не производится:
C++:
User* CParty::DistributeItemToRandomMember(User* requester, CCreature* item, int itemCount) {
    const float PICKUP_RANGE = 1500.0f;

    std::vector<User*> allMembers;
    GetAllPartyMembers(allMembers, item);

    std::vector<User*> eligibleMembers;
   
    for (User* member : allMembers) {
        if (!member || !member->IsAlive() || !member->IsInRange(requester, PICKUP_RANGE)) {
            continue;
        }

        if (member->IsTrading()) {
            member->CancelTrade();
        }

        if (member->CanPerformActions() && member->GetInventory()->CanAddItem(item->GetID(), itemCount)) {
            eligibleMembers.push_back(member);
        }
    }

    User* winner = nullptr;
    if (!eligibleMembers.empty()) {
        int randomIndex = rand() % eligibleMembers.size();
        winner = eligibleMembers[randomIndex];
    }

    FreeMemory(allMembers.data());
    FreeMemory(eligibleMembers.data());

    return winner;
}
rand() как я понял возвращает число от 0 до 32767. Вумно, вумно.
 
Самый обычный рандом. Никаких дополнительных манипуляций с шансом не производится:
C++:
User* CParty::DistributeItemToRandomMember(User* requester, CCreature* item, int itemCount) {
    const float PICKUP_RANGE = 1500.0f;

    std::vector<User*> allMembers;
    GetAllPartyMembers(allMembers, item);

    std::vector<User*> eligibleMembers;
   
    for (User* member : allMembers) {
        if (!member || !member->IsAlive() || !member->IsInRange(requester, PICKUP_RANGE)) {
            continue;
        }

        if (member->IsTrading()) {
            member->CancelTrade();
        }

        if (member->CanPerformActions() && member->GetInventory()->CanAddItem(item->GetID(), itemCount)) {
            eligibleMembers.push_back(member);
        }
    }

    User* winner = nullptr;
    if (!eligibleMembers.empty()) {
        int randomIndex = rand() % eligibleMembers.size();
        winner = eligibleMembers[randomIndex];
    }

    FreeMemory(allMembers.data());
    FreeMemory(eligibleMembers.data());

    return winner;
}
Спасибо!

Так понимаю по порядку: мембер должен быть живой, находится внутри дистанции 1500, если он торгует, то торговля слетит, и у него не должен быть превышен предел загрузки.

А вот дальше то в чем хочу разобраться. Так понимаю по рандомному числу с каким-то коэффициентом зависящим от размера пати (eligibleMembers.size) определяется победитель.

Т.е. если в пати 3 человека, то eligibleMembers[randomIndex] может выдать только 1, 2, 3.
И тут прямая зависимость в % соотношении? Т.е. первая треть чисел будет для первого, вторая треть для второго, третья треть для третьего?
И первый это тот, кто создал пати? Второй, тот кто первым вступил? И т.д?
 
Спасибо!

Так понимаю по порядку: мембер должен быть живой, находится внутри дистанции 1500, если он торгует, то торговля слетит, и у него не должен быть превышен предел загрузки.

А вот дальше то в чем хочу разобраться. Так понимаю по рандомному числу с каким-то коэффициентом зависящим от размера пати (eligibleMembers.size) определяется победитель.

Т.е. если в пати 3 человека, то eligibleMembers[randomIndex] может выдать только 1, 2, 3.
И тут прямая зависимость в % соотношении? Т.е. первая треть чисел будет для первого, вторая треть для второго, третья треть для третьего?
И первый это тот, кто создал пати? Второй, тот кто первым вступил? И т.д?
С точки зрения рандома без разницы кто каким порядком идет в пати.
В случае если в пати 3 человека, псевдо-рандом (rand() % eligibleMembers.size()) выдаст 0 1 или 2 с "равной" вероятностью каждого из них. Не ищите тут никакой магии, это самый простой рандом.
 
Последнее редактирование:
С точки зрения рандома без разницы кто каким порядком идет в пати.
В случае если в пати 3 человека, псевдо-рандом (rand() % eligibleMembers.size()) выдаст 0 1 или 2 с "равной" вероятностью каждого из них. Не ищите тут никакой магии, это самый простой рандом.
Хочу определить порядок использования случайных чисел.

Вижу Кирилл написал про 32767. Это количество сгенерированных чисел, которые сервер крутит по кругу, или это их вариативность при генерации определенного количества чисел, которые сервер крутит по кругу?

Если это вариативность и в пати три человека, то мой вопрос в следующем:

При выпадении от 1 до 10922 дроп забирает кто создал пати? От 10923 до 21844 дроп забирает кого первым пригласили в пати? От 21845 до 32767 дроп забирает кого вторым пригласили в пати? И т.п.
 
Последнее редактирование:
Хочу определить порядок использования случайных чисел.

Вижу Кирилл написал про 32767. Это количество сгенерированных чисел, которые сервер крутит по кругу, или это их вариативность при генерации определенного количества чисел, которые сервер крутит по кругу?

Если это вариативность и в пати три человека, то мой вопрос в следующем:

При выпадении от 1 до 10922 дроп забирает кто создал пати? От 10923 до 21844 дроп забирает кого первым пригласили в пати? От 21845 до 32767 дроп забирает кого вторым пригласили в пати? И т.п.
Всем же был написан код рандома на C, в чем проблема его посмотреть.
И не искать закономерность в рандоме?
К примеру на оффе, в пати из 5-чел, я лутаю дроп 4 раза - потому что рандом.
А может быть и не 1 лута - рандом.
 
Всем же был написан код рандома на C, в чем проблема его посмотреть.
И не искать закономерность в рандоме?
К примеру на оффе, в пати из 5-чел, я лутаю дроп 4 раза - потому что рандом.
А может быть и не 1 лута - рандом.
Мне помог DeepSeek, в итоге это работает не так, как я думал:
1745572691028.webp
 
При нахождении остатка от деления ты рандом обрезаешь. Не надо искать закономерности, что если выпало 1, то значит 2й член группы, если 2, то 3й итд. В этом нету смысла, т.к. рандом идет равномерно, и зависит от соли
 
При нахождении остатка от деления ты рандом обрезаешь. Не надо искать закономерности, что если выпало 1, то значит 2й член группы, если 2, то 3й итд. В этом нету смысла, т.к. рандом идет равномерно, и зависит от соли
если бы использовался непрерывный диапазон, то был бы смысл)
Теперь знаю, что в данном случае мне это не поможет, ответ получил.

а у игрового кубика тоже rand() % 6? :unsure: Dice.webp
 
Вот тут МастерТома подразумевает, что у кубика и заточки используется непрерывный диапозон (на 10:30):

Он мог просто забыть, что у кубика может использоваться другой метод?
 
Последнее редактирование:
С точки зрения рандома без разницы кто каким порядком идет в пати.
В случае если в пати 3 человека, псевдо-рандом (rand() % eligibleMembers.size()) выдаст 0 1 или 2 с "равной" вероятностью каждого из них. Не ищите тут никакой магии, это самый простой рандом.
Хочу немного уточнить. Вы правы. Но нужно понимать что есть различие в рандомных алгоритмах. Практически, равной вероятности просто не может быть на компьютерных системах. Почему?

Как и Мастер Тома указал в своем видео, у каждого алгоритма будет заточка на определенные значения. То есть если взять все возможные значения на выходе от алгоритма, не будет равного шанса между ними. Будет например больше нулей или же там максимальных значений. Или же наоборот. Генерирование рандомных чисел уж довольно трудоемкая работа, и нужна например при шифровании. Так что просто нужно определить какой алгоритм используем, и ужe после этого можно говорить о равных вероятностяx. Даже на Яве, на Nodejs, и особенно что было выбрано на ПТС. Так как корейцы всетаки использовали не самые лучшие алгоритмы, а то что побыстрее. И то что они использовали не идет в сравнение с современными алгоритмами на той же Яве (ну и других платформах).
 
I'm personally using Rand() for when the outcome can be only 1 or 2, and if there are more than 2 possible outcomes, or in your case party members, I would use weighted probability algorithm since it gives me better and more accurate results, consistent with the assigned chance, even if that chance would be the same for all, and more specifically, 100 divided by party size. Here's an example of the latter in action:
1746109767185.webp
 
I'm personally using Rand() only for when the outcome can be only 1 or 2, and if there are more than 2 possible outcomes, or in your case party members, I would use weighted probability algorithm. Here's an example of the latter in action:
<picture>
The interesting part for me is to see how deep people are willing to go to truly simulate randomness. Does it matter if random value is truly random? Or almost random? And to generate something better there are algorithms, though they may take longer and result in values that you may not like :) I do agree that weighted probability is theoretically better. However, it will still be only marginally better than normal random. All things considered.
 
И то что они использовали не идет в сравнение с современными алгоритмами на той же Яве (ну и других платформах).
Корейцы используют 64 битный ГПСЧ Вихрь Мерсенна. Его реализацию можно посмотреть в функциях
genrand64_real1 и genrand64_real2, но стоит учитывать, что диапазон long в java меньше диапазона беззнакового uint64 в C++, поэтому портировать его в том виде как в PTS - не выйдет(но ничего не мешает юзать 32-битную реализацию). В большинстве ява сборок используется XORShift, который выдает менее качественные последовательности чисел. При этом, в контексте игры эти различия вы не заметите и не сможете измерить никаким образом. Это принципиально невозможно для любой из современных реализация рандома.
 
Последнее редактирование:
Для тех кому интересно, можно почитать о алгоритме Вихрe Мерсенна тут, но на английсом языке (там много добавленно по сравнению с русскоязычной версией, и не так позитивно написанно) :

Отмечу что есть предпочтение числам делящимся на 2 "Contains subsequences with more 0's than 1's. This adds to the poor diffusion property to make recovery from many-zero states difficult."

Еще добавлю что в принципе использование операции modulus, да и умножения как такового, тоже негативно влияет на рандомность произведенного числа. Можно почитать тут :
 
Назад
Сверху