Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Как установить процент выпадения какого-либо числа? (http://www.flasher.ru/forum/showthread.php?t=213767)

ЗУБЯТИНА 06.01.2017 15:34

Как установить процент выпадения какого-либо числа?
 
Как установить процент выпадения какого-либо числа?

Zebestov 07.01.2017 02:24

Код AS3:

Math.random() < myPercent / 100


dark256 07.01.2017 12:02

Цитата:

Сообщение от Zebestov (Сообщение 1198425)
Код AS3:

Math.random() < myPercent / 100


Не ожидал такого от тебя!
А как же фабрика фабрик классов? :)

Zebestov 07.01.2017 14:42

Это вызов!
Хорошо. У меня в играх используется система предсказуемого рандома. На протяжении некоторого периода всегда выпадет XX раз одно число и YY раз другое. Реализация проста: на старте наполняем массив XX количеством первых чисел и следом YY количеством вторых. После этого на протяжении игры делаем все по кругу:

1. Взболтали массив;
2. Установили индекс в ноль;
3. Каждый раз выдаем элемент массива с текущим индексом, после чего индекс++;
2. Как доберемся до конца массива, идем в п.1;

ЗУБЯТИНА 07.01.2017 18:33

Цитата:

Сообщение от Zebestov (Сообщение 1198425)
Код AS3:

Math.random() < myPercent / 100


Я немного не разобрался, куда вписывать этот код? И как указать, для какого числа будет действовать этот процент?

Zebestov 07.01.2017 18:40

Для любого будет действовать.
И это не столько код, сколько запрограммированный ответ на вопрос "ну чо там, сейчас выпадет то самое число, которое я тут держу наготове и которое должно выпадать с вероятностью myPercent, или нет?!". Куда это вставлять — тебе видней.

zackscript 08.01.2017 14:16

ЗУБЯТИНА , Вам сначала вообще надо разобраться где лучше писать сценарии Ваших приложений.

Swer 14.01.2017 14:03

Цитата:

Сообщение от Zebestov (Сообщение 1198439)
Это...
1. Взболтали массив;
2. Установили индекс в ноль;
3. Каждый раз выдаем элемент массива с текущим индексом, после чего индекс++;
2. Как доберемся до конца массива, идем в п.1;

Я делал что-то подобное , но по скорости такой способ проигрывает обычному Math.random()*myNumber

Zebestov 14.01.2017 14:37

Скорость здесь не критична. А если и критична, что нужно помнить, что родной Math.random() довольно тормозная штука и его следует заменять на самодельный.
Ну и главное. Мой подход выдает порции с гарантированным процентом выпадения случая.

undefined 14.01.2017 14:39

Цитата:

А если и критична, что нужно помнить, что родной Math.random() довольно тормозная штука и его следует заменять на самодельный.
А можно пример своего велосипеда, который быстрее нативного будет?

Zebestov 14.01.2017 14:45

Велосипед не мой:
Код AS3:

package {
public class MyRandom {
 
        private static var _seed:int = Math.random() * 123456789;
 
        public function MyRandom() {}
 
        /** Случайное число от 0 до 1 или в заданном диапазоне. */
        public static function random(max:Number = 1.0, min:Number = 0.0):Number {
                _seed = (_seed * 9301 + 49297) % 233280;
                var rnd:Number = _seed / 233280;
                return min + rnd * (max - min);
        }
 
        public static function set seed(value:int):void {
                _seed = value;
        }
}
}


caseyryan 14.01.2017 18:58

В чем прикол?

Zebestov 14.01.2017 19:03

О чем речь?

caseyryan 14.01.2017 19:34

О велосипеде, который ты скинул
в чем суть подобных манипуляций?
Код AS3:

_seed = (MyUtils._seed * 9301 + 49297) % 233280;


Zebestov 14.01.2017 20:00

А чтоб я знал. Написал же, велосипед не мой. Работает отлично, я пользуюсь.
- разброс субъективно лучше, чем в нативном;
- скорость (вроде тесты делали) в разы выше;
- ну и самое главное — у него выдача полностью зависит от посева;

undefined 14.01.2017 20:57

