Форум 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=187878)

PasserBy 25.11.2012 20:12

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

for(var i:int = 0; i < 21; i++){
                                for(var i2:int = 0; i2 < 29; i2++){
                                        var perem:Number = Math.random();
                                        if(perem > 0.7){
                                                var some:Enemy = new Enemy();
                                                trace(i  + " " + i2 + "\n");
                                                mama[i][i2].push(true); //ПОЧЕМУ ТАК НЕ РАБОТАЕТ?
                                                //mama[i2].push(some);//ОДНАКО В УЧЕБНИКАХ СИЕ ИСПОЛЬЗУЕТСЯ!
                                        }
                                }
                        }

Рабочий вариант до которого еле додумался.
Код AS3:

for(var i:int = 0; i < 21; i++){
                                for(var i2:int = 0; i2 < 29; i2++){
                                        var perem:Number = Math.random();
                                        if(perem > 0.7){
                                                var some:Enemy = new Enemy();
                                                trace(i  + " " + i2 + "\n");
                                                mama[i][i2] = true;
                                                //mama[i2].push(some);
                                        }
                                }
                        }

ЗЫ мама - это массив (ну как бы с детками :3)

Wolsh 25.11.2012 20:16

Массив таки ДВУ-мерный или всетаки ТРЕХ-мерный?
push это метод массива. У Вас mama это массив, mama[i] это массив, mama[i][i2] — тоже массив?
Что тогда означает код mama[i][i2] = true; ?

PasserBy 25.11.2012 20:19

Цитата:

Сообщение от Wolsh (Сообщение 1106187)
Массив таки ДВУ-мерный или всетаки ТРЕХ-мерный?
push это метод массива. У Вас mama это массив, mama[i] это массив, mama[i][i2] — тоже массив?
Что тогда означает код mama[i][i2] = true; ?

Двумерный массив, то есть внутри каждого элемента i есть массив.
Код AS3:

//Build Massive
                        var mama:Array = new Array(20);
                        for(var j:int = 0; j < 21; j++){
                                mama[j] = new Array(29);
                        }

Код:

Что тогда означает код mama[i][i2] = true; ?
Я имею ввиду тут, что элементу i2 внутри массива i, присваивается значение true

Krusty 25.11.2012 20:21

Запись
Код AS3:

mama[i][i2].push(true);

означает, что это трехмерный массив. Считайте внимательно
Код AS3:

mama.push(true); #одномерный
mama[i].push(true); #двухмерный
mama[i][i2].push(true);  #трехмерный.

Поэтому и не работает.

Wolsh 25.11.2012 20:25

Соответственно Вы можете вызвать метод push у этих массивов mama[j].
Но если Вы записываете туда Boolean (т.е. true или false), то как Вы собираетесь вызывать у них метод push?
Код AS3:

mama[i][i2] = true;
mama[i][i2].push(someVar); // т.е. " (true).push(someVar); "

mama[i][i2] это уже ячейка вложенного массива. А точнее — ее содержимое (в вашем случае true).

PasserBy 25.11.2012 20:25

Цитата:

Сообщение от Krusty (Сообщение 1106189)
Запись
Код AS3:

mama[i][i2].push(true);

означает, что это трехмерный массив. Считайте внимательно
Код AS3:

mama.push(true); #одномерный
mama[i].push(true); #двухмерный
mama[i][i2].push(true);  #трехмерный.

Поэтому и не работает.

mama[i].push(true); #двухмерный -- Если таким образом заполнить массив, то все элементы i2 примут значение true, как этого избежать?
То есть как реализовать
Код:

mama[i][i2] = true;
использую push(); ?

Krusty 25.11.2012 20:30

push добавляет элемент без использования индекса, он просто добавляет элемент за последним.
Цитата:

Если таким образом заполнить массив, то все элементы i2 примут значение true, как этого избежать?
Вы не понимаете? i2 меняется в цикле. переформулируйте задачу.

Wolsh 25.11.2012 20:34

Цитата:

То есть как реализовать mama[i][i2] = true; использую push(); ?
Код AS3:

mama[i].push(true);


PasserBy 25.11.2012 20:37

Цитата:

Сообщение от Krusty (Сообщение 1106192)
push добавляет элемент без использования индекса, он просто добавляет элемент за последним.

Вы не понимаете? i2 меняется в цикле. переформулируйте задачу.

Вариант 1
Код AS3:

for(var i:int = 0; i < 20; i++){
                                for(var i2:int = 0; i2 < 27; i2++){
                                        var perem:Number = Math.random();
                                        if(perem > 0.7){
                                                mama[i].push(true);
                                                trace(i + "\n");
                                        }
                                }
                        }

трейс
Код:

1 true
1 true
1 true
..
2 ..
2 ..
2 ..
..
3 ..
3 ..
3 ..
..
4 true
4 true
4 true
...

вариант 2
Код AS3:

for(var i:int = 0; i < 20; i++){
                                for(var i2:int = 0; i2 < 27; i2++){
                                        var perem:Number = Math.random();
                                        if(perem > 0.7){
                                                mama[i][i2] = true;
                                                trace(i + "\n");
                                        }
                                }
                        }

трейс
Код:

1 true
1 ..
1 true
..
2 ..
2 true
2 true
..
3 true
3 ..
3 ..
..
4 true
4 ..
4 true
..

