Ich hab mal einen relativ alten Code rausgesucht, den ich einfach mal aus Spaß am proggen geschieben habe.
Code: Alles auswählen
Global mapwidth,mapheight
mapwidth = 40
mapheight = 30
Structure node
x.l
y.l
last.l
ber.l
EndStructure
Dim Map.b(mapwidth-1,mapheight-1)
Dim smap.l(mapwidth-1,mapheight-1) ;Nur für das Beispiel wichtig, kann auch weggelassen werden
NewList node.node()
NewList path.POINT()
Procedure D_Pathfinding4(*start.POINT,*target.POINT) ;gibt die Anzahl der Schritte zurück
If CompareMemory(*start,*target,SizeOf(POINT)):ProcedureReturn 0:EndIf
Dim smap.l(mapwidth-1,mapheight-1)
ClearList(node())
AddElement(node()):node()\x = *target\x:node()\y = *target\y
smap(*target\x,*target\y) = 1
Repeat
noconnection = 1
cnt = 0
ForEach node()
If node()\ber = 0
cnt + 1
noconnection = 0
x = node()\x
y = node()\y
node_p = @node()
node()\ber = 1
If x = *start\x And y = *start\y:finish = 1:Break:EndIf
If x+1 < mapwidth
If smap(x+1,y) = 0
If Map(x+1,y)
smap(x+1,y) = 1
Else
AddElement(node())
node()\x = x+1
node()\y = y
node()\last = node_p
smap(x+1,y) = 1
EndIf
EndIf
EndIf
If x-1 >= 0
If smap(x-1,y) = 0
If Map(x-1,y)
smap(x-1,y) = 1
Else
AddElement(node())
node()\x = x-1
node()\y = y
node()\last = node_p
smap(x-1,y) = 1
EndIf
EndIf
EndIf
If y+1 < mapheight
If smap(x,y+1) = 0
If Map(x,y+1)
smap(x,y+1) = 1
Else
AddElement(node())
node()\x = x
node()\y = y+1
node()\last = node_p
smap(x,y+1) = 1
EndIf
EndIf
EndIf
If y-1 >= 0
If smap(x,y-1) = 0
If Map(x,y-1)
smap(x,y-1) = 1
Else
AddElement(node())
node()\x = x
node()\y = y-1
node()\last = node_p
smap(x,y-1) = 1
EndIf
EndIf
EndIf
EndIf
Next
Debug cnt
Until finish Or noconnection
If finish
ClearList(path())
Length = 0
Repeat
Length + 1
AddElement(path())
path()\x = node()\x
path()\y = node()\y
ChangeCurrentElement(node(),node()\last)
Until node()\last = 0
ProcedureReturn Length
Else
ProcedureReturn 0
EndIf
EndProcedure
Procedure D_Pathfinding8(*start.POINT,*target.POINT) ;gibt die Anzahl der Schritte zurück
If CompareMemory(*start,*target,SizeOf(POINT)):ProcedureReturn 0:EndIf
Dim smap.l(mapwidth-1,mapheight-1)
ClearList(node())
AddElement(node()):node()\x = *target\x:node()\y = *target\y
smap(*target\x,*target\y) = 1
Repeat
noconnection = 1
cnt = 0
ForEach node()
If node()\ber = 0
cnt + 1
noconnection = 0
x = node()\x
y = node()\y
node_p = @node()
node()\ber = 1
If x = *start\x And y = *start\y:finish = 1:Break:EndIf
If x+1 < mapwidth
If smap(x+1,y) = 0
If Map(x+1,y)
smap(x+1,y) = 1
Else
AddElement(node())
node()\x = x+1
node()\y = y
node()\last = node_p
smap(x+1,y) = 1
EndIf
EndIf
EndIf
If x-1 >= 0
If smap(x-1,y) = 0
If Map(x-1,y)
smap(x-1,y) = 1
Else
AddElement(node())
node()\x = x-1
node()\y = y
node()\last = node_p
smap(x-1,y) = 1
EndIf
EndIf
EndIf
If y+1 < mapheight
If smap(x,y+1) = 0
If Map(x,y+1)
smap(x,y+1) = 1
Else
AddElement(node())
node()\x = x
node()\y = y+1
node()\last = node_p
smap(x,y+1) = 1
EndIf
EndIf
If x-1 >= 0
If smap(x-1,y+1) = 0
If Map(x-1,y+1)
smap(x-1,y+1) = 1
Else
AddElement(node())
node()\x = x-1
node()\y = y+1
node()\last = node_p
smap(x-1,y+1) = 1
EndIf
EndIf
EndIf
If x+1 < mapwidth
If smap(x+1,y+1) = 0
If Map(x+1,y+1)
smap(x+1,y+1) = 1
Else
AddElement(node())
node()\x = x+1
node()\y = y+1
node()\last = node_p
smap(x+1,y+1) = 1
EndIf
EndIf
EndIf
EndIf
If y-1 >= 0
If smap(x,y-1) = 0
If Map(x,y-1)
smap(x,y-1) = 1
Else
AddElement(node())
node()\x = x
node()\y = y-1
node()\last = node_p
smap(x,y-1) = 1
EndIf
EndIf
If x-1 >= 0
If smap(x-1,y-1) = 0
If Map(x-1,y-1)
smap(x-1,y-1) = 1
Else
AddElement(node())
node()\x = x-1
node()\y = y-1
node()\last = node_p
smap(x-1,y-1) = 1
EndIf
EndIf
EndIf
If x+1 < mapwidth
If smap(x+1,y-1) = 0
If Map(x+1,y-1)
smap(x+1,y-1) = 1
Else
AddElement(node())
node()\x = x+1
node()\y = y-1
node()\last = node_p
smap(x+1,y-1) = 1
EndIf
EndIf
EndIf
EndIf
EndIf
Next
Debug cnt
Until finish Or noconnection
If finish
ClearList(path())
Length = 0
Repeat
Length + 1
AddElement(path())
path()\x = node()\x
path()\y = node()\y
ChangeCurrentElement(node(),node()\last)
Until node()\last = 0
ProcedureReturn Length
Else
ProcedureReturn 0
EndIf
EndProcedure
Restore Map
For y = 1 To mapheight
For x = 1 To mapwidth
;Read Map(x-1,y-1)
Map(x-1,y-1) = Random(1)
Next
Next
_GT_DevCaps.TIMECAPS
SetPriorityClass_(GetCurrentProcess_(),#HIGH_PRIORITY_CLASS)
timeGetDevCaps_(_GT_DevCaps,SizeOf(TIMECAPS))
timeBeginPeriod_(_GT_DevCaps\wPeriodMin)
InitSprite()
OpenWindowedScreen(OpenWindow(0,0,0,mapwidth*20,mapheight*20+20,#PB_Window_ScreenCentered|#PB_Window_SystemMenu,"Pathfinding"),0,0,mapwidth*20,mapheight*20,0,0,0)
CreateGadgetList(WindowID())
ButtonGadget(0,0,mapheight*20,mapwidth*10,20,"DRÜCKEN ;) (4Wege)")
ButtonGadget(1,mapwidth*10,mapheight*20,mapwidth*10,20,"DRÜCKEN ;) (8Wege)")
me.POINT
me\x = Random(mapwidth-1);2
me\y = Random(mapheight-1);2
Map(me\x,me\y) = 0
enemy.POINT
enemy\x = Random(mapwidth-1);37
enemy\y = Random(mapheight-1);28
Map(enemy\x,enemy\y) = 0
Repeat
Select WindowEvent()
Case #PB_Event_Gadget
Select EventGadgetID()
Case 0
me\x = Random(mapwidth-1);2
me\y = Random(mapheight-1);2
Map(me\x,me\y) = 0
enemy\x = Random(mapwidth-1);37
enemy\y = Random(mapheight-1);28
Map(enemy\x,enemy\y) = 0
Repeat
For y = 1 To mapheight
For x = 1 To mapwidth
;Read Map(x-1,y-1)
Map(x-1,y-1) = Random(4)&1
Next
Next
StartTime = timegettime_()
r = D_Pathfinding4(@me,@enemy)
SetWindowTitle(0,"Pathfinding4 ("+Str(timegettime_()-StartTime)+" ms)")
Until r
Case 1
me\x = Random(mapwidth-1);2
me\y = Random(mapheight-1);2
Map(me\x,me\y) = 0
enemy\x = Random(mapwidth-1);37
enemy\y = Random(mapheight-1);28
Map(enemy\x,enemy\y) = 0
Repeat
For y = 1 To mapheight
For x = 1 To mapwidth
;Read Map(x-1,y-1)
Map(x-1,y-1) = Random(4)&1
Next
Next
StartTime = timegettime_()
r = D_Pathfinding8(@me,@enemy)
SetWindowTitle(0,"Pathfinding8 ("+Str(timegettime_()-StartTime)+" ms)")
Until r
EndSelect
Case #PB_Event_CloseWindow
quit = 1
Case 0
Delay(100)
EndSelect
StartDrawing(ScreenOutput())
For x = 0 To mapwidth-1
For y = 0 To mapheight-1
Box(x*20,y*20,20,20,Map(x,y)*255+(smap(x,y)*155)<<8)
Next
Next
ForEach path()
Box(path()\x*20,path()\y*20,20,20,255<<8)
Next
Box(me\x*20,me\y*20,20,20,255<<16)
Box(enemy\x*20,enemy\y*20,20,20,255<<16)
StopDrawing()
FlipBuffers()
Until quit = 1
timeEndPeriod_(_GT_DevCaps\wPeriodMin)
DataSection
Map:
Data.b 1,1,1,1,1,1,1,1,1,1
Data.b 1,0,1,1,0,0,1,0,0,1
Data.b 1,0,0,0,0,0,1,0,0,1
Data.b 1,0,0,0,1,0,1,0,0,1
Data.b 1,0,0,0,1,0,1,1,0,1
Data.b 1,0,0,0,1,0,0,1,0,1
Data.b 1,0,0,0,1,0,0,0,0,1
Data.b 1,0,0,0,1,0,1,0,0,1
Data.b 1,0,0,0,1,0,0,0,0,1
Data.b 1,1,1,1,1,1,1,1,1,1
EndDataSection
Kurze Erklärung: Wenn man auf den 4 Wege-Knopf drückt wird immer eine Verbindung nach rechts,oben,links und unten gesucht, bei 8 Wege auch diagonal. Im Titel steht auch wie lange er für die Wegsuche gebraucht hat. Das grüne ist der Weg (hättet ihr nicht gedacht oder? ^^), das hellgrüne Feld darum ist das Gebiet, welches er abgesucht hat und der rest ist entweder schwarz (frei) oder rot (nich frei, wand oder so..)
Das Programm erstellt übrigens so lange eine neue Karte bis ein Weg gefunden werden konnte. Wird kein Weg gefunden, oder der Startpunkt ist gleich Endpunkt geben die Proceduren 0 zurück, andernfalls die Anzahl der Schritte zwischen den Punkten.
Hoffe dir hilft der Code, konnte ihn selber noch nicht gebrauchen.