а что за класс MyUtils?

Zebestov 14.01.2017 21:24

А блин )) сейчас исправлю. Нет там ничего такого.

Nooob 15.01.2017 10:51

Вложений: 1
Лучший генератор это http://www.math.utah.edu/~pa/Random/Random.html
Код AS3:

seed = (seed * 16807) % 0x7fffffff

Zebestov твой вариант рандома не лучше нативного:
Код AS3:

[SWF(width="400", height="400")]
        public class TestBitmap extends Sprite
        {
                public function TestBitmap()
                {
                        super();
                        test1();
                        test2();
                        test3();
                }
 
                private function test1():void
                {
                        var seed:int = Math.random() * 123456789;
                        function random(min:Number = 0.0, max:Number = 1.0):Number
                        {
                                seed = (seed * 9301 + 49297) % 233280;
                                var rnd:Number = seed / 233280;
                                return min + rnd * (max - min);
                        }
 
                        var bitmapData:BitmapData = new BitmapData(200, 200, false, 0xffffff);
                        for (var i:int = 0; i < 100000; i++)
                        {
                                bitmapData.setPixel(random(0, 200), random(0, 200), random(0, 0xffffff));
                        }
                        var bitmap:Bitmap = new Bitmap(bitmapData);
                        bitmap.x = 0;
                        bitmap.y = 0;
                        addChild(bitmap);
                }
 
                private function test2():void
                {
                        var seed:int = Math.random() * 123456789;
                        function random(max:int):Number
                        {
                                seed = (seed * 16807) % 0x7fffffff;
                                return seed % max;
                        }
 
                        var bitmapData:BitmapData = new BitmapData(200, 200, false, 0xffffff);
                        for (var i:int = 0; i < 100000; i++)
                        {
                                bitmapData.setPixel(random(200), random(200), random(0xffffff));
                        }
                        var bitmap:Bitmap = new Bitmap(bitmapData);
                        bitmap.x = 200;
                        bitmap.y = 0;
                        addChild(bitmap);
                }
 
                private function test3():void
                {
                        var bitmapData:BitmapData = new BitmapData(200, 200, false, 0xffffff);
                        for (var i:int = 0; i < 100000; i++)
                        {
                                bitmapData.setPixel(Math.random() * 200, Math.random() * 200, Math.random() * 0xffffff);
                        }
                        var bitmap:Bitmap = new Bitmap(bitmapData);
                        bitmap.x = 0;
                        bitmap.y = 200;
                        addChild(bitmap);
                }
        }

Верхний слева твой, снизу слева нативный

undefined 15.01.2017 12:28

замерил время - вышло что самый быстрый таки родной :D
Цитата:

test1 112
test2 64
test3 26

Nooob 15.01.2017 13:28

Цитата:

Сообщение от undefined (Сообщение 1198569)
замерил время - вышло что самый быстрый таки родной :D

Измерять нужно в релизном плеере
Код:

test1 810
test2 793
test3 704

при n 10000000 разница не существенна, поэтому не имеет смысла

undefined 15.01.2017 13:38

а в релизном трейсы не работают

Nooob 15.01.2017 13:41

выводи в TextField

undefined 15.01.2017 13:50

не знаю у кого как, но у меня в релизном кажет:
Цитата:

test1:45
test2:27
test3:19
Добавлено через 32 секунды
Код AS3:

package
{
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.text.TextField;
 
        /**
        * ...
        * @author
        */

        public class Main extends Sprite
        {
                private var tf:TextField;
                public function Main()
                {
                        if (stage) init();
                        else addEventListener(Event.ADDED_TO_STAGE, init);
                }
 
                private function init(e:Event = null):void
                {
                        tf = new TextField();
                        removeEventListener(Event.ADDED_TO_STAGE, init);
                        var test:TestBitmap = new TestBitmap();
                        var res:Object;
                        res = test.test();
                        addChild(test);
                        for (var s:String in res)
                                tf.appendText(s + ":" + res[s] + "\n");
                        addChild(tf);
                }
 
        }       
}

Добавлено через 1 минуту
Код AS3:

package 
{
        /**
        * ...
        * @author
        */

        import flash.display.*;
        public class TestBitmap extends Sprite
        {
                public function TestBitmap()
                {
                        super();
                }
                function test():Object {
                        var res:Object = {};
                        res.test1 = test1();
                        res.test2 = test2();
                        res.test3 = test3();
                        return res;
                }
                private function test1():Number
                {
                        var seed:int = Math.random() * 123456789;
                        function random(min:Number = 0.0, max:Number = 1.0):Number
                        {
                                seed = (seed * 9301 + 49297) % 233280;
                                var rnd:Number = seed / 233280;
                                return min + rnd * (max - min);
                        }
                        var res:Number = (new Date()).getTime();
                        var bitmapData:BitmapData = new BitmapData(200, 200, false, 0xffffff);
                        for (var i:int = 0; i < 100000; i++)
                        {
                                bitmapData.setPixel(random(0, 200), random(0, 200), random(0, 0xffffff));
                        }
                        //trace("test1", (new Date()).getTime() - ts);
                        res = new Date().getTime() - res;
                        var bitmap:Bitmap = new Bitmap(bitmapData);
                        bitmap.x = 0;
                        bitmap.y = 0;
                        addChild(bitmap);
                        return res;
                }
 
                private function test2():Number
                {
                        var seed:int = Math.random() * 123456789;
                        function random(max:int):Number
                        {
                                seed = (seed * 16807) % 0x7fffffff;
                                return seed % max;
                        }
 
                        var bitmapData:BitmapData = new BitmapData(200, 200, false, 0xffffff);
                        var res:Number = (new Date()).getTime();
                        for (var i:int = 0; i < 100000; i++)
                        {
                                bitmapData.setPixel(random(200), random(200), random(0xffffff));
                        }
                        res = new Date().getTime() - res;
                        var bitmap:Bitmap = new Bitmap(bitmapData);
                        bitmap.x = 200;
                        bitmap.y = 0;
                        addChild(bitmap);
                        return res;
                }
 
                private function test3():Number
                {
                        var bitmapData:BitmapData = new BitmapData(200, 200, false, 0xffffff);
                        var res:Number = (new Date()).getTime();
                        for (var i:int = 0; i < 100000; i++)
                        {
                                bitmapData.setPixel(Math.random() * 200, Math.random() * 200, Math.random() * 0xffffff);
                        }
                        res = new Date().getTime() - res;
                        var bitmap:Bitmap = new Bitmap(bitmapData);
                        bitmap.x = 0;
                        bitmap.y = 200;
                        addChild(bitmap);
                        return res;
                }
        }
}

Добавлено через 6 минут
вывод - нефиг изобретать велосипед :D

Nooob 15.01.2017 14:09

Цитата:

Сообщение от undefined (Сообщение 1198573)
вывод - нефиг изобретать велосипед :D

есть такие задачи, где должен быть детерминированный рандом, которые нельзя решить нативным рандомом. например клиент-серверная симуляция (бой в RTS/TBS), где с идентичными входными данными должен быть одинаковых результат

Nooob 15.01.2017 15:11

Вложений: 1
Нашел еще один вариант:
Код AS3:

private static var seed1:int = getTimer();
public static function random1 ():Number
{
        seed1 = (seed1 * 214013 + 2531011) % 0x7fffffff;
        return seed1 / 0x7fffffff;
}

И еще один из недр tamarin-central перевел на AS3, он должен быть идентичен флешовому, но выглядит страшно:
Код AS3:

private static var seed:uint = getTimer();
public static function random3 ():Number
{
        var aNum:uint = (seed = ((seed & 1) ? ((seed >> 1) ^ 0x48000000) : (seed >> 1))) * 71;
        aNum = ((aNum << 13) ^ aNum) - (aNum >> 21);
        var iResult:uint = (aNum * int(aNum * aNum * 15731 + 789221) + 1376312589) & 0x7fffffff;
        iResult += aNum;
        iResult = ((iResult << 13) ^ iResult) - (iResult >> 21);
        return (iResult & 0x7fffffff) / (0x7fffffff + 1.0);
}