Бишь рандом значение ...повторюсь как реализовать последнее используя push(); - чтобы результат был сходным. как при использовании mama[i][i2] = true; (Каждому элементу второго , вложенного массива, было присвоено индивидуальное значение

Wolsh 25.11.2012 20:52

Вы читаете, что Вам пишут? (ладно хелп не читаете, это ваше дело).
push() добавляет элемент в конец массива. Ему нет дела до того, какое сейчас значение у переменной-итератора цикла i2. Если Вы не делаете push() (а Вы не делаете, когда рэндом не больше 0.7), то ничего и не добавляется. Ничего — означает "и ячейки тоже". Сама собой пустая ячейка не возникнет, флэш не умеет читать Ваши желания. Либо полностью комплектуйте массив ячейками и значениями, либо используйте оператор = (не понимаю, чем Вас это не устраивает).
Код AS3:

for(var i:int = 0; i < 20; i++){
        for(var i2:int = 0; i2 < 27; i2++){
                var perem:Number = Math.random();
                if(perem > 0.7){
                        mama[i].push(true);
                }
                else{
                        mama[i].push(false);
                }
                trace(i, i2, mama[i][i2]);
        }
}


PasserBy 25.11.2012 21:05

Цитата:

Сообщение от Wolsh (Сообщение 1106197)
Вы читаете, что Вам пишут? (ладно хелп не читаете, это ваше дело).
push() добавляет элемент в конец массива. Ему нет дела до того, какое сейчас значение у переменной-итератора цикла i2. Если Вы не делаете push() (а Вы не делаете, когда рэндом не больше 0.7), то ничего и не добавляется. Ничего — означает "и ячейки тоже". Сама собой пустая ячейка не возникнет, флэш не умеет читать Ваши желания. Либо полностью комплектуйте массив ячейками и значениями, либо используйте оператор = (не понимаю, чем Вас это не устраивает).
Код AS3:

for(var i:int = 0; i < 20; i++){
        for(var i2:int = 0; i2 < 27; i2++){
                var perem:Number = Math.random();
                if(perem > 0.7){
                        mama[i].push(true);
                }
                else{
                        mama[i].push(false);
                }
                trace(i, i2, mama[i][i2]);
        }
}


Хм, спасибо

Wolsh 25.11.2012 21:11

Если "хм" означает "ничего не понял, но все равно спасибо", то лучше спрашивайте, что осталось непонятным.

PasserBy 25.11.2012 21:20

Цитата:

Сообщение от Wolsh (Сообщение 1106202)
Если "хм" означает "ничего не понял, но все равно спасибо", то лучше спрашивайте, что осталось непонятным.

Упустил момент с "иначе" и механикой метода "push()", было непонятно, почему все элементы одного значения.
Видимо в этом случае лучше использовать "Splice".

Добавлено через 6 минут
Чтобы не создавать новую ветку -
в чем проблема?
Код AS3:

package  {
        import flash.display.*;
        import flash.events.*;
        import flash.utils.*;
 
        public class LiveGame extends MovieClip{
        private var timer:Timer;
 
                public function LiveGame() {
                        //Build Massive
                        var mama:Array = new Array(20);
                        for(var j:int = 0; j < 21; j++){
                                mama[j] = new Array(29);
                        }
 
                        //Generate position
                        for(var i:int = 0; i < 20; i++){
                                for(var i2:int = 0; i2 < 27; i2++){
                                        var perem:Number = Math.random();
                                        if(perem > 0.7){
                                                var some:Enemy = new Enemy(0);
                                                some.alive = true;
                                        } else {
                                                var some:Enemy = new Enemy(1);
                                                some.alive = false;
                                        }
 
                                        some.x = (i2 + 1) * 20 - 10;
                                        some.y = (i + 1) * 20 - 10;
 
                                        mama[i][i2] = some; //!!!!
                                        trace(i  + " " + i2 + " " + mama[i][i2]); //Show me massive
                                        addChild(some);
                                }
                        }
                        //add TIMER
                        timer = new Timer(1000, 0);
                        timer.addEventListener(TimerEvent.TIMER, checker);
                        timer.start();
                }
 
                //Check function url to Timer option time
                private function checker(e:TimerEvent):void{
                        trace("Generation: " + e.target.currentCount);
                        //Check LIve here
                        for(var j:int = 0; j < 20; j++){
                                for(var j2:int = 0; j2 < 27; j2++){
                                        var liver_a:int = 0;
                                        trace(mama[j][j2]);
 
                                }
                        }
 
                }
                //removeListener's
                private function destroy():void{
                        timer.removeEventListener(TimerEvent.TIMER, checker);
                }
 
        }
 
}

код enemy
Код AS3:

package  {
        import flash.display.*;
        import flash.events.*;
        import flash.utils.*;
 
        public class Enemy extends Sprite{
        private var size:Number = 8; //Size of circle
        private var colors:Array = [0x000000, 0xFFFFFF]; //Color of circle;
        private var graph:Shape = new Shape(); //Graph circle class
        public var alive:Boolean = false; //Alive status
 
                public function Enemy(stat:int = 0) {
                        // constructor code
                        graph.graphics.beginFill(colors[stat], 0.9);
                        graph.graphics.drawCircle(0, 0, size);
                        graph.graphics.endFill();
                        addChild(graph);
                }
 
                public function draw(stat:int):void{
                        trace("change color");
                        graph.graphics.beginFill(colors[stat], 0.9);
                        graph.graphics.endFill();
                }
        }
}

Ошибка
Код:

LiveGame.as, строка 51        1120: Обращение несуществующего свойства mama.
ЗЫ строка 51 это - trace(mama[j][j2]);

PasserBy 25.11.2012 21:30

В чем ошибка?
Код AS3:

package  {
        import flash.display.*;
        import flash.events.*;
        import flash.utils.*;
 
        public class LiveGame extends MovieClip{
        private var timer:Timer;
 
                public function LiveGame() {
                        //Build Massive
                        var mama:Array = new Array(20);
                        for(var j:int = 0; j < 21; j++){
                                mama[j] = new Array(29);
                        }
                        // constructor code
                        var setk:Setka = new Setka();
                        addChild(setk);
                        //Generate enemy position
                        for(var i:int = 0; i < 20; i++){
                                for(var i2:int = 0; i2 < 27; i2++){
                                        var perem:Number = Math.random();
                                        if(perem > 0.7){
                                                var some:Enemy = new Enemy(0);
                                                some.alive = true;
                                        } else {
                                                var some:Enemy = new Enemy(1);
                                                some.alive = false;
                                        }
 
                                        some.x = (i2 + 1) * 20 - 10;
                                        some.y = (i + 1) * 20 - 10;
 
                                        mama[i][i2] = some; //!!!!
                                        trace(i  + " " + i2 + " " + mama[i][i2]); //Show me massive
                                        addChild(some);
                                }
                        }
                        //add TIMER
                        timer = new Timer(1000, 0);
                        timer.addEventListener(TimerEvent.TIMER, checker);
                        timer.start();
                }
 
                //Check function url to Timer option time
                private function checker(e:TimerEvent):void{
                        trace("Generation: " + e.target.currentCount);
                        //Check LIve here
                        for(var j:int = 0; j < 20; j++){
                                for(var j2:int = 0; j2 < 27; j2++){
                                        var liver_a:int = 0;
                                        trace(mama[j][j2]); //РУГАЕТСЯ НА ЭТУ СТРОЧКУ!!!!
 
                                }
                        }
 
                }
        }
 
}

Код enemy
Код AS3:

package  {
        import flash.display.*;
        import flash.events.*;
        import flash.utils.*;
 
        public class Enemy extends Sprite{
        private var size:Number = 8; //Size of circle
        private var colors:Array = [0x000000, 0xFFFFFF]; //Color of circle;
        private var graph:Shape = new Shape(); //Graph circle class
        public var alive:Boolean = false; //Alive status
 
                public function Enemy(stat:int = 0) {
                        // constructor code
                        graph.graphics.beginFill(colors[stat], 0.9);
                        graph.graphics.drawCircle(0, 0, size);
                        graph.graphics.endFill();
                        addChild(graph);
                }
 
                public function draw(stat:int):void{
                        trace("change color");
                        graph.graphics.beginFill(colors[stat], 0.9);
                        graph.graphics.endFill();
                }
        }
}

Ох...вынесенный массив, а как его организовать вне конструктора основного класса?

Wolsh 25.11.2012 21:36

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

Код AS3:

var perem:Number = Math.random();
var some:Enemy;
if(perem > 0.7){
        some = new Enemy(0);
        some.alive = true;
        } else {
                some = new Enemy(1);
                some.alive = false;
        }
}


