Модераторы: volvo877, Snowy, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Поиск пути (A*/Дейкстра) 
:(
    Опции темы
AlexP11223
Дата 30.1.2012, 13:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 52
Регистрация: 11.10.2011

Репутация: нет
Всего: нет



Пытался реализовать алгоритм A* (точнее пока алгоритм Дейкстры т.е. без эвристики) по этой  статье: http://www.policyalmanac.org/games/aStarTutorial_rus.htm

Получился вот такой код, но работает неверно (находит неправильный путь). Что не так?

Там, где пустой begin end; по идее должен был быть пункт
Цитата

Если клетка уже в открытом списке, то проверяем, не дешевле ли будет путь через эту клетку. Для сравнения используем стоимость G. Более низкая стоимость G указывает на то, что путь будет дешевле. Если это так, то меняем родителя клетки на текущую клетку и пересчитываем для нее стоимости

но вроде бы он никак не должен влиять т.к. двигаться можно только в 4 стороны?
Код

uses
    crt;

type
    TArr = array [0..11, 0..11] of integer;

    TCell = record
        x: integer;
        y: integer;
    end;

    TListCell = record
        x: integer;
        y: integer;
        G: integer;
        parent: TCell;
    end;

    TListArr = array [1..100] of TListCell;

    TList = record
        arr: TListArr;
        len: integer;
    end;

var
    i, j, minind, ind, c: integer;
    start, finish: TCell;
    current: TListCell;
    field: TArr;
    opened, closed: TList;

procedure ShowField;
var
    i, j: integer;
begin
    textcolor(15);
    for i := 0 to 11 do
    begin
        for j := 0 to 11 do
        begin
            case field[j, i] of
                99: textcolor(8);  // непроходимая
                71: textcolor(14); // проходимая
                11: textcolor(10); // старт
                21: textcolor(12); // финиш
                15: textcolor(2); // путь
                14: textcolor(5);
                16: textcolor(6);
            end;
            write(field[j, i], ' ');
        end;
        writeln;
    end;
    textcolor(15);
end;



procedure AddClosed(a: TListCell);
begin
    closed.arr[closed.len + 1] := a;
    inc(closed.len);
end;


procedure AddOpened(x, y, G: integer);
begin
    opened.arr[opened.len + 1].x := x;
    opened.arr[opened.len + 1].y := y;
    opened.arr[opened.len + 1].G := G;
    inc(opened.len);
end;

procedure DelOpened(n: integer);
var
    i: integer;
begin
    AddClosed(opened.arr[n]);
    for i := n to opened.len - 1 do
        opened.arr[i] := opened.arr[i + 1];
    dec(opened.len);
end;


procedure SetParent(var a: TListCell; parx, pary: integer);
begin
    a.parent.x := parx;
    a.parent.y := pary;
end;


function GetMin(var a: TList): integer;
var
    i, min, mini: integer;
begin
    min := MaxInt;
    mini := 0;
    for i := 1 to a.len do
        if a.arr[i].G < min then
        begin
            min := a.arr[i].G;
            mini := i;
        end;

    GetMin := mini;
end;


function FindCell(a: TList; x, y: integer): integer;
var
    i: integer;
begin
    FindCell := 0;
    for i := 1 to a.len do
        if (a.arr[i].x = x) and (a.arr[i].y = y) then
        begin
            FindCell := i;
            break;
        end;
end;


begin
    randomize;
    for i := 0 to 11 do
        for j := 0 to 11 do
            field[i, j] := 99;

    for i := 1 to 10 do
        for j := 1 to 10 do
            if random(5) mod 5 = 0 then
                field[i, j] := 99
            else field[i, j] := 71;

// координаты начальной и конечной позиций
    start.x := 5;
    start.y := 3;

    finish.x := 9;
    finish.y := 8;

    field[start.x, start.y] := 11;
    field[finish.x, finish.y] := 21;

    ShowField; 
    writeln;

    opened.len := 0;
    closed.len := 0;
    AddOpened(start.x, start.y, 0);
    SetParent(opened.arr[opened.len], -1, -1);
    current.x := start.x;
    current.y := start.y;

    repeat
        minind := GetMin(opened);
        current.x := opened.arr[minind].x;
        current.y := opened.arr[minind].y;
        current.G := opened.arr[minind].G;
    //    field[opened.arr[minind].x, opened.arr[minind].y]:=14;
        DelOpened(minind);

        if (field[current.x + 1, current.y] <> 99) then
            if (FindCell(closed, current.x + 1, current.y) <= 0) then
                if (FindCell(opened, current.x + 1, current.y) <= 0) then
                begin
                    AddOpened(current.x + 1, current.y, current.G + 10);
                    SetParent(opened.arr[opened.len], current.x, current.y);
       //             field[opened.arr[opened.len].x, opened.arr[opened.len].y]:=16;
                end
                else
                begin

                end;

        if (field[current.x - 1, current.y] <> 99) then
            if (FindCell(closed, current.x - 1, current.y) <= 0) then
                if (FindCell(opened, current.x - 1, current.y) <= 0) then
                begin
                    AddOpened(current.x - 1, current.y, current.G + 10);
                    SetParent(opened.arr[opened.len], current.x, current.y);
       //             field[opened.arr[opened.len].x, opened.arr[opened.len].y]:=16;
                end
                else
                begin

                end;

        if (field[current.x, current.y + 1] <> 99) then
            if (FindCell(closed, current.x, current.y + 1) <= 0) then
                if (FindCell(opened, current.x + 1, current.y) <= 0) then
                begin
                    AddOpened(current.x, current.y + 1, current.G + 10);
                    SetParent(opened.arr[opened.len], current.x, current.y);
        //            field[opened.arr[opened.len].x, opened.arr[opened.len].y]:=16;
                end
                else
                begin

                end;

        if (field[current.x, current.y - 1] <> 99) then
            if (FindCell(closed, current.x, current.y - 1) <= 0) then
                if (FindCell(opened, current.x, current.y - 1) <= 0) then
                begin
                    AddOpened(current.x, current.y - 1, current.G + 10);
                    SetParent(opened.arr[opened.len], current.x, current.y);
        //            field[opened.arr[opened.len].x, opened.arr[opened.len].y]:=16;
                end
                else
                begin

                end;

        if (FindCell(opened, finish.x, finish.y) > 0) then
            break;
    until opened.len = 0;

    // считаем и отмечаем обратный путь
    c:=0;
    while (current.x <> start.x) and (current.y <> start.y) do
    begin
        field[current.x, current.y] := 15;
        ind := FindCell(closed, current.x, current.y);
        current.x := closed.arr[ind].parent.x;
        current.y := closed.arr[ind].parent.y;
        inc(c);
    end;


    ShowField;
    writeln(c);
    readln;
end.



Это сообщение отредактировал(а) Omfgnoob123 - 31.1.2012, 22:12
PM WWW Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi"
THandle
Rrader
volvo877

Запрещается!

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

2. Публиковать ссылки на варез

3. Оффтопить

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, THandle, Rrader, volvo877.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Object Pascal: кроссплатформенные технологии | Следующая тема »


 




[ Время генерации скрипта: 0.0410 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.