"Честный" рандом

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

"Честный" рандом

Сообщение Xytabich 10 июл 2015, 18:34

Всем привет, написал простенький скрипт рандома для справедливого выпадения шанса(надеюсь понятно написал).
Синтаксис:
Используется csharp
using UnityEngine;
public class FRandom
{
        public int[] chances;//массив индексов

        public FRandom(int[] c){chances = c;}

        public int Get()
        {
                int all = 0;//общее число шансов
                foreach(int c in chances)all+=c;
                int lr = 0;//начало отсчета от предыдущего шанса
                int r = Random.Range(0, all);//берется случайное число из общего количества шансов
                for(int i = 0; i < chances.Length; i++)
                {
                        if(chances[i] > 0)//если имеется шанс на выпадение индекса, идем дальше
                        {
                                if(r >= lr && r < lr + chances[i])//если случайное число находится в границах индекса...
                                {
                                        chances[i]--;//убираем один шанс у индекса
                                        return i;//возвращаем индекс
                                }
                                else lr += chances[i];//или прибавляем шансы от индекса к предыдущим шансам
                        }
                }
                return -1;//если массив индексов пуст или исчерпаны все шансы, возвращаем -1
        }
}


Как он работает: В начале имеется массив с шансами на выпадение какого-либо индекса из массива(которые впоследствии используются в скриптах), при вызове функции Get() начинается расчет выпадающего индекса: считается общее количество шансов, затем отсюда берется случайное число, и, если случайное число входит в границы шансов индекса, возвращается выпавший индекс, или, если исчерпаны все возможные варианты или массив пуст, возвращается -1. При исчерпании всех шансов массив индексов обновляется.

Пример работы:
Синтаксис:
Используется csharp
Color red, yellow, green;//Имеется 3 цвета
Color[] mat = new Color[100];//так же имеется массив с цветами, который нужно заполнить тремя цветами в случайном порядке
redChance = 50;//шанс выпадения красного 50 из 100, т.е. 50%
yellowChance = 45;//шанс выпадения желтого 45%
greenChance = 5;//шанс выпадения зеленого 5%
FRandom fr;//инициализируется переменная рандома

void Start()
{
        fr = new FRandom(new int[]{redChance, yellowChance, greenChance});//задаем массив с шансами
        for(int i = 0; i < mat.Lenght; i++)
        {
                int ind = fr.Get();//берем случайный индекс
                if(ind > -1)//если индекс равен -1, значит закончились шансы
                {
                        swith(ind)//заполняем элемент массива цветом
                        {
                        case 0:
                                mat[i] = red;
                                break;
                        case 1:
                                mat[i] = yellow;
                                break;
                        case 2:
                                mat[i] = green;
                                break;
                        }
                }
        }
}

В результате работы этого скрипта выпадет 50 красных, 45 желтых и 5 зеленых цветов в случайном порядке.

Спасибо за внимание :)
Аватара пользователя
Xytabich
UNIт
 
Сообщения: 89
Зарегистрирован: 16 мар 2014, 23:24

Re: "Честный" рандом

Сообщение Woolf 10 июл 2015, 18:51

алгоритм верный, но реализация... Выходить из цикла по ретурну считается дурным стилем. Для таких вещей придумали цикл while
Разработчик theFisherOnline - там, где клюёт
Разработчик Atom Fishing II - Первая 3D MMO про рыбалку
Разработчик Atom Fishing - Рыбалка на поплавок, донку, нахлыст, блесну в постъядерный период.
Аватара пользователя
Woolf
Адепт
 
Сообщения: 7179
Зарегистрирован: 02 мар 2009, 16:59

Re: "Честный" рандом

Сообщение DbIMok 10 июл 2015, 19:14

Xytabich писал(а):В результате работы этого скрипта выпадет 50 красных, 45 желтых и 5 зеленых цветов в случайном порядке.

записать в массив "50 красных, 45 желтых и 5 зеленых", перемешать, брать по порядку. когда закончится, повторить. все понятно, стандартно. взять чей-то велосипед не глядя, чревато ошибками. разбираться в нем, чтобы убедиться, что ошибок нет - лень. проще сделать самому из общеизвестных проверенных блоков.
правильный вопрос - половина ответа. учитесь формулировать вопросы понятно.
Новости > _Telegram чат @unity3d_ru (11.6k/4.8k online) > _Telegram канал @unity_news (4.7k подписчиков) > Телеграм тема > "Спасибо"
Аватара пользователя
DbIMok
Адепт
 
Сообщения: 6372
Зарегистрирован: 31 июл 2009, 14:05

Re: "Честный" рандом

Сообщение Xytabich 10 июл 2015, 20:12

Woolf писал(а):Выходить из цикла по ретурну считается дурным стилем.

У каждого свой стиль, как по мне так проще, не приходится просчитывать лишнюю информацию.
Аватара пользователя
Xytabich
UNIт
 
Сообщения: 89
Зарегистрирован: 16 мар 2014, 23:24

Re: "Честный" рандом

Сообщение Xytabich 10 июл 2015, 20:20

DbIMok писал(а):записать в массив "50 красных, 45 желтых и 5 зеленых", перемешать, брать по порядку. когда закончится, повторить. все понятно, стандартно. взять чей-то велосипед не глядя, чревато ошибками. разбираться в нем, чтобы убедиться, что ошибок нет - лень. проще сделать самому из общеизвестных проверенных блоков.

тут смысл не в перемешивании, а в реализации четкой случайности(как бы странно это не звучало).
Аватара пользователя
Xytabich
UNIт
 
Сообщения: 89
Зарегистрирован: 16 мар 2014, 23:24

Re: "Честный" рандом

Сообщение DbIMok 10 июл 2015, 20:36

в чем "четкость" случайности? "50 красных, 45 желтых и 5 зеленых" будут четко случайно перемешаны. у вас как-то по другому?
правильный вопрос - половина ответа. учитесь формулировать вопросы понятно.
Новости > _Telegram чат @unity3d_ru (11.6k/4.8k online) > _Telegram канал @unity_news (4.7k подписчиков) > Телеграм тема > "Спасибо"
Аватара пользователя
DbIMok
Адепт
 
Сообщения: 6372
Зарегистрирован: 31 июл 2009, 14:05

Re: "Честный" рандом

Сообщение Xytabich 10 июл 2015, 21:47

DbIMok писал(а):в чем "четкость" случайности? "50 красных, 45 желтых и 5 зеленых" будут четко случайно перемешаны. у вас как-то по другому?

так речь вообще не о перемешивании, здесь нет четкого количества выходных параметров, то есть, например, если исходных элементов 100, то может использоваться только 50 из их числа.
Аватара пользователя
Xytabich
UNIт
 
Сообщения: 89
Зарегистрирован: 16 мар 2014, 23:24


Вернуться в Исходники (Копилка)

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2