Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript (http://www.flasher.ru/forum/forumdisplay.php?f=5)
-   -   Вложенный цикл который все испортил :( (http://www.flasher.ru/forum/showthread.php?t=21383)

Bukhtik 16.10.2001 03:37

Вложенный цикл который все испортил :(
 
Написал шашки
users.i.com.ua/~bukhtik/checkers/checkers.html и вроде как все должно быть хорошо т.к. ничего в них сложного нет, ан не тут то было :(.

10 раз проверил алгоритм т.к. в определенный момент почему то не хочет убирать шашку с поля и виновник был найден - при проверке всех возможных ходов шашек
(Цель =
1. Найти может ли еще человек ходить или все шашки заперты
2. Проверить ситуацию "Бить обязан")

используется цикл вида (8*8 - всего 64 :( ):
Код:

                RedMustJump = new Array();
                BlueMustJump = new Array();
                BlueCanMove = false;
                RedCanMove = false;
                for (i = 0; i<8; i++) {
                        for (j = 0; j<8; j++) {
                                name2=getname(i, j);
                                if (name2<>0) {
                                        MustJump(i, j, 0);
                                        MustJump(i, j, 1);
                                        MustJump(i, j, 2);
                                        MustJump(i, j, 3);
                                }
                        }
                }

Масивы хранят после отработки функции MustJump инстансы шашек которые могут бить.

Функция MustJump:
Код:

function MustJump (x, y, direction) {
                checkPoint = new Array();
                secondcheckPoint = new Array();
                checkPoint[0] = x;
                secondcheckPoint[0] = x;
                checkPoint[1] = y;
                secondcheckPoint[1] = y;
                if (direction == 0) {
                        // blue
                        checkPoint[1]++;
                        checkPoint[0]++;
                        secondCheckPoint[1] += 2;
                        secondCheckPoint[0] += 2;
                } else if (direction == 1) {
                        // blue
                        checkPoint[0]++;
                        checkPoint[1]--;
                        secondCheckPoint[0] += 2;
                        secondCheckPoint[1] -= 2;
                } else if (direction == 2) {
                        // red
                        checkPoint[0]--;
                        checkPoint[1]--;
                        secondCheckPoint[0] -= 2;
                        secondCheckPoint[1] -= 2;
                } else if (direction == 3) {
                        // red
                        checkPoint[0]--;
                        checkPoint[1]++;
                        secondCheckPoint[0] -= 2;
                        secondCheckPoint[1] += 2;
                }
                _level0.MustJump = 1;
                name1=getname(x, y, true);
                if ((checkPoint[0]>7) || (checkPoint[0]<0) || (checkPoint[1]>7) || (checkPoint[1]<0)) {
                        _level0.MustJump = 0;
                }
                if (eval(name1+".crown._visible") == false) {
                        if (name2 == -1) {
                                if (direction == 0 || direction == 1) {
                                        _level0.MustJump = 0;
                                }
                        } else if (direction == 2 || direction == 3) {
                                _level0.MustJump = 0;
                        }
                }
                if (_level0.MustJump<>0) {
                        if ((secondcheckPoint[0]<7) || (secondcheckPoint[0]>0) || (secondcheckPoint[1]<7) || (secondcheckPoint[1]>0)) {
                                if ((name2<>getname(checkPoint[0], checkPoint[1])) && (getname(checkPoint[0], checkPoint[1])<>0)) {
                                        if (getname(secondcheckPoint[0], secondcheckPoint[1]) == 0) {
                                                if (name2 == -1) {
                                                        RedCanMove = true;
                                                        RedMustJump[RedMustJump.length] = name1;
                                                } else {
                                                        BlueCanMove = true;
                                                        BlueMustJump[BlueMustJump.length] = name1;
                                                }
                                        }
                                }
                        }
                        if ((getname(checkPoint[0], checkPoint[1]) == 0) && ((RedCanMove == false) || (BlueCanMove == false))) {
                                if (name2 == -1) {
                                        RedCanMove = true;
                                } else {
                                        BlueCanMove = true;
                                }
                        }
                }
        }

Пояснения: getname() - функция возвращает с заданным 3 параметром true имя инстанса с false - тип клетки поля: 1 - синяя шашка, -1 - красная, 0 - не занята. Переменные name2 и name1 можно и не использовать, но опыты показали что с их помощью тормозит чуть меньше (вызывается getname() один раз, а не несколько)

Проблемма приведенный выше цикл дает задержку 3-5 сек (Celeron-466), + иногда таки перегружает (как мне кажется) флеш и он не убирает убитую шашку с поля.

Проверялось:
1. Убирал цикл => нет задержки

2. Повторял по ходам с трейсом ситуацию когда шашка не убирается с поля 1 раз не убирает, при повторе 10 раз ситуации убирает... (т.е. не убирает "случайным" образом)

3. Пробовал зациклить функцию, которая убирает шашку с поля путем проверки в конце ее а убрана ли шашка с последующим вызовом самой себя при отрицательном ответе - безрезультатно, флеш упорно выдает что все ок и шашка убрана :(.

ЗЫ сорри за столь длинный пост, но хотелось обьяснить все подробно.

Bukhtik 16.10.2001 20:18

Т.к. игра задумана на двоих этот цикл будет перенесен на серверную часть, но все же если кто то придумает, как решить поблемму цикла средствами флеша буду очень благодарен. :)

APM 16.10.2001 21:04

Если не трудно то можешь прислать всю флешку?
Меня заинтересовало нестабильность работы, охота посмотреть в чем дело. Честное слово никуда дальше не уйдет. Можно даже без графики.
А насчет ускорения работы, то кардинально можно ускорить только
если перейти к другой модели - битовой, у тебя реально на доске
32 рабочие клетки, ровно столько сколько бит в слове. Можно попробовать работать масками, а не лобовым перебором.
В любом случае начинать надо с трассировки - сначала найти
максимально долго исполняющуюся функцию, а затем уменьшить количество холостых переборов.
APM apm@tut.by

Bukhtik 18.10.2001 02:13

Отправил.

Barmaglot 18.10.2001 15:54

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

Bukhtik 18.10.2001 20:53

1. По поводу проверки - реально после строки

Код:

if (name2<>0) {...
остаются всего максимум 24 проверяемых ячейки
+ можно проверять только красных/синих на их ходе => в худшем случае получим уменьшение цикла в половину... но все равно притормаживание весьма заметно.

2. По поводу русских шашек - сделаю :), как эти добью.

3. Видел тут топик недавно по схожей тематике
http://flasher.ru/forum/showthread.php?threadid=20138

так вот при включенном дебаге:
510 переменных = 3.313 сек, при выключеном 0,48 сек... (т.е. 2 цифра сопоставима с приведенными в топике данными)
быстрый сплит = 3.737 сек
обычный сплит = 77.223!!!!! (странный результат...)

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

APM 18.10.2001 22:41

ТОлько что получил исходник - проблемы с почтой.
И сразу нашел тормоз да еще какой!!!
Ты определяешь функции в событии mouseMove - это даже хуже
чем в событии enterFrame - перенеси их в событие onLoad - пока не сильно помогает в смысле что-то все-равно не работает но уже реже.

Bukhtik 19.10.2001 02:30

:) эт я пробовал, но т.к. заметной разницы не было вернул как было, ок перенесу.

На самом деле во флеше это моя первая прога, так в основном на других языках пишу, последнее время чаще всего пхп, немного реже Delphi/C, так что представление о програмировании имеется а вот что флеш себя так нехорошо вести будет не думал...

APM 19.10.2001 21:13

Для первого проекта не так уж плохо. Ошибку пока не обнаружил.
Но есть некоторые замечания общего плана.
Первое.
Чувствуется стиль программирования от PHP & Delfi - к сожалению
во флэше это не всегда плюс. Во всех введениях во флэш отсутствует
одно принциальное упоминание об отличии программирования во флэш и
в большинстве всех остальных языков, даже с похожим синтаксисом,
например, JavaScript. Это реально программирование хоть и псевдо
но все-таки многопоточной параллельной системы системы. Все остальные
известные мне языки на самом деле линейны в принципе, и многопоточность
там реализуется специальными средствами, и, самое главное, сознательно.
Во флеше ты сразу же, без предупреждения, попадаешь в мир параллельного
программирования. Это очень удобно, но и достаточно опасно. О синхронизации процессов как-то не думаешь.
Второе.
Основные тормоза у тебя из-за функции getName(). Точнее из-за ее
реализации. Флэш - интерпретатор и работа со строками в нем
реализована достаточно медленно. А у тебя substring используется
слишком часто и не по делу. За удобство работы с именами, приходится
заплатить скоростью. Можно конечно чуть-чуть ускорить заменив
substring на substr - она хотя и депрекейтет, но на самом деле
substring реализованно именно через нее. Но лучше менять
кардинально - "Самая лучшая, самая надежная, самая дешевая деталь в
танке - та которой НЕТ" - принцип создателей танка Т-34 (я думаю
это о чем-то тебе говорит). Поэтому выбрасываем getName() совсем
и заменяем ее другой и немного усложняем инициализацию(она точно
выполняется один раз - так что не должна тормозить в принципе)
Там где ты инициализируешь board1 можно записать следущее
myBoard = new Array()
for (var counter = 0; counter<8; counter++)
{ myBoard[counter] = new Array()
for (var counter2 = 0; counter2<8; counter2++)
{ myBoard[counter][counter2] = 0
}
}
myName = new Array()
myName[0] = "" //not used but may be usefull
myBoard[0][0] = 1
myName[1] = _level0.blue00_64._name;
myBoard[0][2] = 2
myName[2] =_level0.blue10_65._name;
myBoard[0][4] = 3
myName[3] = _level0.blue20_66._name;
myBoard[0][6] = 4
myName[4] = _level0.blue30_67._name;
myBoard[2][0] = 5
myName[5] = _level0.blue00_68._name;
myBoard[2][2] = 6
myName[6] = _level0.blue10_69._name;
myBoard[2][4] = 7
myName[7] = _level0.blue20_70._name;
myBoard[2][6] = 8
myName[8] = _level0.blue30_71._name;
myBoard[1][1] = 9
myName[9] = _level0.blue00_72._name;
myBoard[1][3] = 10
myName[10] = _level0.blue10_73._name;
myBoard[1][5] = 11
myName[11] = _level0.blue20_74._name;
myBoard[1][7] = 12
myName[12] = _level0.blue30_75._name;
myBoard[5][1] = -13
myName[13] = _level0.red00_76._name;
myBoard[5][3] = -14
myName[14] = _level0.red10_77._name;
myBoard[5][5] += -15
myName[15] = _level0.red20_78._name;
..............
ну и так далее - смысл надеюсь понятен - если значение myBoard[x][y]
равно нулю - это пустая клетка, если больше нуля - синяя шашка
если меньше - красная. А имя можно получить из массива myName:
myName[Math.abs(myBoard[x][y])]
Гарантированно будет работать быстрее, и код будет чище
а инициализацию массива можно сильно подсократить если заполнять
их сразу же там где ты делаешь duplicateMovie.
По поводу не стабильности работы - то у меня подозрение на то как
ты прописываешь путь шашки - потому, что у меня была ситуация,
когда с поля снялась совсем не та шашка которую бил. Но если ты
перейдешь к номерам шашек это наверно будет проще вычислить
так как путь сохраняется и его можно посмотреть в отладчике.
сделай для этого переменную oldPath чтобы она не затиралась
или выводи ее пока в строку статус. Я еще не понял то ли у тебя
ошибка в коде или это все-таки какое-то неудачное взаимодействие
параллельных процессов.
Если подправишь - вышли новую версию. Самому вносить исправления и
отслеживать где это используется нет времени - отпуск на носу
и нужно подогнать все хвосты.

Bukhtik 22.10.2001 01:12

Только сегодня добрался до компа...

Вроде поправил, теперь работает значительно стабильнее, но все таки притормаживает если пускать во флеше а не в броузере...

Возникла еще одна интересная проблемма у человека, который тестил последний вариант, цитирую:

Цитата:

Есть глюки.
Дошол я синей до самого низа, а она не стала выглядеть как дамка, но ходить как дамка стала

Это получилось -
Я взял шашку что бы сделать ход и в этот момент открылась аська, закрыв собой поле.
Я ответил на сообщение и закрыл окно аськи.
Даже с отпущеной кнопкой мышки шашка болталась за курсором по всему экрану и когда я ее поставил, то она не стала дамкой.
Можно ли с таким безобразием как то бороться??? (если ходить по нормальному т.е. без аськи вроде таких глюков не бывает...)

ЗЫ исправленный исходник отослал.


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

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