Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 1.0/2.0 (http://www.flasher.ru/forum/forumdisplay.php?f=93)
-   -   Неповторяющийся рандом. (http://www.flasher.ru/forum/showthread.php?t=90259)

poorjorik 06.01.2007 19:35

Неповторяющийся рандом.
 
Друзья, бьюсь уже 3 дня. думал обойтись без помощи форума, да видать по-другому невозможно.
Есть следующая задумка (почти реализованная):
Мувик из N кадров, на каждом кадре стоп, в каждом кадре разные объекты, назовем его БИБЛИОТЕКА.
Мувик в который вставлен БИБЛИОТЕКА (назовем его ВЫБОРКА) и прописано следующее:
--------------------------------------------------------
Код:

onClipEvent (load) {
        var playscene=[1,2,3,4,5,6,7,8,9];
        n=random(playscene.length);
        this.gotoAndStop(n);
        playscene.splice(n,1);
}

--------------------------------------------------------
Идея такая - рандомно выбирается кадр из БИБЛИОТЕКА, и в ВЫБОРКА отображается соответсвенно.
Затем есть еще один мувик, содержащий ВЫБОРКА и код: дубликат симбл.
Итого пытаюсь получить но не получается: чтобы дублированные объекты генерились рандомно, но ни один из них не повторялся. Генерятся рандомно, но иногда бывают повторения.

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

onClipEvent (load) {
        Temp = "";
        i = 1;
while (Number(i)<>11) {
        rnd = random(10);
        x = 1;
        while (Number(x)<>Number((Number(length(Temp))+1))) {
                if ((substring(Temp, x, 1)) eq rnd) {
                        rnd = "";
                }
                x = Number(x)+1;
        }
        if (rnd ne "") {
                Temp = rnd;
                i = Number(i)+1;
        }
}
        this.gotoAndStop(temp);
}

--------------------------------------------------------
Итог тот=же, повторения наблюдаются.

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

iNils 06.01.2007 19:46

1. Для оформления своего кода, надо использовать теги
2. Надо пользоваться поиском
3. В разделе ActionScript, писать вопросы с синтаксисом onClipEvent и подобным, запрещено. Читайте правила подраздела.

poorjorik 06.01.2007 19:51

Прошу прощения, но как я уже сказал, экшн скрипт знаю плохо, а просто могу разобраться что написано, пользуясь книгой. Чем заменить on...() я не знаю. Поиском я пользовался. Ничего подходящего найти не удалось.

iNils 06.01.2007 19:53

Код:

var arrayA:Array = new Array (0, 1, 2, 3, 4, 5, 6);
var arrayB:Array = arrayA.concat()
for (var i:Number = 0; i < arrayA.length; i++) {
        var rnd:Number = Math.floor (Math.random () * arrayB.length);
        var del:Array = arrayB.splice (rnd, 1);
        trace (arrayA[del]);
}


poorjorik 06.01.2007 20:03

trace (arrayA[del]); простите что делает эта строчка, и какую переменную мне собствеено надо брать чтобы перейти на рандомный кадр?

iNils 06.01.2007 20:08

Выдает в трасе-окно случайный результат из массива.

poorjorik 06.01.2007 20:15

Код:

var arrayA:Array = new Array (0, 1, 2, 3, 4, 5, 6);
var arrayB:Array = arrayA.concat()
for (var i:Number = 0; i < arrayA.length; i++) {
        var rnd:Number = Math.floor (Math.random () * arrayB.length);
        var del:Array = arrayB.splice (rnd, 1);
        this.gotoAndStop(arrayA[del]);
}

если сделать так то вообще рандом пропадает. и все одинаковые. Объясните как для чайника пожалуйста

iNils 06.01.2007 20:23

Честно говоря я не понял чего вы хотите и дал вам код которые генерит последовательно случайное и уникальное (в каждом запуске) значение из массива возможных значений.

poorjorik 06.01.2007 20:27

в принципе мне это и надо. теперь осталось тольок выяснить arrayA[del] - это и есть это значение? и второе: "при каждом запуске" это как?

poorjorik 06.01.2007 20:30

Вложений: 1
вот посмотрите пожалуйста что мне нужно (работает некоректно, есть повторения)

iNils 06.01.2007 20:44

Слегка переписал код чтобы было понятнее.
Код:

//// первоначальный массив
var arrayA:Array = new Array (0, 1, 2, 3, 4, 5, 6);
//// это функция которая делает массив случайным, ее не трогаем
function getNewRandom (arrayA:Array):Array {
        var arrayB:Array = arrayA.concat ();
        var arrayC:Array = new Array ();
        for (var i:Number = 0; i < arrayA.length; i++) {
                var rnd:Number = Math.floor (Math.random () * arrayB.length);
                arrayC.push (arrayB.splice (rnd, 1));
        }
        return arrayC;
}
//// создаем случайный массив номер 1
var arrayR1:Array = getNewRandom (arrayA);
//// создаем случайный массив номер 2
var arrayR2:Array = getNewRandom (arrayA);
//// создаем случайный массив номер 3
var arrayR3:Array = getNewRandom (arrayA);
//// это просто в качестве примера выводим содержимое этих массивов
trace (arrayR1);
trace (arrayR2);
trace (arrayR3);

Если вам нужен только один случайный массив, то вы используйте только один getNewRandom. А на выходе получите массив в котором все значение случайно перемешаны в отличии от исходного. Вы проходитесь по всем элементам полученного массива и делаете с их значением что вам там угодно.

wvxvw 06.01.2007 20:56

Я использую другой вариант. Принцип где-то похож, но чуть меньше кода
Код:

var _arr:Array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
function orderRND():Number{
return Math.floor(Math.random()*2-1);
}
_arr.sort(orderRND);

Математику можно немножко более точной сделать, но в принципе и так работает.

iNils 06.01.2007 20:58

Цитата:

Сообщение от wvxvw
Я использую другой вариант. Принцип где-то похож, но чуть меньше кода
Код:

var _arr:Array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
function orderRND():Number{
return Math.floor(Math.random()*2-1);
}
_arr.sort(orderRND);

Математику можно немножко более точной сделать, но в принципе и так работает.

И что это? Какой был массив, таким и остался.

poorjorik 06.01.2007 21:01

Выдает такие ошибки:
Symbol=ðàìêà, Layer=Layer 1, Frame=1: Line 4: '{' expected
function getNewRandom (arrayA:Array):Array {

Symbol=ðàìêà, Layer=Layer 1, Frame=1: Line 12: Unexpected '}' encountered
}

wvxvw 06.01.2007 21:03

Код:

var _arr:Array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
function orderRND():Number{
return Math.floor(Math.random()*2.5-1);
}
_arr.sort(orderRND);

В код вкралась досадная очепятка, не 2. а 2.5 %)

ЗЫ. У этого метода есть определенные недостатки - первый член массива практически всегда остается на первой позиции. Но с другой стороны - операцию нужно делать всего 1 раз, а не каждый раз, когда нужно получить случайный элемент массива.

ЗЫ. 2.9999999 будет еще лучше, чем 2.5

ЗЫЫ. ДА, и еще недостаток... такой рандом получается хуже родного флешевского рандома (даже если операцию повторить несколько раз, то значения распространяются недостаточно равномерно.... но если "качество" не принципиально (просто прокрутить серию клипов, например) то и так сойдет, а если нужно "настоящее" рандомальное число, ну или по крайней мере "более" рандомальное (например имитация подбрасывания костей) то лучше так не делать =)

poorjorik 06.01.2007 21:28

Складывается ощущение неприятное что я остаюсь в стороне от общего разговора.
Посмотрите исходник пожалуйста. рандом генератор случайных уникальных чисел у меня есть, я приводил его код в первом посте. Но он корректно не работет в моем случае. Вообще вопрос не в том как рандом сделать, а как в моем случае заставить корректно его работать.

wvxvw 07.01.2007 00:06

Посмотрел исходник.... А есть какая-то реальная необходимость делать это в АС1? Если честно, просто элементарно не нашел место, где находится этот скрипт, который не работает. Просто дико неудобно.

Вариант iNils'a предлагает функцию, которая будет при каждом запуске выдавать один член массива с произвольным индексом и удалять его, после того, как в массиве не останется ничего функция закончит работу.

В моем варианте функция просто сортирует массив в произвольном порядке. Т.е. запустив ее 1 раз получим из массива 1,2,3,4,5,6,7,8,9,0 например 2,4,1,6,3,7,0,8,9,5.

Ваше дело, как это применять.

Kikasso 09.01.2007 15:38

Цитата:

Сообщение от iNils
Код:

var arrayA:Array = new Array (0, 1, 2, 3, 4, 5, 6);
var arrayB:Array = arrayA.concat()
for (var i:Number = 0; i < arrayA.length; i++) {
        var rnd:Number = Math.floor (Math.random () * arrayB.length);
        var del:Array = arrayB.splice (rnd, 1);
        trace (arrayA[del]);
}


Уважаемый iNils, извините пож. но почему этот код выводит то что хотелось и компилятор не ругается?
Если del это Array, то что такое arrayA[del]?

Я бы так сделал:
Код:

//исходный массив
var myArr:Array = new Array (0, 1, 2, 3, 4, 5, 6);
// копия
var arr:Array = myArr.concat();
//длинна массива, чтобы не искать ее лишний раз
var num:Number = arr.length;
while ( num > 0 ){
        // случайный индекс
        var rnd:Number = Math.floor (Math.random () * num );
        // выдергиваем элемент с этим индексом из массива
        trace (arr.splice( rnd, 1 ) );
        // длинна массива уменьшилась
        num--;
}

PS - только что заметил вторую страницу. Вопрос все равно остался.
Автор, а повторения кстати неизбежны.
Имеем ряд 1,2,3
Первое перемешивание 2,3,1
Второе перемешивание 1,3,2
цифра 1 повторилась - все как в жизни, так бывает.
Если вам нужно избежать такой ситуации, надо исключать последний выпавший номер из нашей "лотереи".

Kikasso 09.01.2007 16:15

Ошибка выделена:
Код:

var playscene=[1,2,3,4,5,6,7,8,9];
n=Math.floor(Math.random()*playscene.length); //или n=random(playscene.length), если очень хочется
this.gotoAndStop(playscene[n]);
playscene.splice(n,1);

Только код надо вынести из того клипа, который вы дублируете, потому что массив у вас создается каждый раз заново.


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

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