Помощь · Поиск · Пользователи · Календарь
Полная версия этой страницы: random
Flash Zone Forum > Macromedia Flash > Общие вопросы
Rohan
Сегодня сделал великое открытие на ровном месте: я тупил в течении долгих лет )) Вообщем, смысл в следующем. Допустим, вам нужно получить какое-то число в диапазоне от 0 до 9. Многие используют для этого random(), но, как по мне, эту ерунду вообще нужно выкинуть из AS, ведь есть намного более гибкий Math.random(). Итак, Math.random... Для получения числа в диапазоне от 0 до 9 я всегда пользовался выражением типа
Код
Math.round(Math.random()*9)

и все вроде ОК... Прежде чем продолжу - хотелось бы получить некоторую статистику: пользовались ли вы когда либо таким способом получения случайного числа? (вопрос _без_ подвоха smile.gif )
MustLive
Цитата(Rohan @ 16.06.2006 - 22:25) *
(вопрос _без_ подвоха smile.gif )

Ты наверное как-то пропустил этот момент.

random() является устаревшим (деприкейтид) с флеша 5. Начиная с которого Макромедия рекомендовала юзать Math.random().

Причём здесь упор не сколько на гибкость (для большинства случаев обычного рандома хватает, плюс синтаксис длиннее у маз.рандома, и нужно обрезать результат (для получение целого числа), да и кто знает, может обычный рандом через маз сейчас и выполняется), а на скорость выполнения. Мол Math-ы все более быстрее выполняются (начиная с 5го флеша), чем "стандартные".

Плюс здесь идёт упор на стандартизацию (в канонах екма скрипт), мол в ява-скрипте используется Math.random(), вот и во флеше используйте. Так что random() - это эпоха 4го флеша.

Цитата
Math.round(Math.random()*9)

Я чаще (в основном) флор использую:
Код
Math.floor(Math.random()*9)

P.S.

Rohan, давно пора уже было начинать юзать Math.random() wink.gif

В флеш 4 я юзал обычный random(). В флеш 5, продолжил его юзать, не было особой нужды в Math.random(). А вот во флеш 6 уже начал переходить на Math.random() - с каждым новый проектом про старый рандом всё меньше вспоминаешь. А как в январе 2006 установил флеш 8 - то ни о каких рандомах (обычных) уже и речи быть не может smile.gif.

Здесь также стоит обратить внимание, кроме стиля, что раз метод устаревший (деприкейтид), то в любой момент Макромедия/Адоб может прекратить его поддержку в плеере (сколько можно совместимость поддерживать, со всем устаревшим, тоже ведь лишний код в плеере и редакторе) - так что всем давно пора использовать новые методы и подходы.
Rohan
Блин, я не об этом! Я сам никогда не пользовался обычным random-ом, всю жизнь _только_ Math.random.
Суть вопроса в другом... У рандома, как оказалось, куча ньюансов )) Вообщем, смысл в том, что
Код
Math.round(Math.random()*9)
использовать вообще нельзя! Это - не корректно ))
Но это мелочи... Вопрос на засыпку: является ли случайным число
Код
Math.random()+Math.random()
? smile.gif Опять же: никогда не обращал на это внимание, и считал что ДА. А оказалось... Провел статистику, офигел от результатов =) Хотя, если разобраться, все так и должно быть...

Цитата(MustLive @ 17.06.2006 - 03:38) *
Rohan, давно пора уже было начинать юзать Math.random() wink.gif

Просто интересно: __в каком месте__ я написал что использую обычный random()??? dry.gif
MustLive
Цитата(Rohan @ 17.06.2006 - 10:27) *
Просто интересно: __в каком месте__ я написал что использую обычный random()??? dry.gif

Цитата
Сегодня сделал великое открытие на ровном месте: я тупил в течении долгих лет ))

smile.gif

Цитата
Блин, я не об этом! Я сам никогда не пользовался обычным random-ом, всю жизнь _только_ Math.random.

Это хорошо, так и нужно.

Цитата
Суть вопроса в другом... У рандома, как оказалось, куча ньюансов ))

Например? Расскажи поподробней о своих наблюдениях.

Цитата
Вообщем, смысл в том, что
Код
Math.round(Math.random()*9)
использовать вообще нельзя! Это - не корректно ))

1) Math.round некорректен здесь, как я писал, я юзаю флор - и это более корректно, это позволит избежать возможных ошибок, которые могут возникнуть при округлении (Math.round). Т.е. Math.round(Math.random()*9) не является 100% эквивалентом random(9). Коим является Math.floor(Math.random()*9).