Test:
Код AS3:

        [SWF(width = "400", height = "500")]
        public class Test2 extends Sprite
        {
                private var text:TextField;
 
                public function Test2 ()
                {
                        super();
 
                        text = new TextField();
                        text.y = 400;
                        text.height = 100;
                        addChild(text);
 
                        test1();
                        test2();
                        test3();
                        test4();
                }
 
                private static var seed1:int  = getTimer();
                public static function random1 ():Number
                {
                        seed1 = (seed1 * 214013 + 2531011) % 0x7fffffff;
                        return seed1 / 0x7fffffff;
                }
 
                private function test1 ():void
                {
                        var bitmapData:BitmapData = new BitmapData(200, 200, false, 0xffffff);
                        var time:int              = getTimer();
                        for (var i:int = 0; i < 100000; i++)
                        {
                                bitmapData.setPixel(random1() * 200, random1() * 200, random1() * 0xffffff);
                        }
                        text.appendText("test1 " + (getTimer() - time) + "\n");
                        var bitmap:Bitmap = new Bitmap(bitmapData);
                        bitmap.x = 0;
                        bitmap.y = 0;
                        addChild(bitmap);
                }
 
                private static var seed2:int  = getTimer();
                public static function random2 ():Number
                {
                        seed2 = (seed2 * 16807) % 0x7fffffff;
                        return seed2 / 0x7fffffff;
                }
 
                private function test2 ():void
                {
                        var bitmapData:BitmapData = new BitmapData(200, 200, false, 0xffffff);
                        var time:int              = getTimer();
                        for (var i:int = 0; i < 100000; i++)
                        {
                                bitmapData.setPixel(random2() * 200, random2() * 200, random2() * 0xffffff);
                        }
                        text.appendText("test2 " + (getTimer() - time) + "\n");
                        var bitmap:Bitmap = new Bitmap(bitmapData);
                        bitmap.x = 200;
                        bitmap.y = 0;
                        addChild(bitmap);
                }
 
                private static var seed3:uint = getTimer();
                public static function random3 ():Number
                {
                        var aNum:uint = (seed3 = ((seed3 & 1) ? ((seed3 >> 1) ^ 0x48000000) : (seed3 >> 1))) * 71;
                        aNum = ((aNum << 13) ^ aNum) - (aNum >> 21);
                        var iResult:uint = (aNum * int(aNum * aNum * 15731 + 789221) + 1376312589) & 0x7fffffff;
                        iResult += aNum;
                        iResult = ((iResult << 13) ^ iResult) - (iResult >> 21);
                        return (iResult & 0x7fffffff) / (0x7fffffff + 1.0);
                }
 
                private function test3 ():void
                {
                        var bitmapData:BitmapData = new BitmapData(200, 200, false, 0xffffff);
                        var time:int              = getTimer();
                        for (var i:int = 0; i < 100000; i++)
                        {
                                bitmapData.setPixel(random3() * 200, random3() * 200, random3() * 0xffffff);
                        }
                        text.appendText("test3 " + (getTimer() - time) + "\n");
                        var bitmap:Bitmap = new Bitmap(bitmapData);
                        bitmap.x = 0;
                        bitmap.y = 200;
                        addChild(bitmap);
                }
 
                private function test4 ():void
                {
                        var bitmapData:BitmapData = new BitmapData(200, 200, false, 0xffffff);
                        var time:int              = getTimer();
                        for (var i:int = 0; i < 100000; i++)
                        {
                                bitmapData.setPixel(Math.random() * 200, Math.random() * 200, Math.random() * 0xffffff);
                        }
                        text.appendText("test4 " + (getTimer() - time) + "\n");
                        var bitmap:Bitmap = new Bitmap(bitmapData);
                        bitmap.x = 200;
                        bitmap.y = 200;
                        addChild(bitmap);
                }
        }


Zebestov 15.01.2017 17:04

Цитата:

Сообщение от Nooob (Сообщение 1198568)
Zebestov твой вариант рандома не лучше нативного