PasserBy 25.11.2012 21:56

Цитата:

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

Код AS3:

var perem:Number = Math.random();
var some:Enemy;
if(perem > 0.7){
        some = new Enemy(0);
        some.alive = true;
        } else {
                some = new Enemy(1);
                some.alive = false;
        }
}


Реализовал так, но ваш способ более гибок!! (спасибо)
Код AS3:

var some:Enemy = new Enemy();
                                        if(perem > 0.7){
                                                some.alive = true;
                                        } else {
                                                some.alive = false;
                                        }


Возникли новые вопросы)
Код AS3:

package  {
        import flash.display.*;
        import flash.events.*;
        import flash.utils.*;
 
        public class LiveGame extends MovieClip{
        private var timer:Timer;
        private var mama:Array = new Array(20);
 
                public function LiveGame() {
                        //Build Massive
                        for(var j:int = 0; j < 21; j++){
                                mama[j] = new Array(29);
                        }
                        // constructor code
                        var setk:Setka = new Setka();
                        addChild(setk);
                        //Generate enemy position
                        for(var i:int = 0; i < 20; i++){
                                for(var i2:int = 0; i2 < 27; i2++){
                                        var perem:Number = Math.random();
                                        var some:Enemy = new Enemy();
                                        if(perem > 0.7){
                                                some.alive = true;
                                        } else {
                                                some.alive = false;
                                        }
 
                                        some.x = (i2 + 1) * 20 - 10;
                                        some.y = (i + 1) * 20 - 10;
 
                                        mama[i][i2] = some; //!!!!
                                        trace(i  + " " + i2 + " " + mama[i][i2]); //Show me massive
                                        addChild(some);
                                }
                        }
                        //add TIMER
                        timer = new Timer(1000, 0);
                        timer.addEventListener(TimerEvent.TIMER, checker);
                        timer.start();
                }
 
                //Check function url to Timer option time
                private function checker(e:TimerEvent):void{
                        trace("Generation: " + e.target.currentCount);
                        //Check LIve here
                        var liver_a:int = 0;
                        for(var j:int = 0; j < 20; j++){
                                for(var j2:int = 0; j2 < 27; j2++){
 
                                        //CHECK LIVER AROUND
                                        //--
                                        if(j > 0 && j2 > 0){ //РУГАЕТСЯ НА ЭТУ МАССУ УСЛОВИЙ, ПОЧЕМУ:?
                                                if(mama[j - 1][j2 - 1].alive == true){ liver_a ++; }
                                        }
                                        //0-
                                        if(j2 > 0){
                                                if(mama[j][j2 - 1].alive == true){ liver_a ++; }
                                        }
                                        //+-
                                        if(j < 20 && j2 > 0){
                                                if(mama[j + 1][j2 - 1].alive == true){ liver_a ++; }
                                        }
                                        //-0
                                        if(j > 0){
                                                if(mama[j - 1][j2].alive == true){ liver_a ++; }
                                        }
                                        //+0
                                        if(j < 20){
                                                if(mama[j + 1][j2].alive == true){ liver_a ++; }
                                        }
                                        //-+
                                        if(j > 0 && j2 < 27){
                                                if(mama[j - 1][j2 + 1].alive == true){ liver_a ++; }
                                        }
                                        //0+
                                        if(j2 < 27){
                                                if(mama[j][j2 + 1].alive == true){ liver_a ++; }
                                        }
                                        //++
                                        if(j < 20 && j2 < 27){
                                                if(mama[j + 1][j2 + 1].alive == true){ liver_a ++; }
                                        }
                                }
                        }
                        trace(liver_a);
                }
                //removeListener's
                private function destroy():void{
                        timer.removeEventListener(TimerEvent.TIMER, checker);
                }
 
        }
 
}