2) В чём по твоему некорректность Math.random()*9 (с раундом, флором, без разницы, сам Math.random()*9 в чём некорректен)?

Цитата
Вопрос на засыпку: является ли случайным число
Код
Math.random()+Math.random()
? smile.gif Опять же: никогда не обращал на это внимание, и считал что ДА. А оказалось... Провел статистику, офигел от результатов =) Хотя, если разобраться, все так и должно быть...

По идее число должно быть (псевдо) случайным. Т.е. если взять что первый Math.random() случайное число и второй Math.random() тоже, то мы приходим к вопросу, является ли случайным числом сумма двух случайных чисел. Ну и вопрос о полной случайности Math.random() тоже имеет место. smile.gif

А вот статистика (а она должна быть достаточно объёмной для получения выводов) - это уже интересно. Что за статистика, какова методика, какие результаты (что так взбудоражили) и какие выводы.
Rohan
Цитата(MustLive @ 17.06.2006 - 16:12) *
smile.gif
2) В чём по твоему некорректность Math.random()*9 (с раундом, флором, без разницы, сам Math.random()*9 в чём некорректен)?

некорректность Math.floor(Math.random()*9) в том, что ты получишь значения в диапазоне от НУЛЯ и до ВОСЬМИ, и все, казалось бы, круто - написать Math.floor(Math.random()*10) - и нет проблем... НО! Ведь существует в таком случае вероятность того что выпадет 10 =)) Одна на миллиард, но она есть (в случае, когда Math.random() возвратит ровно единицу)!
С Math.round() вообще весело - если написать Math.round(Math.random()*9) - все будет ОК с диапазоном - значения будут лежать в диапазоне от 0 до 9 ВСЕГДА, НО!!! НУЛЕЙ и ДЕВЯТОК будет в два раза меньше чем единиц, двоек, и т.д. Угадайте, почему? wink.gif
Цитата(MustLive @ 17.06.2006 - 16:12) *
По идее число должно быть (псевдо) случайным. Т.е. если взять что первый Math.random() случайное число и второй Math.random() тоже, то мы приходим к вопросу, является ли случайным числом сумма двух случайных чисел. Ну и вопрос о полной случайности Math.random() тоже имеет место. smile.gif

Случайность самого рандома во флеше вне сомнений - подтверждено все той же статистикой wink.gif А ВОТ СУММА ДВУХ РАНДОМНЫХ ЧИСЕЛ случайной НЕ является!!! Она подчиняется некоторому (похожему на нормальное) распределению, т.е. Значение 0 и значение 2 выпадет крайне редко, чаще всего будет выпадать единица )) Сейчас продемонстрирую наглядно...
Rohan
Вообщем, о статистике =)) Возьмем следующий код:
Код
var DATA:Array = [];
for(var i:Number=0; i<2000; i++){
    var num1:Number = Math.floor(Math.random()*15);
    var num2:Number = Math.floor(Math.random()*15);
    var index:Number = num1;
    if(DATA[index]==undefined) DATA[index]=0;
    DATA[index]++;
}
trace(DATA);

Очевидно, что эта конструкция много раз вычисляет некоторое целое число, затем считает, сколько раз это число выпало (DATA[0] - количество выпадений нуля, DATA[1]-единицы и т.д.) З.Ы. Не обращайте внимание на неиспользуемый num2 - он понадобится дальше wink.gif
Вот пример результата:
Код
128,118,130,133,134,134,136,128,137,118,134,143,152,141,134

как видно, все нормально: вероятность выпадения каждого числа одинакова. А теперь проделаем эксперимент номер два )
Код
var DATA:Array = [];
for(var i:Number=0; i<2000; i++){
    var num1:Number = Math.floor(Math.random()*15);
    var num2:Number = Math.floor(Math.random()*15);
    var index:Number = (num1 + num2)/2; //разделим на два, чтобы получить значения в том же диапазоне - это не принципиально
    if(DATA[index]==undefined) DATA[index]=0;
    DATA[index]++;
}
trace(DATA);

результат следующий:
Код
8,41,47,55,78,111,126,142,128,97,73,59,52,22,8