Во-первых, не мой, а используемый мною в моих проектах.
Во-вторых, лучше, например, в деле перемешивания небольших массивов. Натив мешает отвратительно.
В-третьих, лучше уже хотя бы потому, что имеет повторяемость при одном и том же seed (это ты и сам указал чуть позже, да)
Такова практика.
Алгоритмы "идентичные нативному" беру на карандаш. Но опять же, как раз во втором пункте они работают хуже, так что я даже рад тому, как мешает выбранный мной когда-то первый вариант.
Годная тема поднялась! Много полезного ) топикстартер, поди, в шоке!

undefined 15.01.2017 17:41

Цитата:

Натив мешает отвратительно.
Какие могут быть требования к белому шуму?Кстати,неплохо было бы построить спектр приведенных тут методов.

Zebestov 15.01.2017 17:47

Требование: "максимально рассыпчато" перемешать массив из N нулей и M единиц.
– Вариант, который выбрал я и который кочует у меня из AS в JS — отлично!
– Нативный рандом — кол!

undefined 15.01.2017 17:53

а ну это критерий нравится/не нравится, его не проверишь

Zebestov 15.01.2017 17:56

Нет. Это критерий минимальной длины неперемешанных рядов единиц и нулей.

undefined 15.01.2017 17:59

видимо тут как раз и играет свою роль "неслучайность" твоего метода.Для 0 и 1 оно может и работает, но в какой-нибудь рулетке или покере его лучше не использовать.

Nooob 15.01.2017 18:21

Zebestov Ты по шуму посмотри, выбранный тобой метод дает картинку из линий.
Как минимум варианты
Код AS3:

seed = (seed * 16807) % 0x7fffffff;

Код AS3:

seed = (seed * 214013 + 2531011) % 0x7fffffff;

дают лучший результат

чисел 9301, 49297, 233280 даже в таблице часто используемых параметров для Линейного конгруэнтного метода нету, стоило бы задуматься

Zebestov 15.01.2017 18:26

Nooob, зачем мне смотреть на шум, если в моем случае он ничего не решает?

Nooob 15.01.2017 18:40

Zebestov, Есть стандартные способы определения "качества" псевдо-рандома, один из них по шуму, шум не должен содержать явных паттернов и иметь достаточную плотность, только в этом случае вероятность будет вероятнее. Если что то советуешь то советуй правильно, с указанием первоисточников и как и зачем оно работает. а не белеберду описанную кем-то где-то.

Zebestov 15.01.2017 18:49

Nooob, ну не навязывай мне плохой вариант только потому, что какие-то там "стандартные способы определения" и "шумы" говорят в его пользу где-то за пределами моей задачи. Ведь я не математик-теоретик. Мне нужен подходящий инструмент для лучшего решения конкретного спектра задач, и я его нашел.

Nooob 15.01.2017 18:57

Как ты определяешь плохой вариант от хорошего?
чем используемый тобой вариант из The Central Randomizer:
Код AS3:

seed = (seed * 9301 + 49297) % 233280;

отличается от варианта который используется в Apple CarbonLib и C++11:
Код AS3:

seed = (seed * 16807) % 0x7fffffff;

в Microsoft Visual C/C++:
Код AS3:

seed = (seed * 214013 + 2531011) % 0x7fffffff;

я не понимаю критерий твоей оценки

Zebestov 15.01.2017 19:04

Цитата:

Сообщение от Nooob (Сообщение 1198595)
Как ты определяешь плохой вариант от хорошего … я не понимаю критерий твоей оценки

Выше доступно изложил.

undefined 15.01.2017 19:15

Zebestov, Nooob говорит что твой вариант неуниверсален.Он работает только в твоем(весьма специфичном) случае.Кто-нибудь прочтет, что он якобы быстрее штатного,вставит в свой покер и вылетит в трубу)

Zebestov 15.01.2017 19:17

undefined, Nooob не слышит собеседника — с ним же никто не спорит! И даже более того )

Nooob 15.01.2017 19:31

Zebestov Я тебя слышу и понимаю, но возможно ты меня не понял что я попросил код или вариант для выявления "максимальной рассыпчатости при минимальной длине неперемешанных рядов единиц и нулей", так как мне кажется что любой верный псевдо-рандом должен так же верно справляться с этой задачей


Часовой пояс GMT +4, время: 16:18.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.