Mam problem, przy wywoływaniu funkcji dostaję ten błąd, lecz kompletnie nie wiem z jakiego powodu :/ Wydaje mi się że wszystko jest okej :/
Miejsce wywoływania jej:
procedure TForm1.Button2Click(Sender: TObject);
var
tmp1, tmp2:integer;
j:LongInt;
WynikSzukania:Boolean;
CzasPoczatkowy, CzasKoncowy: Integer;
Wejscie, Wyjscie:TPoint;
begin
Randomize;
Wejscie.X := 0;
Wejscie.Y := 0;
Wyjscie.Y := Wielkosc-1;
Wyjscie.X := Wielkosc-1;
CzasPoczatkowy := GetTickCount;
Droga := nil;
WynikSzukania:=NajkrotszaDroga(Swiat, Wejscie, Wyjscie, Wielkosc, Wielkosc, Droga);
if WynikSzukania then
begin
MessageBox(0, 'Udalo sie!', 'Sukces', 0);
CzasKoncowy := GetTickCount;
Label4.Caption := inttostr(CzasKoncowy-CzasPoczatkowy) + ' ms';
end;
form1.PaintBox1.Canvas.Brush.Color := clgreen;
if (Droga^[0].wiersz = Wielkosc-1) and (Droga^[0].kolumna = Wielkosc-1) then
begin
for j:=0 to high(Droga^) do
form1.PaintBox1.Canvas.Rectangle(Droga^[j].wiersz*5,Droga^[j].kolumna*5,Droga^[j].wiersz*5+5, Droga^[j].kolumna*5+5);
end;
end;
Kod funkcji:
function NajkrotszaDroga(const ASwiat:TSwiat;
const AStart,ACel:TPoint;
const AKolumny,AWiersze:integer;
var ADroga:PDroga):boolean;
const // k,w k,w k,w
kierunek:array[0..7,0..1]of integer=((0,-1),(1,0),(0,1),(-1,0),(-1,-1),(1,-1),(1,1),(-1,1));
var
fWynik,
fMeta:boolean;
row,
col,
Zalazek,
j,k,L:LongInt;
rozmiarBufora:LongInt;
tabKolejka :array of TWspolrzedna;
tabBufor :array of TWspolrzedna;
_Cel:TPoint;
ileOdwiedzin:array of array of LongInt;
tabodwiedzin:array of array of boolean;
odleglosc:extended;
zlozonosc,
i,WxK,
MaxIndeks:int64;
begin
odleglosc:=High(dWord);
MaxIndeks:=0;
zlozonosc:=0;
fWynik:=true;
fMeta:=false;
setLength(ileOdwiedzin,AWiersze,AKolumny);
setLength(tabodwiedzin,AWiersze,AKolumny);
//Utworz rozmiar pocztakowy tablicy kolejka
setLength(tabKolejka,1);
//zapamietaj pozycje startu
// _start:=Astart;
tabKolejka[0].wiersz :=Astart.y;
tabKolejka[0].kolumna:=Astart.x;
tabOdwiedzin[tabKolejka[0].wiersz,tabKolejka[0].kolumna]:=true;
//romiar poczatkowy tablicy bufora
rozmiarBufora:=1;
_Cel:=Acel;//w y jest wiersz w x jest kolumna startu
WxK:=AWiersze*AKolumny-1;
while (not fMeta) do
begin
//Kolejka
for j:=0 to high(tabKolejka)do
begin
//pętal dla 4 lub 8 kierunków szukania drogi
for k:=0 to high(kierunek) do
begin
col:=tabKolejka[j].kolumna+kierunek[k,0];
row:=tabKolejka[j].wiersz+kierunek[k,1];
if (col<0)or(col>=AKolumny)or(row<0)or(row>=AWiersze)then continue;
if(ASwiat[row,col]=0)
then
begin
if tabOdwiedzin[row,col]=false then begin
ileOdwiedzin[row,col]:=ileOdwiedzin[tabKolejka[j].wiersz,tabKolejka[j].kolumna]+1;
tabOdwiedzin[row,col]:=true;
setlength(tabBufor,rozmiarBufora);
tabBufor[rozmiarBufora-1].wiersz:=row;
tabBufor[rozmiarBufora-1].kolumna:=col;
inc(rozmiarBufora);
//if (odleglosc>=Abs(WagaMety-col-row*AKolumny))then
if (odleglosc>=sqrt(sqr(_Cel.y-row)+sqr(_Cel.x-col))) then
begin
odleglosc:=sqrt(sqr(_Cel.y-row)+sqr(_Cel.x-col));
MaxIndeks:=col+row*AKolumny;
end;
if (col=_Cel.x)and(row=_Cel.y)then begin
fMeta:=true;
break;
end;
end;
end;
end;//koniec petli dla kierunkow
end;//koniec petli dla biezacej kolejki
//zniszcz koljekę
tabKolejka:=nil;
setLength(tabKolejka,high(tabBufor)+1);
//zapamietaj nowa kolejkę
for k:=0 to high(tabBufor)do tabKolejka[k]:=tabBufor[k];
//zniszcz bufor
tabBufor:=nil;
rozmiarBufora:=1;
inc(zlozonosc);
if zlozonosc>WxK then
begin
//nie znaleziono drogi, wiec podejdz najblizej do celu
_Cel.Y:=Maxindeks div AKolumny;
_Cel.X:=Maxindeks-_Cel.Y*Akolumny;
fWynik:=false;
fMeta:=true;
break;
end;
end;{koniec while}
//***********************************************
Zalazek:=ileOdwiedzin[_Cel.y,_Cel.x];
rozmiarBufora:=1;
Setlength(tabKolejka,rozmiarBufora);
Setlength(ADroga^,rozmiarBufora);
TabKolejka[0].wiersz:=_Cel.y;
TabKolejka[0].kolumna:=_Cel.x;
ADroga^[0].wiersz:=TabKolejka[0].wiersz;
ADroga^[0].kolumna:=TabKolejka[0].kolumna;
fmeta:=false;
i:=0;
while i<zlozonosc do
begin
for k:=0 to high(kierunek) do
begin
col:=TabKolejka[high(TabKolejka)].kolumna+kierunek[k,0];
row:=TabKolejka[high(TabKolejka)].wiersz+kierunek[k,1];
if (col<0)or(col>=AKolumny)or(row<0)or(row>=AWiersze)then continue;
if(ASwiat[row,col]=0)
then begin
if ileOdwiedzin[row,col]=Zalazek-1then
begin
Zalazek:=ileOdwiedzin[row,col];
inc(rozmiarBufora);
Setlength(tabKolejka,rozmiarBufora);
TabKolejka[high(TabKolejka)].kolumna:=col;
TabKolejka[high(TabKolejka)].wiersz:=row;
Setlength(ADroga^,rozmiarBufora);
ADroga^[high(TabKolejka)].wiersz :=TabKolejka[high(TabKolejka)].wiersz;
ADroga^[high(TabKolejka)].kolumna:=TabKolejka[high(TabKolejka)].kolumna;
if(col=Astart.x)and(row=Astart.y)then i:=zlozonosc;//fMeta:=true;
break;
end;//Koniec szukania zalazka
end;//konec testu komorek tablicy
end;//koniec kierunku
//
inc(i);
end;//koniec while
result:=fWynik;
end;
Jest to algorytm napisany przez Oksala, natomiast w momencie Setlength(ADroga^,rozmiarBufora); dostaję wyjątek EAccessViolation, nie wiem z jakiego powodu, może ktoś coś poradzić?