ну как? wink.gif Желающие могут построить график зависимости количества выпадений числа от самого значения этого числа. Получится очень даже нехилое распределение smile.gif
MustLive
Rohan, интересное исследование.
Код
var DATA1 = [];
var DATA2 = [];
var DATA3 = [];
var DATA4 = [];
for (var i=0; i<2000; i++){
    var num1 = Math.floor(Math.random()*15);
    var num2 = Math.floor(Math.random()*15);
    var num3 = Math.floor(Math.random()*15);
    var index1 = num1;
    var index2 = (num1 + num2)/2; //разделим на два, чтобы получить значения в том же диапазоне - это не принципиально
    var index3 = (num1 + num3)/2;
    var index4 = (num2 + num3)/2;
    if (DATA1[index1]==undefined) DATA1[index1]=0;
    if (DATA2[index2]==undefined) DATA2[index2]=0;
    if (DATA3[index3]==undefined) DATA3[index3]=0;
    if (DATA4[index3]==undefined) DATA4[index4]=0;
    DATA1[index1]++;
    DATA2[index2]++;
    DATA3[index3]++;
    DATA4[index4]++;
}
trace(DATA1);
trace(DATA2);
trace(DATA3);
trace(DATA4);

Причём если взять ещё добавить 3 случайное число, и сложить помимо 1 и 2, 1 и 3, 2 и 3, то распределения получится такими же. Ввиде параболы (гаусовское распределение).
Код
143,121,159,123,129,123,130,162,134,134,143,125,136,123,115
14,37,51,62,83,100,110,122,113,100,79,67,54,23,12
12,30,52,68,69,88,121,145,113,96,77,56,48,21,5
10,35,51,63,87,110,118,126,99,80,76,52,42,25,10

Как я уже упоминал некоторым товарищам, сейчас я без своего компа (который 26.05.2006 умер, и до сих пор не удалось его вернуть к жизни, ожидается что окончательная замена неработающего хардвара произойдёт уже на следующей неделе), и флеша 8 не имею - для работы на другой ПК я себе поставил флеш 6/мх. Поэтому код привожу в 6/мх формате.

Так вот, интересное распределение. По началу я подумал, что может есть связь в генераторе случайных чисел, что мол каждое следующее не полностью случайно, а зависит от предыдущего (в любом случае всегда можно придраться к качеству генератора случайных чисел). Мол первое число выходит небольшое (в основном), второе уже большое (в основном), сумма их поделённая на 2 является "серединой" - что и показывает данное распределение - что больше средних значений (наша парабола). Но вот если сделать 3 рандома и взять три разные суммы, то распределение одинаковые. Т.е. мы имеем то что имеем smile.gif - что сумма двух случайных чисел число далеко не случайное.

Из мат.статистики и теории вероятности (из универа) я о данной сумме ничего не припоминаю - таких вопросов мы вроде не проходили. Так что глянем инфу в инете. И как можно прочитать (в одном высказывании), что "именно суммированием случайных величин рекомендуется воспользоваться для генерирования нормального распределения".

Так что в данном исследовании мы получили то, что и д.б. получить - нормальное распределение (гаусовское). Т.е. вполне рандомайзер во флеше работает wink.gif. Какие ещё притензии у Рохана к Math.random() а? Что тебя вообще смутило (само нормальное распределение) и что потянуло к созданию темы? smile.gif
Rohan
Цитата(MustLive @ 18.06.2006 - 03:09) *
Что тебя вообще смутило (само нормальное распределение) и что потянуло к созданию темы? smile.gif

То что мы всеми этими приколами пользуемся и не догадуемся об этом. Я не исключаю то что во многих играх с рандомом создатели не следят за такими ньюансами и в результате...
То что распределение логичное - Я НАПИСАЛ СРАЗУ! Это вполне нормально, но заметь: ты ответил что сумма двух случайных чисел есть также число случайное, и каждый бы так ответил - но, как видно, не все так просто.
ВОПРОС С Math.floor и Math.round ТАК И НЕ СНЯЛИ!!!, а тема изначально создавалась именно об этом. Объясню еще раз: Math.floor(Math.random()*10) обязан как бы возвращать значения от 0 до 9, НО! В одном случае на миллиард он возвратит значение 10!!! И ВЫ УВЕРЕНЫ что ваш проект не слет из-за этого??? Если вдруг он где-нить попытается обратится к десятому элементу массива и построить на его значении все дальнейшие вычисления, а его ТУПО НЕТУ?..
С Math.round(Math.random()) такого НЕ БУДЕТ, НО! Такой способ ВООБЩЕ НЕЛЬЗЯ использовать, хоть никто из вас так и не догадался почему wink.gif
А ты спрашиваешь что меня смутило... Да ничего в самом методе Math.random() меня НЕ смутило, меня смущает то, как все флешеры (в т.ч. и я) эти методом пользуются...
MustLive
Rohan
Цитата
То что распределение логичное - Я НАПИСАЛ СРАЗУ! Это вполне нормально, но заметь: ты ответил что сумма двух случайных чисел есть также число случайное, и каждый бы так ответил - но, как видно, не все так просто.

