Page 1 of 1

Разработка "автоплавалки" или автоходьбы по морю.

Posted: 25.07.2014 17:14
by drabadan
В этой теме буду спрашивать всякие штука дрюки до которых сам не додумаюсь! В конце темы, надеюсь, скрипт будет реализован! Кому тоже интересно - подключаемся без стеснений.

Концепция:
1. Пишем "путь" по которому будеть плыть\идти, стараемся там сдлеать всякие сортировочки, чтобы ближе всего плыть.
2. Преобразуем этот путь в поток команд.
3. Отрабатываем эти все команды.

Если у кого есть концепция интересней или правильней - очень прошу отписаться, чтобы ни я ни другие не опытные люди не ломали себе зубы\головы занимаясь дурней!

Вопрос к знатокам, знаете ли вы как отличить воду от другой поверхности?
Тесты инфотайлом дают результаты - возле берега тайлы 6030 до 6050, чуть дальше в море тайл 0. Точно такой же как и "пешеходной зоны".

UPD: Вопрос снимается, прибрежные тайлы будут границей в которую корабль заплывать\заходить не будет!

Re: Разработка "автоплавалки" или автоходьбы по морю.

Posted: 25.07.2014 18:53
by Vizit0r
вода может быть как статикой, так и динамикой.

Re: Разработка "автоплавалки" или автоходьбы по морю.

Posted: 25.07.2014 19:13
by drabadan
плавать\ходить можно только по статичной воде? Я за основу как не проходной беру тайл >0, что бы к берегу не подплывать.
А можно попросить выложить ходилку, которая вшита? Или GetPathArray код функции етой, или там военные тайны есть?

Re: Разработка "автоплавалки" или автоходьбы по морю.

Posted: 25.07.2014 23:18
by nah nah
занимался этой темой, не доделал, а потом переустановил винду, забыв сохранить наработки.
сразу скажу - параметры у функции такие - Х, У и ориентация корабля в пункте назначения.
ориентация легко находится по типу мачты, тайлы, на которых корабль, высчитываются от мачты. (кажется от мачты, но могу и ошибиться)
проверка на "проплываемость" - хз
алгоритм поиска пути - стрёмный и сложный
1 - решить в какую сторону искать (ведь от (0,0) к (mахХ,mахУ) всего один шаг)
2 - поиск в ширину с шагом в 30 тайлов, если не алё - уменьшить шаг, опять не алё - вернуться на предпоследнюю точку и уменьшить шаг
3 - поик пути от точки до точки - тоже стрёмный, ведь корабль может перемещаться в любом направлении, поворачивая или не поворачивая. И надо прощупывать все эти варианты перемещения.
4 - Плыть, а пока плывём - прощупываем следующий участок.
5 - + к этому проверка на разных злобных морских тварей.
Итого - 3 потока.

Re: Разработка "автоплавалки" или автоходьбы по морю.

Posted: 26.07.2014 2:20
by Vizit0r
не забывать, что корабль - это не один тайл, и соответственно места для проплывания ему надо дофига)

Re: Разработка "автоплавалки" или автоходьбы по морю.

Posted: 29.07.2014 11:39
by drabadan
чёта загруз я с алгоритмом поиска пути... Начал читать про всякие А* и волновые алгоритмы, но моска не хватает запилить это в скрипт.
По поводу, что корабль не 1 тайл - так и ограничения к проходимости ставить расстояние от мачты до трюма *2, может еще + 3 тайла для пущей верности. Вот только как обойти препятствие :)


Выложу свои текущие потуги, может подскажите вдруг я сразу "не туда" иду!
Решил писать инклюдом.
Текущие потуги!

Code: Select all

Unit SinbaDrabadan;

interface

var 
 Path : Array of TPoint;

implementation

procedure AddPointToPathArray(Point : TPoint);
begin
 SetLength(Path, Length(Path) + 1);
 Path[High(Path)].X := Point.X;
 Path[High(Path)].Y := Point.Y;
end;

function Pathfinding(Point : TPoint) : Boolean;
var
 Cell : TMapCell;
 i : Integer;
begin
 //тут должен быть умный код...
end;

function CheckTile(Point : TPoint) : Boolean;
var
 Cell : TMapCell; 
begin  
 Result := False;
 Cell := GetMapCell(Point.X, Point.Y, WorldNum);
 if (Cell.Tile = 168) or (Cell.Tile = 169) or (Cell.Tile = 170) or (Cell.Tile = 171) then
  Result := True;
end;

function CreatePath(Target : TPoint; var ResultString : String) : Boolean;
var
 Current : TPoint;
 cell : TMapCell; 
begin 
 Current.X := GetX(Self);
 Current.Y := GetY(Self);
 repeat   
   if Current.X > Target.X then    
	 Current.X := Current.X - 1;
   if Current.Y > Target.Y then
     Current.Y := Current.Y - 1;
   if Current.X < Target.X then    
	 Current.X := Current.X + 1;
   if Current.Y < Target.Y then
     Current.Y := Current.Y + 1;
   if not CheckTile(Current) then
    begin
	 AddToSystemJournal(IntToStr(Length(Path)));
	 Result := False;
	 ResultString := 'Wrong current tile!';
	 exit;
	end
   else   
    AddPointToPathArray(Current);
   cell := GetMapCell(Current.X, Current.Y, WorldNum);
   AddToSystemJournal(IntToStr(Current.X) + ' ' + IntToStr(Current.Y) + ' tile: ' + IntToStr(cell.Tile));    
 until (Current.X = Target.X) and (Current.Y = Target.Y);     
 AddToSystemJournal(IntToStr(Length(Path)));
 ResultString := 'Everything is ok!'
end;

end.

Re: Разработка "автоплавалки" или автоходьбы по морю.

Posted: 29.07.2014 16:33
by nah nah
имхо: нужно сначала забацать функции второстепенные

Code: Select all

class Ship():
    def __init__(self, tiller_man_id):
        self.id = tiller_man_id

    def getbox(self, need_dir=None):
        boxes = {0: ((-2, 3), (0, 11)), 2: ((0, 11), (-2, 3)),    # для small ship
                 4: ((-2, 3), (-10, 1)), 6: ((-10, 1), (-2, 3))}  # { dir: (x_range, y_range) }
        dir = self.getdir() if need_dir is None else need_dir
        x_range, y_range = boxes[dir] 
        box = [(GetX(self.id)+x, GetY(self.id)+y) for x in x_range for y in y_range]
        return box

    def getdir(self):
        dirs_dict = {0x3E4E: 0, 0x3E55: 2, 0x3E48: 4, 0x3E50: 6}
        return dirs_dict[GetType(self.id)]
тут объект "корабль" с полем id, в котором храниться id рулевого, с методами getbox, возвращающий массив с тайлами, которые занимает посудина, и getdir, определящим направление лодки по типу рулевого.

что конкретно не понимаешь в а*?

Re: Разработка "автоплавалки" или автоходьбы по морю.

Posted: 31.07.2014 10:25
by drabadan
nah nah wrote:имхо: нужно сначала забацать функции второстепенные

Code: Select all

class Ship():
    def __init__(self, tiller_man_id):
        self.id = tiller_man_id

    def getbox(self, need_dir=None):
        boxes = {0: ((-2, 3), (0, 11)), 2: ((0, 11), (-2, 3)),    # для small ship
                 4: ((-2, 3), (-10, 1)), 6: ((-10, 1), (-2, 3))}  # { dir: (x_range, y_range) }
        dir = self.getdir() if need_dir is None else need_dir
        x_range, y_range = boxes[dir] 
        box = [(GetX(self.id)+x, GetY(self.id)+y) for x in x_range for y in y_range]
        return box

    def getdir(self):
        dirs_dict = {0x3E4E: 0, 0x3E55: 2, 0x3E48: 4, 0x3E50: 6}
        return dirs_dict[GetType(self.id)]
тут объект "корабль" с полем id, в котором храниться id рулевого, с методами getbox, возвращающий массив с тайлами, которые занимает посудина, и getdir, определящим направление лодки по типу рулевого.

что конкретно не понимаешь в а*?
буду сидеть разбираться, с первого раза не понял все :)