Форум программистов, компьютерный форум, киберфорум
ActionScript
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/8: Рейтинг темы: голосов - 8, средняя оценка - 5.00
 Аватар для Defake
5 / 5 / 0
Регистрация: 24.08.2011
Сообщений: 191
AS 3.0

Движок поиска пути

05.01.2013, 10:53. Показов 1531. Ответов 2
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Пишу по урокам движок поиска, но чуть шаг в сторону - уже ошибки. Помогите исправить, пожалуйста.
ActionScript 3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
private function goWater(x_:int, y_:int):void {
            if (inMap(x_, y_ - 1) && _mapMask[x_][y_ - 1] == _freeCell) {
                // Заполняем клетку водой
                _mapMask[x_][y_ - 1] = WATER_KEY; 
                // Запоминаем из какой клетки вода пришла
                (_mapDirs[x_][y_ - 1] as Point).x = x_;
                (_mapDirs[x_][y_ - 1] as Point).y = y_;
            }
            if (inMap(x_, y_ + 1) && _mapMask[x_][y_ + 1] == _freeCell) {
                _mapMask[x_][y_ + 1] = WATER_KEY;
                (_mapDirs[x_][y_ + 1] as Point).x = x_;
                (_mapDirs[x_][y_ + 1] as Point).y = y_;
            }
            if (inMap(x_ - 1, y_) && _mapMask[x_ - 1][y_] == _freeCell) {
                _mapMask[x_ - 1][y_] = WATER_KEY; 
                (_mapDirs[x_ - 1][y_] as Point).x = x_;
                (_mapDirs[x_ - 1][y_] as Point).y = y_;
            }
            if (inMap(x_ + 1, y_) && _mapMask[x_ + 1][y_] == _freeCell) {
                _mapMask[x_ + 1][y_] = WATER_KEY;
                (_mapDirs[x_ + 1][y_] as Point).x = x_;
                (_mapDirs[x_ + 1][y_] as Point).y = y_;
            }
}
В таком виде всё работает, но когда в условии if я убираю метод inMap
ActionScript 3
1
2
3
4
5
6
7
private function inMap(x_:int, y_:int):Boolean {
            if (x_ >= 0 && x_ < _mapWidth && y_ >= 0 && y_ < _mapHeight) {
                return true;
            } else {
                return false;
            }
        }
Тогда выскакивает ошибка "Error #1010: Термин не определен и не имеет свойств."
Пробовал и trace(_mapMask[x_][y_]) и всякое такое, но всё время пишет, что термин не определен. Но когда вместе с методом, например так:
ActionScript 3
1
trace(inMap(x_, y_ + 1) && _mapMask[x_][y_ + 1] == _freeCell);
то, о чудо! Работает.

Это было во-первых. Теперь во-вторых:
Я к стандартному поиску пути по прямым клеточкам добавил диагональный поиск пути:
ActionScript 3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//В той же функции goWater
if (inMap(x_ - 1, y_ - 1) && _mapMask[x_ - 1][y_ - 1] == _freeCell && (_mapMask[x_ - 1][y_] == _freeCell || _mapMask[x_][y_ - 1] == _freeCell)) {
                _mapMask[x_ - 1][y_ - 1] = WATER_KEY; 
                (_mapDirs[x_ - 1][y_ - 1] as Point).x = x_;
                (_mapDirs[x_ - 1][y_ - 1] as Point).y = y_;
            }
            if (inMap(x_ + 1, y_ - 1) && _mapMask[x_ + 1][y_ - 1] == _freeCell && (_mapMask[x_ + 1][y_] == _freeCell || _mapMask[x_][y_ - 1] == _freeCell)) {
                _mapMask[x_ + 1][y_ - 1] = WATER_KEY;
                (_mapDirs[x_ + 1][y_ - 1] as Point).x = x_;
                (_mapDirs[x_ + 1][y_ - 1] as Point).y = y_;
            }
            if (inMap(x_ - 1, y_ + 1) && _mapMask[x_ - 1][y_ + 1] == _freeCell && (_mapMask[x_ - 1][y_] == _freeCell || _mapMask[x_][y_ + 1] == _freeCell)) {
                _mapMask[x_ - 1][y_ + 1] = WATER_KEY; 
                (_mapDirs[x_ - 1][y_ + 1] as Point).x = x_;
                (_mapDirs[x_ - 1][y_ + 1] as Point).y = y_;
            }
            if (inMap(x_ + 1, y_ + 1) && _mapMask[x_ + 1][y_ + 1] == _freeCell && (_mapMask[x_ + 1][y_] == _freeCell || _mapMask[x_][y_ + 1] == _freeCell)) {
                _mapMask[x_ + 1][y_ + 1] = WATER_KEY;
                (_mapDirs[x_ + 1][y_ + 1] as Point).x = x_;
                (_mapDirs[x_ + 1][y_ + 1] as Point).y = y_;
            }