Я ответил что по идее.
Цитата
По идее число должно быть (псевдо) случайным. Т.е. если взять что первый Math.random() случайное число и второй Math.random() тоже, то мы приходим к вопросу, является ли случайным числом сумма двух случайных чисел.

А также:
Цитата
Из мат.статистики и теории вероятности (из универа) я о данной сумме ничего не припоминаю - таких вопросов мы вроде не проходили. Так что глянем инфу в инете. И как можно прочитать (в одном высказывании), что "именно суммированием случайных величин рекомендуется воспользоваться для генерирования нормального распределения".

Т.е. всё сводится к наличию (или отсутствию) конкретных знаний.

Цитата
ВОПРОС С Math.floor и Math.round ТАК И НЕ СНЯЛИ!!!

На самом деле я его снял ещё в первом своём месадже, когда упомянул про флор, просто ты так и не заметил этого.

Цитата
а тема изначально создавалась именно об этом. Объясню еще раз: Math.floor(Math.random()*10) обязан как бы возвращать значения от 0 до 9, НО! В одном случае на миллиард он возвратит значение 10!!! И ВЫ УВЕРЕНЫ что ваш проект не слет из-за этого??? Если вдруг он где-нить попытается обратится к десятому элементу массива и построить на его значении все дальнейшие вычисления, а его ТУПО НЕТУ?..

Я так и понял, что в этом тема. И потому написал тебе про маз.флор. Что я его использую и всем рекомендую. Я не расписывал детали работы маз.флора, а ты по незнаюнию уже второе сообщение подряд пишет некорректные вещи и на этом строишь своё убеждение в том, что есть проблемы в мазах.

Я как я планировал ответить на твоё предыдущее, и на твоё последнее сообщение, где ты приводил доводы про флор и раунд, то сейчас я тебе поясню в чём ты не прав.

Начнём с того, что как я сказал в первом посте "Ты наверное как-то пропустил этот момент." Т.е. возвращаемся к "я тупил в течении долгих лет". И сейчас сделаем для тебя, и скорее всего для многих других флешеров, открытие.

Math.random() не возвращет единицу. Если бы кто-нибудь удосужился, ещё в 5 флеше, внимателньо прочитать хелп то ни подобных разговоров, ни этой темы, ни вообще подобных проблем бы не было.

Цитирую хелп:
Код
Usage

Math.random()

Description

Method; returns n, where 0 <= n < 1.

Т.е. никогда не возвращает единицу.

И по этому если юзать маз.флор вместе с маз. рандомом - то всё работает как надо! Всегда!


Вот почему я юзаю Math.floor(Math.random()*x) и вот почему это выбор профессионалов. И даже люди которые неверно думали на данную комбинацию (как ты), всё равно её юзают - так как это верное решение.

Math.floor(Math.random()*9) возвращает от 0 до 8, как и random(9) - т.е. это полные эквиваленты, как я и говорил. И никаких Math.round(Math.random()*9) - который округляет, имеет неравномерное распределение и возвращает от 0 до 9.
Цитата
С Math.round(Math.random()) такого НЕ БУДЕТ, НО! Такой способ ВООБЩЕ НЕЛЬЗЯ использовать, хоть никто из вас так и не догадался почему

Знающим людям и догадываться ненужно wink.gif А кто не знал, но кому надо - тот догадается. Math.round с Math.random нельзя использоваться - как и ты, я об этом тоже говоирил многократно.

И неравномерное распределение Math.round(Math.random()) исходит из природы округления. А Math.floor(Math.random()) - имеет самое добротное распределение, тут можно не переживать, это не Math.round. С Math.floor(Math.random()) никаких проблем не будет, и проект будет работать как надо.

Користувачів Math.round(Math.random()) до раю не пускають... wink.gif

Цитата
А ты спрашиваешь что меня смутило... Да ничего в самом методе Math.random() меня НЕ смутило, меня смущает то, как все флешеры (в т.ч. и я) эти методом пользуются...