Код:

TypeError: Error #1010: Термин не определен и не имеет свойств.
        at LiveGame/checker()
        at flash.utils::Timer/_timerDispatch()
        at flash.utils::Timer/tick()


Wolsh 25.11.2012 22:34

Последнее условие уберите. Мало того что оно бессмысленно, поскольку выполнится всегда (само условие дублирует условия циклов), так еще и при крайних значениях итераторов Вы выходите за границы массива. Попросту говоря, у Вас нет в массиве врагов никаких экземпляров врага по индексам mama[19+1=20][n] или mama[n][26+1=27]. 27 ячеек имеют индексы 0-26, например, а не 1-27. В ячейке 27 нет врага, там undefined или null, а у них нет свойства "живой".

PasserBy 25.11.2012 22:46

Цитата:

Сообщение от Wolsh (Сообщение 1106212)
Последнее условие уберите. Мало того что оно бессмысленно, поскольку выполнится всегда (само условие дублирует условия циклов), так еще и при крайних значениях итераторов Вы выходите за границы массива. Попросту говоря, у Вас нет в массиве врагов никаких экземпляров врага по индексам mama[19+1=20][n] или mama[n][26+1=27]. 27 ячеек имеют индексы 0-26, например, а не 1-27. В ячейке 27 нет врага, там undefined или null, а у них нет свойства "живой".

Убрать это?
Код AS3:

if(j < 20 && j2 < 27){
        if(mama[j + 1][j2 + 1].alive == true){ liver_a ++; }
}

Так внутренний массив состоит из 27 элементов, то есть если элемент 27 условие 27+ 1 не выполняется...к тому же обратите внимание на следующее ..
рабочий пример
Код AS3:

// North
                                        if ( y > 0 )
                                                if ( _cells[x][y-1].ok ) bros++;
 
                                        // North East
                                        if ( x < _max && y > 0 )
                                                if ( _cells[x+1][y-1].ok ) bros++;
 
                                        // North West
                                        if ( x > 0 && y > 0 )
                                                if ( _cells[x-1][y-1].ok ) bros++;
 
                                        // South
                                        if ( y < _max )
                                                if ( _cells[x][y+1].ok ) bros++;
 
                                        // South East
                                        if ( x < _max && y < _max )
                                                if ( _cells[x+1][y+1].ok ) bros++;
 
                                        // South West
                                        if ( x > 0 && y < _max )
                                                if ( _cells[x-1][y+1].ok ) bros++;
 
                                        // East
                                        if ( x < _max )
                                                if ( _cells[x+1][y].ok ) bros++;
 
                                        // West
                                        if ( x > 0 )
                                                if ( _cells[x-1][y].ok ) bros++;

полный код рабочего примера в приложенных файлах..=\

Krusty 25.11.2012 22:51

В плотном массиве из 27 элементов - элементы имеют индексы от 0 до 26 включительно. Нумерация элементов всегда с 0 в as3. Не Паскаль, да.

PasserBy 25.11.2012 23:00

Цитата:

Сообщение от Krusty (Сообщение 1106219)
В плотном массиве из 27 элементов - элементы имеют индексы от 0 до 26 включительно. Нумерация элементов всегда с 0 в as3. Не Паскаль, да.

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

Wolsh 25.11.2012 23:35

Вам вроде объяснили. У Вас нет элемента [n][27] и элемента [20][n]. Их нет. 27-й элемент имеет индекс 26. Соответственно все написанные условия приводят к ошибке — Вы обращаетесь к элементу, которого нет. Какими еще словами это объяснять, я не знаю. Предлагаю поспать и перечитать топик.

Я вообще не понял зачем Вам этот огород. Все эти вопросы только для того, чтобы выяснить, есть ли там элемент с индексом, который хочется проверить на живучесть. Вуаля.
Код AS3:

                        var arr:Array = new Array(9);
                        trace(arr[9] == null); // true

Так что вместо того, чтобы пытать значения итераторов, достаточно просто спросить, есть там кто? А уже потом — живой ли он?
Другими словами:
Код AS3:

if(mama[j - 1][j2 - 1]        is enemy && mama[j - 1][j2 - 1].alive)        liver_a ++;
if(mama[j - 1][j2]                is enemy && mama[j - 1][j2].alive)                liver_a ++;
if(mama[j - 1][j2 + 1]        is enemy && mama[j - 1][j2 + 1].alive)        liver_a ++;
if(mama[j + 1][j2 - 1]        is enemy && mama[j + 1][j2 - 1].alive)        liver_a ++;
if(mama[j + 1][j2]                is enemy && mama[j + 1][j2].alive)                liver_a ++;
if(mama[j + 1][j2 + 1]        is enemy && mama[j + 1][j2 + 1].alive)        liver_a ++;
if(mama[j][j2 + 1]                is enemy && mama[j][j2 + 1].alive)                liver_a ++;
if(mama[j][j2 - 1]                is enemy && mama[j][j2 - 1].alive)                liver_a ++;