Разберем условие. С самого начала было только:
ActionScript 3
1
 (inMap(x_ + 1, y_ + 1) && _mapMask[x_ + 1][y_ + 1] == _freeCell)
но тогда моб проходил между двумя закрытыми клетками. То есть, к примеру, моб окружен закрытыми клетками (через которые нельзя ходить), а по диагонали нашлась свободная клетка - он там проходил. Я решил это исправить.
То есть, если моб хочет пройти в клетку, которая справа-снизу от него, то должна быть по крайней мере одна свободная клетка либо справа, либо снизу от него.
ActionScript 3
1
 (inMap(x_ + 1, y_ + 1) && _mapMask[x_ + 1][y_ + 1] == _freeCell && (_mapMask[x_ + 1][y_] == _freeCell || _mapMask[x_][y_ + 1] == _freeCell))
И вот здесь моб вообще перестал ходить по диагоналям. Я думал, что намудрил со скобками. Но и такой вариант:
ActionScript 3
1
2
3
4
5
if (inMap(x_ + 1, y_ + 1) && _mapMask[x_ + 1][y_ + 1] == _freeCell) {
if (_mapMask[x_ + 1][y_] == _freeCell || _mapMask[x_][y_ + 1] == _freeCell) {
//Код
}
}
Не подошел.

