Ich habe vor einem Jahr etwas über Pathfinding in BB gelesen und fast aller wieder vergessen
Aber das was ich wusste hat noch gereicht, hier meine Funktion um zu gucken ob es einen Weg gibt (Man kann in die Funktion auch noch reinbauen, zu speichern wolang er geht, dann kann man den Weg abrufen)
UDF:
Spoiler anzeigen
;-3 => Punkt außerhalb der Karte
;-2 => Timeout
;-1 => Arrayerror
; 0 => kein Weg
; 1 => Weg
Func _isPath($feld,$p1,$p2,$timeout=1000,$wand=1);Welche MS-TIMEOUT-ZAHL? -> 1000 / old 5000
;Author: TheShadowAE
If Not IsArray($feld) or Not IsArray($p1) Or Not IsArray($p2) Then Return SetError(1,0,-1) ;ob alles Arrays sind
If UBound($feld,0)<2 Then Return SetError(2,0,-1);ob $feld 2+ D ist (3D wird nur 2D benutzt)
Local $width=UBound($feld,1)-1
Local $height=UBound($feld,2)-1
If $p1[0]<0 or $p1[1]<0 Or $p1[0]>$width Or $p1[1]>$height Then Return -3;Punkte außerhalb Karte?
If $p2[0]<0 or $p2[1]<0 Or $p2[0]>$width Or $p2[1]>$height Then Return -3;Punkte außerhalb Karte?
If $feld[$p2[0]][$p2[1]]=$wand Or $feld[$p1[0]][$p1[1]]=$wand Then Return 0;Punkt ist Wand?
Local $now[3]=[$p1[0],$p1[1],(Abs(($p2[0]-$p1[0])+($p2[1]-$p1[1])))]
Local $old[3]=[$now[0],$now[1],$now[2]]
Local $weg[4][3]
Local $nweg=0
Local $timer=TimerInit()
If $now[0]=$p2[0] And $now[1]=$p2[1] Then Return 1;Sind beide Punkte gleich?
While 1
$isnull=1
For $x=0 to $width
For $y=0 to $height
If $feld[$x][$y]<>$wand Then
$isnull=0
ExitLoop 2
EndIf
Next
Next
If $isnull=1 Then Return 0 ;Ist alles Wand?
$endit=1
If $now[1]-1>=0 Then
If $feld[$now[0]][$now[1]-1]<>$wand Then $endit=0
EndIf
If $now[0]+1<=$width Then
If $feld[$now[0]+1][$now[1]]<>$wand Then $endit=0
EndIf
If $now[1]+1<=$height Then
If $feld[$now[0]][$now[1]+1]<>$wand Then $endit=0
EndIf
If $now[0]-1>=0 Then
If $feld[$now[0]-1][$now[1]]<>$wand Then $endit=0
EndIf
If $endit=1 Then
;~ ConsoleWrite("Debug-Ende"&@CRLF);Debug
Return 0
EndIf
$old[0]=$now[0]
$old[1]=$now[1]
$old[2]=$now[2]
$weg[0][0]=$now[0]
$weg[0][1]=$now[1]-1
$weg[0][2]=Abs(($p2[0]-$weg[0][0])+($p2[1]-$weg[0][1]))
If $weg[0][1]<>Abs($weg[0][1]) Then
$weg[0][2]=$width+$height+3
$weg[0][1]=0
EndIf
$weg[1][0]=$now[0]+1
$weg[1][1]=$now[1]
$weg[1][2]=Abs(($p2[0]-$weg[1][0])+($p2[1]-$weg[1][1]))
If $weg[1][0]>$width Then
$weg[1][2]=$width+$height+3
$weg[1][0]=$width
EndIf
$weg[2][0]=$now[0]
$weg[2][1]=$now[1]+1
$weg[2][2]=Abs(($p2[0]-$weg[2][0])+($p2[1]-$weg[2][1]))
If $weg[2][1]>$height Then
$weg[2][2]=$width+$height+3
$weg[2][1]=$height
EndIf
$weg[3][0]=$now[0]-1
$weg[3][1]=$now[1]
$weg[3][2]=Abs(($p2[0]-$weg[3][0])+($p2[1]-$weg[3][1]))
If $weg[3][0]<>Abs($weg[3][0]) Then
$weg[3][2]=$width+$height+3
$weg[3][0]=0
EndIf
For $x=0 to 3
If $feld[$weg[$x][0]][$weg[$x][1]]=$wand Then $weg[$x][2]=$width+$height+3
Next
If $weg[0][2]<=$weg[1][2] Then ;'<=' da es egal ist wenn der Weg gleich lang ist
$nweg=0
Else
$nweg=1
EndIf
If $weg[$nweg][2]<=$weg[2][2] Then
$nweg=$nweg
Else
$nweg=2
EndIf
If $weg[$nweg][2]<=$weg[3][2] Then
$nweg=$nweg
Else
$nweg=3
EndIf
If $weg[$nweg][2]>=$now[2] Then
$feld[$now[0]][$now[1]]=$wand
$now[0]=$old[0]
$now[1]=$old[1]
$now[2]=$old[2]
EndIf
If $weg[$nweg][2]<>$width+$height+3 Then
$now[0]=$weg[$nweg][0]
$now[1]=$weg[$nweg][1]
$now[2]=$weg[$nweg][2]
EndIf
;~ ConsoleWrite("Debug: "&$now[0]&" "&$now[1]&" "&$now[2]&@CRLF);Debug
;~ ConsoleWrite("Feld: "&$feld[0][0]&" "&$feld[1][0]&" "&$feld[2][0]&@CRLF);Debug für das Beispiel
;~ ConsoleWrite("Feld: "&$feld[0][1]&" "&$feld[1][1]&" "&$feld[2][1]&@CRLF);Debug für das Beispiel
;~ ConsoleWrite("Feld: "&$feld[0][2]&" "&$feld[1][2]&" "&$feld[2][2]&@CRLF);Debug für das Beispiel
If $now[0]=$p2[0] And $now[1]=$p2[1] Then Return 1 ;Am Ziel?
If TimerDiff($timer)>=$timeout Then Return -2 ;Timeout?
WEnd
EndFunc
Beispiel:
Spoiler anzeigen
;#Test
Dim $feld[3][3]=[[0,0,0],[0,0,0],[0,0,0]]
Dim $von[2]=[0,0]
Dim $zu[2]=[4,4]
$x=_isPath($feld,$von,$zu)
MsgBox(0,"",$x)
;#
Gerne Kritik, Bugs oder sonstiges melden