Кроме того, можно просмотр этого квадрата 3х3 запихать в свой двойной циклик, дабы не строчить ритмичным стихом. Сможете?

Понять бы еще, чего считает этот счетчик печенок по всему полю)))

PasserBy 26.11.2012 09:41

Цитата:

Сообщение от Wolsh (Сообщение 1106224)
Вам вроде объяснили. У Вас нет элемента [n][27] и элемента [20][n]. Их нет. 27-й элемент имеет индекс 26. Соответственно все написанные условия приводят к ошибке — Вы обращаетесь к элементу, которого нет. Какими еще словами это объяснять, я не знаю. Предлагаю поспать и перечитать топик.

Я вообще не понял зачем Вам этот огород. Все эти вопросы только для того, чтобы выяснить, есть ли там элемент с индексом, который хочется проверить на живучесть. Вуаля.
Код AS3:

                        var arr:Array = new Array(9);
                        trace(arr[9] == null); // true

Так что вместо того, чтобы пытать значения итераторов, достаточно просто спросить, есть там кто? А уже потом — живой ли он?
Другими словами:
Код AS3:

if(mama[j - 1][j2 - 1]        is enemy && mama[j - 1][j2 - 1].alive)        liver_a ++;
if(mama[j - 1][j2]                is enemy && mama[j - 1][j2].alive)                liver_a ++;
if(mama[j - 1][j2 + 1]        is enemy && mama[j - 1][j2 + 1].alive)        liver_a ++;
if(mama[j + 1][j2 - 1]        is enemy && mama[j + 1][j2 - 1].alive)        liver_a ++;
if(mama[j + 1][j2]                is enemy && mama[j + 1][j2].alive)                liver_a ++;
if(mama[j + 1][j2 + 1]        is enemy && mama[j + 1][j2 + 1].alive)        liver_a ++;
if(mama[j][j2 + 1]                is enemy && mama[j][j2 + 1].alive)                liver_a ++;
if(mama[j][j2 - 1]                is enemy && mama[j][j2 - 1].alive)                liver_a ++;

Кроме того, можно просмотр этого квадрата 3х3 запихать в свой двойной циклик, дабы не строчить ритмичным стихом. Сможете?

Понять бы еще, чего считает этот счетчик печенок по всему полю)))

Достойное объяснение, выгодная альтернатива, спасибо!
Мне таки было непонятно с массивами..(п)
так в начале программы я создавал массивы с границами -
Код AS3:

private var mama:Array = new Array(20)//То есть тут будут 20 элементов с индексами от 0 до 19
 
                public function LiveGame() {
                        //Build Massive
                        for(var j:int = 0; j < 21; j++){
                                mama[j] = new Array(29);//То есть тут будут 29 элементов с индексами от 0 до 28
                        } etc.

Но ведь в цикле с проверкой я не выходил за эти рамки =\
Код AS3:

for(var j:int = 0; j < 20; j++){
                                for(var j2:int = 0; j2 < 27; j2++){ etc.

Делаю проверку я вот для чего .. Математическая игра жизнь
Из за погрешности в коде массивов и проверки
Код AS3:

if(mama[u][u2].alive == true){
                                                if(liver_a > 3 || liver_a < 2){
                                                        mama[u][u2].alive = false;
                                                } else if(liver_a == 2 || liver_a == 3){
                                                        mama[u][u2].alive = true;
                                                }
                                        } else if(mama[u][u2].alive == false){
                                                if(liver_a == 3){
                                                        mama[u][u2].alive = true;
                                                }
                                        }
                                        liver_a = 0;

ход игры идет не так =(

maxkar 26.11.2012 10:53

Цитата:

Сообщение от PasserBy (Сообщение 1106264)
Достойное объяснение, выгодная альтернатива, спасибо!
так в начале программы я создавал массивы с границами -
Код AS3:

private var mama:Array = new Array(20)//То есть тут будут 20 элементов с индексами от 0 до 19
                        for(var j:int = 0; j < 21; j++){} etc.


Это не массив с границами. Был создан массив с двадцатью null'ами. Прочитайте документацию на то, что делает конструктор, и примеры рядом. Затем в массив положили двадцать один элемент (не двадцать!).

Цитата:

Но ведь в цикле с проверкой я не выходил за эти рамки =\
Код AS3:

for(var j:int = 0; j < 20; j++){
                                for(var j2:int = 0; j2 < 27; j2++){ etc.


За рамки не выходили. Но и не инициализировали ничего на границах. Вы заполнили массив с индексами [0..19]. Затем пошли по тому же циклу и делаете следующее:
Код AS3:

if(j < 20 && j2 > 0){
  if(mama[j + 1][j2 - 1].alive == true){ liver_a ++; }
}

При j = 19 вы обращаетесь к mama[20], который содержит в себе массив с null'ами. Соответственно, после доступа по (j2-1) вы получите из него только null, у которого нет свойства alive.

Цитата:

Из за погрешности в коде массивов и проверки
Нет там погрешностей. Это вы с массивами не разобрались. Нужно аккуратно разобраться с индексами. Заодно разобраться с канонической формой итерации (for (var i = start; i < end; i++)) - вам нужно понять, по каким именно значениям выполняется итерация, что такое start и end в таком цикле.

Добавлено через 2 минуты
Цитата:

ход игры идет не так =(
Ход игры у вас не так идет еще и из-за того, что у вас новое поколение рождается не одновременно. Сначала проверяется одна клетка, при необходимости - обновляется. Затем с учетом уже нового состояния проверяется соседняя с ней и т.д.

PasserBy 26.11.2012 12:04

Цитата:

Сообщение от maxkar (Сообщение 1106270)
Это не массив с границами. Был создан массив с двадцатью null'ами. Прочитайте документацию на то, что делает конструктор, и примеры рядом. Затем в массив положили двадцать один элемент (не двадцать!).

За рамки не выходили. Но и не инициализировали ничего на границах. Вы заполнили массив с индексами [0..19]. Затем пошли по тому же циклу и делаете следующее:
Код AS3:

if(j < 20 && j2 > 0){
  if(mama[j + 1][j2 - 1].alive == true){ liver_a ++; }
}

При j = 19 вы обращаетесь к mama[20], который содержит в себе массив с null'ами. Соответственно, после доступа по (j2-1) вы получите из него только null, у которого нет свойства alive.


Нет там погрешностей. Это вы с массивами не разобрались. Нужно аккуратно разобраться с индексами. Заодно разобраться с канонической формой итерации (for (var i = start; i < end; i++)) - вам нужно понять, по каким именно значениям выполняется итерация, что такое start и end в таком цикле.

Добавлено через 2 минуты

Ход игры у вас не так идет еще и из-за того, что у вас новое поколение рождается не одновременно. Сначала проверяется одна клетка, при необходимости - обновляется. Затем с учетом уже нового состояния проверяется соседняя с ней и т.д.

Исправил, внесение изменений в массив, ..
Код AS3:

..
private var mama:Array = new Array(21); ////21 элементов массива, c инд. от 0 до 20
..
//Build Massive
        for(var j:int = 0; j < 21; j++){ //21 элементов массива, каждый из которых (с инд. от 0 до 20)
                mama[j] = new Array(27); //Приобретает значение нового массива из 27 элементов с инд. от 0 до 26
        }


Код AS3:

for(var i:int = 0; i < 21; i++){              //Чекаем по циклам в том же стиле, 
        for(var i2:int = 0; i2 < 27; i2++){ //что и создавали сие массивы (см.выше)
                var perem:Number = Math.random(); //Код ниже не имеет значения
                var some:Enemy = new Enemy();
                if(perem > 0.8){
                some.alive = true;
                } else {
                some.alive = false;
                }
 
                some.x = (i2 + 1) * 20 - 10;
                some.y = (i + 1) * 20 - 10;
 
                mama[i][i2] = some; //!!!!
                trace(i  + " " + i2 + " " + mama[i][i2]); //Show me massive
                addChild(some);
                }
        } etc.

Код AS3:

//Код вне конструктора
trace("Generation: " + e.target.currentCount);
                        //Check LIve here
                        var liver_a:int = 0;
                        for(var u:int = 0; u < 20; u++){//ОБРАТИТЕ ВНИМАНИЕ, используем те же параметры, что при
                                for(var u2:int = 0; u2 < 27; u2++){ // "населении" массива
 
                                        //CHECK LIVE AROUND
                                        //--
                                        if(u > 0 && u2 > 0){//Не позволяет выходить за границы [0-20,0-26]
                                                if(mama[u - 1][u2 - 1].alive == true){ liver_a ++; }
                                        }
                                        //0-
                                        if(u2 > 0){              //Не позволяет выходить за границы [0-20,0-26]
                                                if(mama[u][u2 - 1].alive == true){ liver_a ++; }
                                        }
                                        //+-
                                        if(u < 20 && u2 > 0){//Не позволяет выходить за границы [0-20,0-26]
                                                if(mama[u + 1][u2 - 1].alive == true){ liver_a ++; }
                                        }
                                        //-0
                                        if(u > 0){                //Не позволяет выходить за границы [0-20,0-26]
                                                if(mama[u - 1][u2].alive == true){ liver_a ++; }
                                        }
                                        //+0
                                        if(u < 20){              //Не позволяет выходить за границы [0-20,0-26]
                                                if(mama[u + 1][u2].alive == true){ liver_a ++; }
                                        }
                                        //-+
                                        if(u > 0 && u2 < 27){//Не позволяет выходить за границы [0-20,0-26]
                                                if(mama[u - 1][u2 + 1].alive == true){ liver_a ++; }
                                        }
                                        //0+
                                        if(u2 < 27){            //Не позволяет выходить за границы [0-20,0-26]
                                                if(mama[u][u2 + 1].alive == true){ liver_a ++; }
                                        }
                                        //++
                                        if(u < 20 && u2 < 27){//Не позволяет выходить за границы [0-20,0-26]
                                                if(mama[u + 1][u2 + 1].alive == true){ liver_a ++; }
                                        }
                                        /*
                                        ==========================
                                        > 3 = dead
                                        3 = new live
                                        2 - 3 = alive
                                        < 2 = dead
                                        ==========================
                                        */

                                        if(mama[u][u2].alive == true){
                                                if(liver_a > 3 || liver_a < 2){
                                                        mama[u][u2].alive = false;
                                                } else if(liver_a == 2 || liver_a == 3){
                                                        mama[u][u2].alive = true;
                                                }
                                        } else if(mama[u][u2].alive == false){
                                                if(liver_a == 3){
                                                        mama[u][u2].alive = true;
                                                }
                                        }
                                        liver_a = 0;
                                }               
                        }
                        redrawFunction();

И что в итоге? В итоге ламповый привет от ..
Код:

TypeError: Error #1010: Термин не определен и не имеет свойств.
        at LiveGame/checker()
        at flash.utils::Timer/_timerDispatch()
        at flash.utils::Timer/tick()


maxkar 26.11.2012 12:14

Цитата:

Код AS3:

                                        if(u > 0 && u2 < 27){//Не позволяет выходить за границы [0-20,0-26]
                                                if(mama[u - 1][u2 + 1].alive == true){ liver_a ++; }
                                        }


u2 + 1 == 27. А там объекта нет.
И включите отладочную информацию. Вам станет видно, в какой строке проблема.

PasserBy 26.11.2012 12:38

Цитата:

Сообщение от maxkar (Сообщение 1106280)
u2 + 1 == 27. А там объекта нет.
И включите отладочную информацию. Вам станет видно, в какой строке проблема.

Код AS3:

for(var u:int = 0; u < 20; u++){
                                for(var u2:int = 0; u2 < 27; u2++){  //ТУТ ОСТАВИТЬ
..
 
if(u > 0 && u2 < 26){//А ЗДЕСЬ НЕОБХОДИМО ИЗМЕНИТЬ ДИАПАЗОН?
                                                if(mama[u - 1][u2 + 1].alive == true){ liver_a ++; }
                                        }
..

Хм, работает, и вроде бы чекает все позиции.

Что касается "отладочной информации", пока не умею. Спасибо.

Wolsh 26.11.2012 12:49

Код AS3:

for(var q:uint = u-1; q < u+1; q++)
{
        for(var p:uint = u2-1; p < u2+1; p++)
        {
                var cellEnemy:enemy = mama[q][p] as enemy;
                if(cellEnemy != null && cellEnemy.alive) liver_a++;
        }
}
if(mama[u][u2].alive) liver_a--;

А Вам вообще надо для трупов считать врагов вокруг? А то может просто продолжать цикл, если mama[u][u2] уже труп и врагами не интересуется, чтобы не гонять циклы зазря.

PasserBy 26.11.2012 15:54

Цитата:

Сообщение от Wolsh (Сообщение 1106290)
Код AS3:

for(var q:uint = u-1; q < u+1; q++)
{
        for(var p:uint = u2-1; p < u2+1; p++)
        {
                var cellEnemy:enemy = mama[q][p] as enemy;
                if(cellEnemy != null && cellEnemy.alive) liver_a++;
        }
}
if(mama[u][u2].alive) liver_a--;

А Вам вообще надо для трупов считать врагов вокруг? А то может просто продолжать цикл, если mama[u][u2] уже труп и врагами не интересуется, чтобы не гонять циклы зазря.


Правила игры ЖИзнь
Код:

Правила

Место действия этой игры — «вселенная» — это размеченная на клетки поверхность или плоскость — безграничная, ограниченная, или замкнутая (в пределе — бесконечная плоскость).

Каждая клетка на этой поверхности может находиться в двух состояниях: быть «живой» или быть «мёртвой» (пустой). Клетка имеет восемь соседей (окружающих клеток).

Распределение живых клеток в начале игры называется первым поколением. Каждое следующее поколение рассчитывается на основе предыдущего по таким правилам:

в пустой (мёртвой) клетке, рядом с которой ровно три живые клетки, зарождается жизнь;

если у живой клетки есть две или три живые соседки, то эта клетка продолжает жить;
в противном случае (если соседей меньше двух или больше трёх) клетка умирает («от одиночества» или «от перенаселённости»).

Игра прекращается, если на поле не останется ни одной «живой» клетки, если при очередном шаге ни одна из клеток не меняет своего состояния (складывается стабильная конфигурация) или если конфигурация на очередном шаге в точности (без сдвигов и поворотов) повторит себя же на одном из более ранних шагов (складывается периодическая конфигурация).


PasserBy 27.11.2012 18:23

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

main
Код AS3:

package  {
        import flash.display.*;
        import flash.events.*;
        import flash.ui.*;
        import flash.utils.Timer;
        //@author I'm
        public class Main extends MovieClip{
        private var CellSize:int = 10; //DEFAULT CELL SIZE
        private var CellPad:int = 40//DEFAULT CELL PAD
        private var _max:int;                    //FOR MASSIVE SIZE
        private var mamaDefault:Array = new Array(); //DEFAULT MASSIVE
        private var mamaLoad:Array = new Array();        //FOR LOAD FUNCTION MASSIVE
 
        private var timeM:Timer;
 
                public function Main() {
                        // constructor code
                        var _grid:Grid = new Grid(CellSize, CellPad); //ADD GRID
                        addChild(_grid);
 
                        _max = CellPad - 1;
                        creatLive();
 
                        timeM = new Timer( 200 );
                        timeM.addEventListener(TimerEvent.TIMER, timerListener);
                        timeM.start();
                }
 
                //CREAT MASSIVES & ADD CELL's
                private function creatLive():void{
                        var i:int;
                        var j:int;
                        for(i = 0; i < _max; i++){
                                mamaDefault[i] = new Array();
                                mamaLoad[i] = new Array();
 
                                for(j = 0; j < _max; j++){
                                        var decisive:Number = Math.random();
                                        var _cell:Cell = new Cell(CellSize);
                                        _cell.x = i * CellSize;                                                //TAKE CELL POSITION
                                        _cell.y = j * CellSize;
                                        if( decisive > 0.9 ){
                                                Cell(_cell).setState(1);
                                        } else {
                                                Cell(_cell).setState(0);
                                        }
                                        mamaDefault[i][j] = _cell;
                                        mamaLoad[i][j] = Cell(_cell).getState();
                                        addChild(_cell);
                                }
                        }
                }
 
                //TIME SHIFT MANAGER
                private function timerListener(e:TimerEvent):void{
                        checkLiveAround();
                }
 
                //CHECK AROUND STATUS AND WRITE IT ON MASSIVE 2 (mamaLoad)
                private function checkLiveAround():void{
                        var i1:int;
                        var i2:int;
                        var bros:int = 0;                                                                        //POINT OF LIVE AROUND
                        var _min:int = _max - 1;                                                        //NUMBER, FOR CHECK BORDER
                        //trace(CellPad, _max, _min);
                        //START CHECK MASSIVE
                        for(i1 = 0; i1 < _max; i1++){
                                for(i2 = 0; i2 < _max; i2++){
                                        // North
                                        if ( i2 > 0 )
                                                if ( mamaDefault[i1][i2-1]._state > 0.4 ) bros++;
 
                                        // North East
                                        if ( i1 < _min && i2 > 0 )
                                                if ( mamaDefault[i1+1][i2-1]._state > 0.4 ) bros++;
 
                                        // North West
                                        if ( i1 > 0 && i2 > 0 )
                                                if ( mamaDefault[i1-1][i2-1]._state > 0.4 ) bros++;
 
                                        // South
                                        if ( i2 < _min )
                                                if ( mamaDefault[i1][i2+1]._state > 0.4 ) bros++;
 
                                        // South East
                                        if ( i1 < _min && i2 < _min )
                                                if ( mamaDefault[i1+1][i2+1]._state > 0.4 ) bros++;
 
                                        // South West
                                        if ( i1 > 0 && i2 < _min )
                                                if ( mamaDefault[i1-1][i2+1]._state > 0.4 ) bros++;
 
                                        // East
                                        if ( i1 < _min )
                                                if ( mamaDefault[i1+1][i2]._state > 0.4 ) bros++;
 
                                        // West
                                        if ( i1 > 0 )
                                                if ( mamaDefault[i1-1][i2]._state > 0.4 ) bros++;
 
                                        /*
                                        DO NEW MASSIVE WITH PARAMETERS OF NEW LIVE
                                        ==========================================
                                        2 or 3 = alive
                                        > 3 or < 2 = dead
                                        ==========================================
                                        */

                                        if( bros == 3 || bros == 2){
                                                mamaLoad[i1][i2] = 1;
                                        } else if( bros > 3 || bros < 2){
                                                mamaLoad[i1][i2] = 0;
                                        }
                                        if( mamaDefault[i1][i2]._state > 0.4 && bros == 3 ){
                                                mamaLoad[i1][i2] = 0.5;
                                        }
                                        bros = 0;
                                }
                        }
                        unWriteMassive1();
                        //END CHECK MASSIVE
                }
 
                //FUNCTION TO UNWRITE FIRST MASSIVE (mamaDefault)
                private function unWriteMassive1():void{
                        var i1:int;
                        var i2:int;
                        for(i1 = 0; i1 < _max; i1++){
                                for(i2 = 0; i2 < _max; i2++){
                                        Cell(mamaDefault[i1][i2]).setState(mamaLoad[i1][i2]);
                                }
                        }
                        //trace("Complete rewrite");
                }
 
        }
 
}

Cell
Код AS3:

package  {
        import flash.display.*;
        import flash.events.*;
        import flash.ui.*;
 
        public class Cell extends Sprite{
        private var _size:int = 10;
        public var _state:Number = 1; //THIS ALPHA
        public var ok:Boolean = false; //Alive STATUS
        private var gra:Shape = new Shape();
 
                public function Cell(size:int) {
                        // constructor code
                        _size = size;
                        gra.graphics.beginFill(0x000000,1);
                        gra.graphics.drawRect( 0, 0, _size, _size);
                        gra.graphics.endFill();
                        gra.addEventListener(Event.ENTER_FRAME, checkState);
                        addChild(gra);
                }
                //LISTENER OF GRA
                private function checkState(e:Event):void{
                        this.alpha = _state;
                }
                //TAKE STATE
                public function setState(stateHere:Number):void{
                        _state = stateHere;
                }
                //GET STATE
                public function getState():Number{
                        return _state;
                }
        }
}

Нелогичное движение ии в приложенных файлах (.swf)

PasserBy 27.11.2012 18:55

Ах!!!!!....Проблема Решена!!! эйфория, кайф ))))
Решение:

Код который был(вырезка)
Код AS3:

if( bros == 3 || bros == 2){
                                                mamaLoad[i1][i2] = 1;
                                        } else if( bros > 3 || bros < 2){
                                                mamaLoad[i1][i2] = 0;
                                        }
                                        if( mamaDefault[i1][i2]._state > 0.4 && bros == 3 ){
                                                mamaLoad[i1][i2] = 0.5;
                                        }
                                        bros = 0;

Измененный код(вырезка):
Код AS3:

if(Cell(mamaDefault[i1][i2])._state > 0.4){
                                                if( bros == 3 || bros == 2){
                                                        mamaLoad[i1][i2] = 1;
                                                } else if( bros > 3 || bros < 2){
                                                        mamaLoad[i1][i2] = 0;
                                                }
                                        }
                                        if( bros == 3 ){
                                                mamaLoad[i1][i2] = 0.5;
                                        }
                                        bros = 0;

Вот..В приложенных файлах няшная рабочая версия. всем спасибо!

Wolsh 27.11.2012 22:43

1) зацикливается на повторяющихся состояниях
2) ни разу не видел клетку с тремя соседями (по правилам перенаселение это больше трех соседей)
3) продолжают жить непонятные конструкции из одной красной и двух полупрозрачных клеток, которые крутятся вокруг живой.
4) остаются конструкции из только полупрозрачных клеток. Не очень понял, кто это.


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

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