Можете, пожалуйста, подсказать, в чем дело?
На всякий случай выкладываю весь код класса PathFinder
ActionScript 3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
public class PathFinder 
    {
        private static const WATER_KEY:int = 999;
        private var _mapMask:Array = [], _mapDirs:Array = [];
        private var _mapWidth:int = 0, _mapHeight:int = 0; 
        private var _freeCell:int = 1; // Вид свободной ячейки
        private var _maxIterations:int = 150; // Счетчик повторов
 
        public function PathFinder(mapArr_:Array) 
        {
            var rowMask:Array; 
            var rowDirs:Array; 
            _mapWidth = mapArr_.length; 
            _mapHeight = mapArr_[0].length; 
            for (var x:int = 0; x < _mapWidth; x++) {
                rowMask = []; 
                rowDirs = [];
                for (var y:int = 0; y < _mapHeight; y++) {
                    rowMask.push(mapArr_[x][y]); // Копируем состояние клетки
                    rowDirs.push(new Point()); // Создаем нулевую коордианту направления
                }
                _mapMask.push(rowMask);
                _mapDirs.push(rowDirs);
            }
        }
        
        private function inMap(x_:int, y_:int):Boolean {
            if (x_ >= 0 && x_ < _mapWidth && y_ >= 0 && y_ < _mapHeight) {
                return true;
            } else {
                return false;
            }
        }
        
        public function findWay(start_:Point, finish_:Point):Array {
            _mapMask[finish_.x][finish_.y] = WATER_KEY;
            var count:int = 0;
            while (count < _maxIterations) {
                for (var y_:int = 0; y_ < _mapHeight; y_++) {
                    for (var x_:int = 0; x_ < _mapWidth; x_++) {
                        if (_mapMask[x_][y_] == WATER_KEY) {
                            goWater(x_, y_);
                        }
                    }
                }
                if (_mapMask[start_.x][start_.y] == WATER_KEY) {
                    trace("Путь есть!");
                    return getWay(start_, finish_);
                }
                trace("count=" +count);
                count++;
                if (count == _maxIterations) {
                    trace("MAX ITERATIONS");
                }
            }
            return [];
        }
        
        private function goWater(x_:int, y_:int):void {
            if (inMap(x_, y_ - 1) && _mapMask[x_][y_ - 1] == _freeCell) {
                // Заполняем клетку водой
                _mapMask[x_][y_ - 1] = WATER_KEY; 
                // Запоминаем из какой клетки вода пришла
                (_mapDirs[x_][y_ - 1] as Point).x = x_;
                (_mapDirs[x_][y_ - 1] as Point).y = y_;
            }
            if (inMap(x_, y_ + 1) && _mapMask[x_][y_ + 1] == _freeCell) {
                _mapMask[x_][y_ + 1] = WATER_KEY;
                (_mapDirs[x_][y_ + 1] as Point).x = x_;
                (_mapDirs[x_][y_ + 1] as Point).y = y_;
            }
            if (inMap(x_ - 1, y_) && _mapMask[x_ - 1][y_] == _freeCell) {
                _mapMask[x_ - 1][y_] = WATER_KEY; 
                (_mapDirs[x_ - 1][y_] as Point).x = x_;
                (_mapDirs[x_ - 1][y_] as Point).y = y_;
            }
            if (inMap(x_ + 1, y_) && _mapMask[x_ + 1][y_] == _freeCell) {
                _mapMask[x_ + 1][y_] = WATER_KEY;
                (_mapDirs[x_ + 1][y_] as Point).x = x_;
                (_mapDirs[x_ + 1][y_] as Point).y = y_;
            }
            
            //ДИАГОНАЛЬНЫЙ ПОИСК ПУТИ
            if (inMap(x_ - 1, y_ - 1) && _mapMask[x_ - 1][y_ - 1] == _freeCell && (_mapMask[x_ - 1][y_] == _freeCell || _mapMask[x_][y_ - 1] == _freeCell)) {
                _mapMask[x_ - 1][y_ - 1] = WATER_KEY; 
                (_mapDirs[x_ - 1][y_ - 1] as Point).x = x_;
                (_mapDirs[x_ - 1][y_ - 1] as Point).y = y_;
            }
            if (inMap(x_ + 1, y_ - 1) && _mapMask[x_ + 1][y_ - 1] == _freeCell && (_mapMask[x_ + 1][y_] == _freeCell || _mapMask[x_][y_ - 1] == _freeCell)) {
                _mapMask[x_ + 1][y_ - 1] = WATER_KEY;
                (_mapDirs[x_ + 1][y_ - 1] as Point).x = x_;
                (_mapDirs[x_ + 1][y_ - 1] as Point).y = y_;
            }
            if (inMap(x_ - 1, y_ + 1) && _mapMask[x_ - 1][y_ + 1] == _freeCell && (_mapMask[x_ - 1][y_] == _freeCell || _mapMask[x_][y_ + 1] == _freeCell)) {
                _mapMask[x_ - 1][y_ + 1] = WATER_KEY; 
                (_mapDirs[x_ - 1][y_ + 1] as Point).x = x_;
                (_mapDirs[x_ - 1][y_ + 1] as Point).y = y_;
            }
            if (inMap(x_ + 1, y_ + 1) && _mapMask[x_ + 1][y_ + 1] == _freeCell && (_mapMask[x_ + 1][y_] == _freeCell || _mapMask[x_][y_ + 1] == _freeCell)) {
                _mapMask[x_ + 1][y_ + 1] = WATER_KEY;
                (_mapDirs[x_ + 1][y_ + 1] as Point).x = x_;
                (_mapDirs[x_ + 1][y_ + 1] as Point).y = y_;
            }
        }
        
        private function getWay(start_:Point, finish_:Point):Array {
            var way:Array = [];
            var p1:Point = new Point(start_.x, start_.y);
            var p2:Point = new Point();
            trace("S="+start_);
            while (p1.x != finish_.x || p1.y != finish_.y) {
                p2.x = (_mapDirs[p1.x][p1.y] as Point).x
                p2.y = (_mapDirs[p1.x][p1.y] as Point).y
                way.push(new Point(p2.x, p2.y));
                p1.x = p2.x;
                p1.y = p2.y;
                trace(_mapDirs[p1.x][p1.y]);
            }
            trace("OK!");
            return way;
        }
    }
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
05.01.2013, 10:53
Ответы с готовыми решениями:

