The code:
Code: Select all
;From https://autohotkey.com/boards/viewtopic.php?p=185714&sid=8cab78acf6a567c2a660576b839e52ca#p185714
Grid = ; Easier to create with monospace text
(Join`n
**********
* A *
* * *
******* *
* *
* * ****
* ** *
* ** *
** Z* *
* *
**********
)
; Create Array from Grid data
Closed := {}
for Y, Line in StrSplit(Grid, "`n")
for X, val in StrSplit(Line)
if (val = "*")
Closed[X,Y] := true
else if (val = "A")
X1 := X, Y1 := Y
else if (val = "Z")
X2 := X, Y2 := Y
; Find Path
Path := Astar_Grid(X1, Y1, X2, Y2, Closed)
; Display Grid and Path
Display := ""
for Y, Line in StrSplit(Grid, "`n")
for X, val in StrSplit(Line "`n")
{
for index, Cell in Path
if (Cell.X = X and Cell.Y = Y and index > 1 and index < Path.MaxIndex())
{
Display .= "+"
continue 2
}
Display .= val
}
Gui, font, s16, courier new
Gui, Add, Text,, % Grid "`n`n" Display
Gui, Show
; Astar_Grid and supporting functions
Astar_Grid(X1, Y1, X2, Y2, Closed := "")
{
if !IsObject(Closed)
Closed := {}
Open := {}, From := {}, G := {}, F := {}
Open[X1, Y1] := true, G[X1, Y1] := 0
F[X1, Y1] := Estimate_F(X1, Y1, X2, Y2)
while Open.MaxIndex()
{
Lowest_F_Set(X, Y, F, Open)
if (X = X2 and Y = Y2)
return From_Path(From, X, Y)
Open[X].Delete(Y)
if !Open[X].MaxIndex()
Open.Delete(X)
Closed[X, Y] := true
for index, Near in [{"X": X, "Y": Y-1},{"X": X-1, "Y": Y},{"X": X+1, "Y": Y},{"X": X, "Y": Y+1}]
{
if (Closed[Near.X, Near.Y] = true)
continue
Open[Near.X, Near.Y] := true, tG := G[X, Y] + 1
if (IsObject(G[Near.X, Near.Y]) and tG >= G[Near.X, Near.Y])
continue
From[Near.X, Near.Y] := {"X": X, "Y": Y}
G[Near.X, Near.Y] := tG
F[Near.X, Near.Y] := G[Near.X, Near.Y] + Estimate_F(Near.X, Near.Y, X2, Y2)
}
}
}
Estimate_F(X1, Y1, X2, Y2)
{
return Abs(X1-X2) + Abs(Y1-Y2)
}
Lowest_F_Set(ByRef X, ByRef Y, ByRef F, ByRef Set)
{
l := 0x7FFFFFFF
for tX , element in Set
for tY, val in element
if (F[tX, tY] < l)
l := F[tX, tY], X := tX, Y := tY
return l
}
From_Path(From, X, Y)
{
Path := {}, XY := {"X": X, "Y": Y}
Path.InsertAt(1, XY)
while (IsObject(From[XY.X, XY.Y]))
Path.InsertAt(1, XY:= From[XY.X, XY.Y])
return Path
}
1_ Change the mapdata. My mapdata is a 400x400 matrix, i mean 400x and 400y, this means it has 160.000 characters (400 per line). When i paste this data on the script it says "Continuation Section Too Long". So i'm lost with what can i do.
2_ My mapdata has "0" for walkable cell, "1" and "5" for non walkable (1 let's you throw arrows throught it and the other is a wall / map limit), so i need it to "choose" that cell when it's a "0".
3_ Instead of displaying it on screen i want it to display the coordinates, i mean something like: "315,10 -> 316,10 -> 316,11 -> 317,11".
What i tried:
1_ I added a "," between each value in the mapdata and wrote this to declare it in 400 arrays of 400 values each:
Code: Select all
asdf=400
tooltip, Loading MapData
loop, 400
{
FileReadLine, aux, mapdata.txt, %asdf%
mapy%a_index%:= StrSplit(aux, ",", " `t" "]" "[")
asdf--
}
tooltip, Map Loaded!
The problem comes when i try to change the A* code to use this instead of the Grid declared because it gets a little too slow.
2_ From what i understand:
I have to declare Closed[x,y] := true for each cell that is not walkable so i changed the code a little to look like this:
Code: Select all
tooltip, Reading MapData
FileRead, Grid, mapdata.txt
tooltip, Creating Array
; Create Array from Grid data
Closed := {}
for Y, Line in StrSplit(Grid, "`n")
for X, val in StrSplit(Line)
if (val = "1") or (val = "5")
Closed[X,Y] := true
else if (val = "A")
X1 := X, Y1 := Y
else if (val = "Z")
X2 := X, Y2 := Y
tooltip, Finding path
; Find Path
Path := Astar_Grid(X1, Y1, X2, Y2, Closed)
tooltip, There u go
; Display Grid and Path
Display := ""
for Y, Line in StrSplit(Grid, "`n")
for X, val in StrSplit(Line "`n")
{
for index, Cell in Path
if (Cell.X = X and Cell.Y = Y and index > 1 and index < Path.MaxIndex())
{
Display .= "+"
continue 2
}
Display .= val
}
Gui, font, s2, courier new
Gui, Add, Text,, % Display
Gui, Show
3_ Here is when the real problem begins:
Code: Select all
for Y, Line in StrSplit(Grid, "`n")
{
for X, val in StrSplit(Line "`n")
{
for index, Cell in Path ;
{
if (Cell.X = X and Cell.Y = Y and index > 1 and index < Path.MaxIndex())
{
Display .= "+"
continue 2
}
Display .= val
}
}
}
The main problem is that i don't understand what is Cell.X and why is it compared to X, same for Cell.Y and same for Path.MaxIndex.
I understand what happens when that if is true, it means that the cell is walkable, but still i don't get what is comparing there.
I think that by understanding that part i can change it to suit my needs.
Thank you for your time.