Mit dem folgenden Snippet kann man selbst eine Map zeichnen und sich dann den Dijkstra-Pfad anzeigen lassen.
Man sollte darauf achten, möglichst zusammenhängende Mauern ohne diagonale "Schlupflöcher" zu zeichnen, dann ist das Ergebnis eindrucksvoller!
Linke Maustaste = Mauern setzen
Rechte Maustaste = Mauern löschen
Mittlere Maustaste = Start und Endpunkt setzen (sind identische Punkte, der weiter rechts unten liegende Punkt ist immer der Startpunkt)
ESC = Programm beenden
Wenn man zufrieden mit seiner Map ist, einfach "ENTER" drücken, und das Programm zeigt den berechneten Dijkstra-Pfad.  
 
Und so funktionierts:
Einfach alle Felder der virtuellen Map auf eine hohe Zahl (z.B. 1000) setzen, das Zielfeld bleibt auf 0. Dann durch alle Felder iterieren, für jedes Feld auf den angrenzenden Nachbarfeldern schauen (Mauern und andere blockierende Architektur überspringen), ob dessen Wert um mindestens 2 kleiner ist, als der Wert des aktuellen Feldes. Wenn ja, dann den Wert des aktuellen Feldes auf [angrenzender Wert+1] setzen. Dies in einer Schleife wiederholen, solange bis nichts geändert wurde. Das Ergebnis ist eine 
Heightmap, wo man vom Startpunkt aus bis zum Ziel "herunterrollt".
Code: Alles auswählen
EnableExplicit
Declare loop()
Declare createMap()
Declare processInput()
Declare calculateDijkstra()
Declare drawMap(dijkstraReady)
#xRes = 800
#yRes = 600
#xMax = 19
#yMax = 14
#tileSize = 40
Global screen
Global Dim worldMap(#xMax,#yMax)
Global Dim dijkstraMap(#xMax,#yMax)
If InitSprite()
   screen = OpenWindow(#PB_Any,0,0,#xRes,#yRes,"Dijkstra Maps - (press ESC to quit)",#PB_Window_ScreenCentered)
   If OpenWindowedScreen(WindowID(screen),0,0,#xRes,#yRes)
      If InitKeyboard()
         If InitMouse()
            createMap()
            loop()
            End
         EndIf
      EndIf
   EndIf
EndIf
Debug "Something is rotten in the state of Denmark."
Procedure loop()
	Protected dijkstraReady	
	
	Repeat
		ExamineKeyboard()
		ExamineMouse()
		If Not dijkstraReady
			dijkstraReady = processInput()
		EndIf
		drawMap(dijkstraReady)
		FlipBuffers()
		WaitWindowEvent(1)
	Until KeyboardPushed(#PB_Key_Escape)
EndProcedure
Procedure createMap()
	Protected x, y
	
	For x = 0 To #xMax
		For y = 0 To #yMax
			If Not(x = 0 Or y = 0 Or x = #xMax Or y = #yMax)
				worldMap(x,y) = 1
			EndIf
		Next
	Next
EndProcedure
Procedure processInput()
	Protected button, x, y
	Dim mousehit(3)
	mouseHit(1) = MouseButton(#PB_MouseButton_Left)
	mouseHit(2) = MouseButton(#PB_MouseButton_Right)
	mouseHit(3) = MouseButton(#PB_MouseButton_Middle)
	Static count
	
	x = MouseX()/#tileSize
	y = MouseY()/#tileSize
	If x = 0 Or y = 0 Or x =#xMax Or y = #yMax
		ProcedureReturn 0
	EndIf
	
	For button = 1 To 2
		If mouseHit(button)
			If worldMap(x,y) = 2 And count > 0 
				count -1
			EndIf
			worldMap(x,y) = (button-1)   ;linke Maustaste malt Mauern, rechte Maustaste löscht diese wieder
		EndIf
	Next
	If mousehit(3) And count < 2 And worldMap(x,y) <> 2	;Start/Endpunkte setzen (maximal 2 erlaubt)
		count +1
		worldMap(x,y) = 2
	EndIf
	
	If KeyboardReleased(#PB_Key_Return)
		If count < 2
			Debug "Start/Target-Point is missing!"
			ProcedureReturn 0
		Else
			calculateDijkstra()
			ProcedureReturn 1
		EndIf
	EndIf
EndProcedure
Procedure calculateDijkstra()
	Protected x, y
	Protected xDir, yDir
	Protected noChange
	Protected count
	
	For x = 1 To #xMax-1
		For y = 1 To #yMax-1
			If worldMap(x,y) = 1
				dijkstraMap(x,y) = 1000			;irgendein hoher Wert
			EndIf
			If worldMap(x,y) = 2
				count +1
				If count = 2					;den zweiten Punkt als Startpunkt deklarieren
					dijkstraMap(x,y) = 1000
				EndIf
			EndIf
		Next
	Next
	
	Repeat
		noChange = 1
		For x = 1 To #xMax-1
			For y = 1 To #yMax-1
				
				If worldMap(x,y) = 1
					
					For xDir = -1 To 1
						For yDir = -1 To 1
							
							If dijkstraMap(x+xDir,y+yDir) < (dijkstraMap(x,y) -1) And worldMap(x+xDir,y+yDir) > 0	;wenn angrenzender Wert um mindestens 2 kleiner ...
								dijkstraMap(x,y) = dijkstraMap(x+xDir,y+yDir) +1									;... aktuelles Feld auf [angrenzender Wert+1] setzen
								noChange = 0
							EndIf
						Next
					Next
				EndIf
			Next
		Next
	Until noChange
EndProcedure
Procedure drawMap(dijkstraReady)
	Protected x, y
	
	ClearScreen(RGB(255,255,255))
	
	If StartDrawing(ScreenOutput())
		DrawingMode(#PB_2DDrawing_Default)
		
		For x = 0 To #xMax
			For y = 0 To #yMax
				Select worldMap(x,y)
					Case 0
						Box(x*#tileSize,y*#tileSize,#tileSize,#tileSize,RGB(0,0,0))
					Case 1
						If dijkstraReady
							DrawText((x*#tileSize)+(#tileSize/2),(y*#tileSize)+(#tileSize/2),Str(dijkstraMap(x,y)),RGB(0,0,0),RGB(255,255,255))
						EndIf
					Case 2
						Box(x*#tileSize,y*#tileSize,#tileSize,#tileSize,RGB(0,255,0))
				EndSelect
			Next
		Next
		
		Circle(MouseX(),MouseY(),5,RGB(255,0,0))
		StopDrawing()
	EndIf
EndProcedure