Поиск пути в играх. Алгоритм поиска пути A*
В своё время долго и упорно разбирал различные алгоритмы поиска путей для различных задач. Сейчас, во время отпуска, решил сделать доброе...

Движок поиска для самописного сайта
Есть самописный движок, необходимо организовать поиск по БД (mysql), по двум полям - русское название и название на английском языке. При...

Нужен движок на рнр гостевой книги форума и поиска по сайту
Прошу прошения но Нужен движок на рнр гостевой книги форума и поиска по сайту рнр я немного знаю но написать сам мало времени буду...

2
Модератор
 Аватар для TanaTiX
2936 / 1795 / 180
Регистрация: 19.02.2011
Сообщений: 6,552
05.01.2013, 11:49
1) В том методе происходит проверка на допустимые координаты ячейки. Соответственно если происходит выход за пределы карта, то дальше проверка не происходит. Если эту проверку убрать, то вы ссылаетесь на несуществующий объект и получаете ошибку.
2) А что говорят трэйсы? Дебажить пробовал? Видимых ошибок, не пробуя компилировать не вижу.
1
 Аватар для Defake
5 / 5 / 0
Регистрация: 24.08.2011
Сообщений: 191
05.01.2013, 12:15  [ТС]
1) Точно! Я блин и смотрю, что почему-то не всегда, когда убираю проверку, игра вылетает. Дурак) Спасибо)
2) Трейсы говорят, что все клетки заняты, а потом вылезает ошибка "Термин не определен".
Дебажить? Эмм.. Я всегда просто компилирую программу, она мне выдает все красные ошибки и подсвечивает строку кода, где ошибка. Это оно и есть? Если да, то тут оно бесполезно, так как для программы ошибки как таковой нет. Она просто не делает то, что я хочу.

-----
Ну почему ответ находится сам после того, как спросишь у других?)) Понял в чем дело) Просто я проверяю свободна ли ячейка сбоку, но она уже заполнена "Водным ключем" и для программы уже свободной не считается)
Спасибо за ответ)
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
05.01.2013, 12:15
Помогаю со студенческими работами здесь

Алгоритм поиска пути A*
использую библиотеку SFML только для окна пытался сделать алгоритм поиска пути от одной до другой точки(левая и правая кнопка мыши) окно...

функция поиска пути
Доброго времени суток! Подскажите пожалуйста почему не работает функция?? В данный момент учусь по учебнику Выразительный JavaScript,...

Алгоритмы поиска пути
Подскажите пож, какие есть алгоритмы поиска пути на примере двухмерного массива. Например есть массив b x a x ...

Алгоритм поиска пути
Ребята, помогите разобраться с кодом. Пробую реализовать преследование привидений пакмана. При этом использую алгоритм поиска пути и...

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


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Новые блоги и статьи
Переходник USB-CAN-GPIO
Eddy_Em 20.03.2026
Достаточно давно на работе возникла необходимость в переходнике CAN-USB с гальваноразвязкой, оный и был разработан. Однако, все меня терзала совесть, что аж 48-ногий МК используется так тупо: просто. . .
Оттенки серого
Argus19 18.03.2026
Оттенки серого Нашёл в интернете 3 прекрасных модуля: Модуль класса открытия диалога открытия/ сохранения файла на Win32 API; Модуль класса быстрого перекодирования цветного изображения в оттенки. . .
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru