A* Pfadfindung

  • Moin Leute.

    Ich hatte versucht enen kleines Programm für die Pfadfindung zu Proggen ansatztechnisch läuft das ganze auch nur müssen da noch Fehler drin sein.
    Vllt hat ja einer Lust sich die Zeit zu nehmen und mal düber zu schauen.

    Spoiler anzeigen
    [autoit]

    #include <GDIPlus.au3>
    #include <Array.au3>

    [/autoit] [autoit][/autoit] [autoit]

    HotKeySet("s","start")

    [/autoit] [autoit][/autoit] [autoit]

    Enum $GUIMain, $hGUIMain, $GUIMainWidth, $GUIMainHeight, $GUIAnzahl
    Enum $hGraphic, $hBitmap, $hBuffer, $hPen, $hBrushRectStart, $hBrushRectEnd ,$hBrushRectAktiv, $hBrushRectDeaktiv, $hBrushRedraw, $hBrushRectWeg, $GDIAnzahl
    Global $aGUI[$GUIAnzahl], $aGDI[$GDIAnzahl], $aRecs[1][4]
    Global $GitterWidth = 50
    Global $aRectsClosed[1][5], $aRectsOpend[1][6] = [[111111,1111111,1111111,1111111,1111111,1111111]], $aAktuellRect[1][4], $aStartRect[1][4], $aEndRect[1][4]

    [/autoit] [autoit][/autoit] [autoit]

    GUI()
    Init_GDI()
    Init_Gitter_Rec()
    Draw_Gitternetz()

    [/autoit] [autoit][/autoit] [autoit]

    Set_StartRect(1)
    Set_EndRect(UBound($aRecs)-1)

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    ;$aCursorInfo = GUIGetCursorInfo($aGUI[$hGUIMain])
    ;If IsArray($aCursorInfo) Then ToolTip($aCursorInfo[4])
    Sleep(10)
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func start()
    For $i = 0 To 3
    $aAktuellRect[0][$i] = $aRecs[1][$i]
    $aStartRect[0][$i] = $aRecs[1][$i]
    $aEndRect[0][$i] = $aRecs[UBound($aRecs)-1][$i]
    Next
    ;_ArrayDisplay($aAktuellRect)
    Do
    For $j = 1 To UBound($aRecs)-1
    If Abs($aRecs[$j][1] - $aAktuellRect[0][1]) < ($GitterWidth+1) And Abs($aRecs[$j][2] - $aAktuellRect[0][2]) < ($GitterWidth+1) And $aRecs[$j][3] = 0 Then
    If Abs($aRecs[$j][1] - $aAktuellRect[0][1]) < ($GitterWidth+1) And $aRecs[$j][2] = $aAktuellRect[0][2] Then
    $G = (Abs($aRecs[$j][1] - $aAktuellRect[0][1]) / $GitterWidth)*10
    $H = ((Abs($aRecs[$j][1] - $aEndRect[0][1]) / $GitterWidth)*10)+((Abs($aRecs[$j][2] - $aEndRect[0][2]) / $GitterWidth)*10)
    ElseIf Abs($aRecs[$j][2] - $aAktuellRect[0][2]) < ($GitterWidth+1) And $aRecs[$j][1] = $aAktuellRect[0][1] Then
    $G = (Abs($aRecs[$j][2] - $aAktuellRect[0][2]) / $GitterWidth)*10
    $H = ((Abs($aRecs[$j][1] - $aEndRect[0][1]) / $GitterWidth)*10)+((Abs($aRecs[$j][2] - $aEndRect[0][2]) / $GitterWidth)*10)
    Else
    $G = ((Abs($aRecs[$j][1] - $aAktuellRect[0][1]) / $GitterWidth)*10-10)+((Abs($aRecs[$j][2] - $aAktuellRect[0][2]) / $GitterWidth)*10-10)+14
    $H = ((Abs($aRecs[$j][1] - $aEndRect[0][1]) / $GitterWidth)*10)+((Abs($aRecs[$j][2] - $aEndRect[0][2]) / $GitterWidth)*10)
    EndIf
    _2DArrayAdd($aRectsOpend, "0|" & $aRecs[$j][1] & "|" & $aRecs[$j][2] & "|" & $G & "|" & $H & "|" & $G+$H )
    ;MsgBox(0,"","CtrlID : " & $aRecs[$j][0] & @CRLF & "PosX : " & $aRecs[$j][1] & @CRLF & "PosY : " & $aRecs[$j][2] & @CRLF & "RecState : " & $aRecs[$j][3] & @CRLF & "G Wert : " & $G & @CRLF & "H Wert : " & $H)
    EndIf
    Next
    ;_ArrayDisplay($aRectsOpend)
    $aMinRectsOpend = _Array2DMinMax($aRectsOpend, 0, 5)
    ;_ArrayDisplay($aMinRectsOpend)
    $aMinRectsOpend = StringSplit($aMinRectsOpend[1],";")
    _GDIPlus_GraphicsFillRect($aGDI[$hGraphic], $aRectsOpend[$aMinRectsOpend[1]][1]+1, $aRectsOpend[$aMinRectsOpend[1]][2]+1, $GitterWidth-1, $GitterWidth-1, $aGDI[$hBrushRectWeg])
    For $k = 1 To UBound($aRecs)-1
    If $aRecs[$k][1] = $aRectsOpend[$aMinRectsOpend[1]][1] And $aRecs[$k][2] = $aRectsOpend[$aMinRectsOpend[1]][2] Then
    $aRecs[$k][3] = 1
    ExitLoop
    EndIf
    Next
    For $l = 0 To 3
    $aAktuellRect[0][$l] = $aRectsOpend[$aMinRectsOpend[1]][$l]
    Next
    ;_ArrayDisplay($aAktuellRect)
    ;_ArrayDisplay($aEndRect)
    ReDim $aRectsOpend[1][6]
    ;_ArrayDisplay($aRectsOpend)
    Sleep(500)
    Until $aAktuellRect[0][1] = $aEndRect[0][1] And $aAktuellRect[0][2] = $aEndRect[0][2]
    EndFunc
    ;$aGDI[$hBrushRectWeg]

    [/autoit] [autoit][/autoit] [autoit]

    Func Init_Gitter_Rec()
    For $i = $GitterWidth To $aGUI[$GUIMainWidth] step $GitterWidth
    For $j = $GitterWidth To $aGUI[$GUIMainWidth] Step $GitterWidth
    $Tmp_CtrlID = GUICtrlCreateLabel("",$j-$GitterWidth,$i-$GitterWidth,$GitterWidth,$GitterWidth)
    GUICtrlSetOnEvent(-1,"RecClicked")
    _2DArrayAdd($aRecs, $Tmp_CtrlID & "|" & $j-$GitterWidth & "|" & $i-$GitterWidth & "|" & 0)
    Next
    Next
    ;~ _ArrayDisplay($aRecs)
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func Set_StartRect($index)
    _GDIPlus_GraphicsFillRect($aGDI[$hGraphic], $aRecs[$index][1]+1, $aRecs[$index][2]+1, $GitterWidth-1, $GitterWidth-1, $aGDI[$hBrushRectStart])
    $aRecs[$index][3] = 2
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func Set_EndRect($index)
    _GDIPlus_GraphicsFillRect($aGDI[$hGraphic], $aRecs[$index][1]+1, $aRecs[$index][2]+1, $GitterWidth-1, $GitterWidth-1, $aGDI[$hBrushRectEnd])
    $aRecs[$index][3] = 0
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func RecClicked()
    For $i = 1 To UBound($aRecs)-1
    If @GUI_CtrlId = $aRecs[$i][0] Then ExitLoop
    Next
    ;MsgBox(0,"","CtrlID : " & $aRecs[$i][0] & @CRLF & "PosX : " & $aRecs[$i][1] & @CRLF & "PosY : " & $aRecs[$i][2] & @CRLF & "RecState : " & $aRecs[$i][3] )
    If $aRecs[$i][3] = 0 Then
    Draw_Rec(1,$aRecs[$i][1],$aRecs[$i][2])
    $aRecs[$i][3] = 1
    ElseIf $aRecs[$i][3] = 1 Then
    Draw_Rec(0,$aRecs[$i][1],$aRecs[$i][2])
    $aRecs[$i][3] = 0
    EndIf
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func Draw_Rec($bSw,$RecsPosX, $RecsPosY)
    Switch $bSw
    Case 0
    _GDIPlus_GraphicsFillRect($aGDI[$hGraphic], $RecsPosX+1, $RecsPosY+1, $GitterWidth-1, $GitterWidth-1, $aGDI[$hBrushRectDeaktiv])
    Case 1
    _GDIPlus_GraphicsFillRect($aGDI[$hGraphic], $RecsPosX+1, $RecsPosY+1, $GitterWidth-1, $GitterWidth-1, $aGDI[$hBrushRectAktiv])
    EndSwitch
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func Draw_Gitternetz()
    #region horizontal
    For $i = $GitterWidth To $aGUI[$GUIMainWidth]-$GitterWidth step $GitterWidth
    _GDIPlus_GraphicsDrawLine($aGDI[$hBuffer],0,$i,$aGUI[$GUIMainWidth],$i)
    Next
    #endregion

    [/autoit] [autoit][/autoit] [autoit]

    #region Vertikal
    For $i = $GitterWidth To $aGUI[$GUIMainHeight]-$GitterWidth step $GitterWidth
    _GDIPlus_GraphicsDrawLine($aGDI[$hBuffer],$i,0,$i,$aGUI[$GUIMainHeight])
    Next
    #endregion
    _GDIPlus_GraphicsDrawImage($aGDI[$hGraphic], $aGDI[$hBitmap], 0, 0)
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func Init_GDI()
    _GDIPlus_Startup()
    $aGDI[$hGraphic] = _GDIPlus_GraphicsCreateFromHWND($aGUI[$hGUIMain])
    $aGDI[$hBitmap] = _GDIPlus_BitmapCreateFromGraphics($aGUI[$GUIMainWidth], $aGUI[$GUIMainHeight], $aGDI[$hGraphic])
    $aGDI[$hBuffer] = _GDIPlus_ImageGetGraphicsContext($aGDI[$hBitmap])
    $aGDI[$hPen] = _GDIPlus_PenCreate(0xFF000000,6)
    $aGDI[$hBrushRectAktiv] = _GDIPlus_BrushCreateSolid("0x" & Hex(255, 2) & Hex(60, 2) & Hex(255, 2) & Hex(255, 2))
    $aGDI[$hBrushRectDeaktiv] = _GDIPlus_BrushCreateSolid("0x" & Hex(255, 2) & Hex(240, 2) & Hex(240, 2) & Hex(240, 2))
    $aGDI[$hBrushRedraw] = _GDIPlus_BrushCreateSolid("0x" & Hex(0, 2) & Hex(0, 2) & Hex(0, 2) & Hex(0, 2))
    $aGDI[$hBrushRectStart] = _GDIPlus_BrushCreateSolid("0x" & Hex(255, 2) & Hex(80, 2) & Hex(255, 2) & Hex(0, 2))
    $aGDI[$hBrushRectEnd] = _GDIPlus_BrushCreateSolid("0x" & Hex(255, 2) & Hex(255, 2) & Hex(0, 2) & Hex(0, 2))
    $aGDI[$hBrushRectWeg] = _GDIPlus_BrushCreateSolid("0x" & Hex(255, 2) & Hex(255, 2) & Hex(255, 2) & Hex(0, 2))
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func GUI()
    Opt("GUIOnEventMode",1)
    $aGUI[$GUIMainWidth] = 500
    $aGUI[$GUIMainHeight] = 500
    $aGUI[$GUIMain] = GUICreate("A* Pfadfindung",$aGUI[$GUIMainWidth],$aGUI[$GUIMainHeight])
    $aGUI[$hGUIMain] = WinGetHandle($aGUI[$GUIMain])
    GUISetOnEvent(-3,"_exit")
    GUISetState()
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    ;==================================================================================================
    ; Function Name: _Array2DMinMax(ByRef $ARRAY [, $MAX=0 [, $iCol=0 [, $sDelim=';']]])
    ; Description:: gibt den minimalen od. maximalen Wert eines 1D/2D-Array zurück
    ; Überprüfung einer oder aller Spalten
    ; Parameter(s): $ARRAY das zu prüfende Array
    ; $MAX 0 = Minwert (Standard); 1 = Maxwert
    ; $iCol SpaltenIndex 0 = Standard
    ; -1 = alle Spalten werden geprüft
    ; $sDelim Trennzeichen f. Indexwerte, Standard ';'
    ; mit 'Default' Zeichen von Opt('GUIDataSeparatorChar')
    ; Return Value(s): Erfolg Array[0] = Max/Min-Wert; Array[1] = Index(Zeile [, Spalte])
    ; Fehler -1 @error = 1 kein Array übergeben
    ; @error = 2 $iCol überschreitet UBound,2
    ; Author(s): BugFix ([email='bugfix@autoit.de'][/email])
    ;==================================================================================================
    Func _Array2DMinMax(ByRef $ARRAY, $MAX=0, $iCol=0, $sDelim=';')
    If Not IsArray($ARRAY) Then Return SetError(1,0,-1)
    Local $Ub2nd = UBound($ARRAY, 2)-1, $arOut[2] = [0]
    If $MAX <> 0 Then $MAX = 1
    If $sDelim = Default Then $sDelim = Opt('GUIDataSeparatorChar')
    If @error Then
    For $i = 0 To UBound($ARRAY) -1
    If $MAX = 1 Then
    If Number($ARRAY[$i]) > $arOut[0] Then
    $arOut[0] = Number($ARRAY[$i])
    $arOut[1] = $i
    EndIf
    Else
    If $i = 0 Then
    $arOut[0] = Number($ARRAY[$i])
    $arOut[1] = $i
    EndIf
    If Number($ARRAY[$i]) < $arOut[0] Then
    $arOut[0] = Number($ARRAY[$i])
    $arOut[1] = $i
    EndIf
    EndIf
    Next
    Else
    If $iCol > $Ub2nd Then Return SetError(2,0,-1)
    If $iCol < -1 Then $iCol = -1
    If $iCol = -1 Then
    For $i = 0 To UBound($ARRAY) -1
    For $k = 0 To $Ub2nd
    If $MAX = 1 Then
    If Number($ARRAY[$i][$k]) > $arOut[0] Then
    $arOut[0] = Number($ARRAY[$i][$k])
    $arOut[1] = $i & $sDelim & $k
    EndIf
    Else
    If $i = 0 Then
    $arOut[0] = Number($ARRAY[$i][$k])
    $arOut[1] = $i & $sDelim & $k
    EndIf
    If Number($ARRAY[$i][$k]) < $arOut[0] Then
    $arOut[0] = Number($ARRAY[$i][$k])
    $arOut[1] = $i & $sDelim & $k
    EndIf
    EndIf
    Next
    Next
    Else
    For $i = 0 To UBound($ARRAY) -1
    If $MAX = 1 Then
    If Number($ARRAY[$i][$iCol]) > $arOut[0] Then
    $arOut[0] = Number($ARRAY[$i][$iCol])
    $arOut[1] = $i & $sDelim & $iCol
    EndIf
    Else
    If $i = 0 Then
    $arOut[0] = Number($ARRAY[$i][$iCol])
    $arOut[1] = $i & $sDelim & $iCol
    EndIf
    If Number($ARRAY[$i][$iCol]) < $arOut[0] Then
    $arOut[0] = Number($ARRAY[$i][$iCol])
    $arOut[1] = $i & $sDelim & $iCol
    EndIf
    EndIf
    Next
    EndIf
    EndIf
    Return $arOut
    EndFunc ;==>_Array2DMinMax

    [/autoit] [autoit][/autoit] [autoit]

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _2DArrayAdd
    ; Description ...: Adds a specified value at the end of an existing array.
    ; Syntax.........: _2DArrayAdd(ByRef $avArray, $vValue, $sDel = "|")
    ; Parameters ....: $avArray - Array to modify
    ; $vValue - Value to add
    ; $sDel - delimiters to splite the 2D elements default is |
    ; Return values .: Success - Index of last added item
    ; Failure - -1, sets @error
    ; |1 - $avArray is not an array
    ; |2 - $avArray is not a 2 dimensional array
    ; |3 - splitted Value <> Ubound of the 2 dimension of the Array or in $sValue is no delimiters
    ; Author ........: Dater
    ; Modified.......:
    ; Remarks .......:
    ; Related .......:
    ; Link ..........: http://www.Autoit.de
    ; Example .......:
    ; ===============================================================================================================================
    Func _2DArrayAdd(ByRef $avArray, $sValue, $sDel = "|")
    If Not IsArray($avArray) Then Return SetError(1, 0, -1)
    If UBound($avArray, 0) <> 2 Then Return SetError(2, 0, -1)

    [/autoit] [autoit][/autoit] [autoit]

    Local $aValue = StringSplit($sValue,$sDel,2)
    Local $iUBound_D1 = UBound($avArray,1)
    Local $iUBound_D2 = UBound($avArray,2)

    [/autoit] [autoit][/autoit] [autoit]

    If Not IsArray($aValue) Or UBound($aValue) <> $iUBound_D2 Then Return SetError(3, 0, -1)

    [/autoit] [autoit][/autoit] [autoit]

    ReDim $avArray[$iUBound_D1 + 1][$iUBound_D2]
    For $i = 0 To UBound($aValue)-1
    $avArray[$iUBound_D1][$i] = $aValue[$i]
    Next

    [/autoit] [autoit][/autoit] [autoit]

    Return $iUBound_D1
    EndFunc ;==>_2DArrayAdd

    [/autoit] [autoit][/autoit] [autoit]

    Func _exit()
    Exit
    EndFunc

    [/autoit]

    mfg Darter

    Das finden von Rechtschreibfehlern muss sofort und unverzüglich dem Autor gemeldet werden. Das eigennützige Verwenden dieser Rechtschreibfehler ist strengstens untersagt und kann mit Freiheitsenzug bestraft werden.