Я по тому и спрашивал - ведь с самим Math.random() всё хорошо. Потому непонятна была из первых постов суть твоих замечаний. Всё дело было уже в округлениях-отсечениях (раунд-флор). Проблема была в не корректных знаниях о работе флора, потому и акценты были неверно раставлены (что и флор и раунд - оба плохие). Юзай флор и всё будет хорошо smile.gif.
Jox
Я смотрю вы круто в этом шарите, сам я пользуюсь:
Код
Math.round(Math.random()*9)

У меня вопрос: допустим у меня 2 мувика круг (kr) и квадрат (kv) в шутере. И я хочу чтобы они выбегали не последовательно. Допустим я стреляю в круг (убиваю), он ещё раз появляется, затем квадрат.
Я думаю, что это можно осуществить, через Math.random(). Надо ли мувики обозначать цифрами, и вообще как можно это осуществить?
Eyronz
Если тебя я правильно понял нужно чтобы при каком-то событии вылетал или круг или квадрат, что определяется случайно. Вот глянь код, тут при запуске клипа будет вылетает какой нибудь обьект.
Код
z=Math.floor(Math.random()*2);
if(z==1){
attachMovie("kv","kv1",1);
    _root.kv1._x=600;
    _root.kv1._y=200;
    onEnterFrame = function (){
    _root.kv1._x-=25;
}
}
if(z==0){
attachMovie("kr","kr1",1);
    _root.kr1._x=600;
    _root.kr1._y=200;
    onEnterFrame = function (){
    _root.kr1._x-=25;
}
}


Переменная z может быть или 0 или 1, случайным образом. Если ноль, то вылетает круг, если же 1, то соответственно квадрат.
Код писать в кадр. Создать два символа - мувика: круг и квадрат. Дать символам ( не экземплярам, т.к. на поле не должно ничего быть) соответственно коду имена. Поставить в свойствах Linkage символов галочки на Export for AS. Думаю ты знаешь как это делать.
Понятно?

Только за правильность написания сильно не бейте по рукам. Главное РАБОТАЕТ.
MustLive
Цитата(Jox @ 9.07.2006 - 12:11) *
Я смотрю вы круто в этом шарите, сам я пользуюсь:
Код
Math.round(Math.random()*9)

Jox

Никаких Math.round(Math.random())!

Используй исключительно Math.floor(Math.random()). Т.к. с Math.round баги обеспечены. О чём уже много писалось выше.

Как я писал:
Цитата
Користувачів Math.round(Math.random()) до раю не пускають... wink.gif

Так что используй Math.floor.

Цитата
Я думаю, что это можно осуществить, через Math.random(). Надо ли мувики обозначать цифрами, и вообще как можно это осуществить?

Eyronz уже привел пример, из которого ты можешь понять суть алгоритма работы с Math.random().
Jox
Всё круто, спасибо за подсказу, мы с программистом так всё и сделали (не заходя ещё сюда),
но у нас не много проблема в другом, флешка состоит из множество файлов, поэтому с путями загрузки проблемы.
P.S. Отвечать не обязательно.

В главном swf файле Port в кадре написали
Код
_root.Port.loadMovie("em"+Math.floor(Math.random()*2+1)+".swf");

, где ещё 3 swf файлы (em1, em2, em3) являются врагами.
chingachgoog
Цитата(MustLive @ 17.06.2006 - 03:38) *
random() является устаревшим (деприкейтид) с флеша 5. Начиная с которого Макромедия рекомендовала юзать Math.random().

Причём здесь упор не сколько на гибкость (для большинства случаев обычного рандома хватает, плюс синтаксис длиннее у маз.рандома, и нужно обрезать результат (для получение целого числа), да и кто знает, может обычный рандом через маз сейчас и выполняется), а на скорость выполнения. Мол Math-ы все более быстрее выполняются (начиная с 5го флеша), чем "стандартные".


Самый прикол в том, что якобы "устаревший" random() выполняется БЫСТРЕЕ, чем "новейший" Math. Это при выполнении в голом виде. А если прибавить округление и перемножение для Math, то его отставание еще больше.
(ну и вы сами заметили, что random() синтаксически удобнее).
Поэтому в критичных к скорости блоках кода как раз целесообразнее использовать "старый" random().

PS
Разработчики всегда много недоговаривают или даже врут - их цель: продать новый продукт.
Русская версия IP.Board © 2001-2009 IPS, Inc.