[Beendet] Wegfindungs-Scriptwettbewerb

  • Da die µitLight ja mehr oder minder tot ist, starte ich mal eine kleine Wettbewerb.

    Die Aufgabe ist es einen Block durch eine "Welt" von einem Start zu einem Zielpunkt selbstständig navigieren zu lassen. Die Welt generiert sich bei jedem starten des Scriptes neu mit unterschiedlicher Anzahl und größe der Hindernisse. Die Generierung der Welt mit Start und Zielpunkt sowie die Bewegungsrichtungen (hoch, runter, links, rechts) habe ich schon Vorgegeben.

    Dir Prüfungs zu Kollisionsvermeidung mit einem Hinterniss, das erkennen ob man am Ziel angelangt ist und die Prüfung ob es überhaupt ein Weg zum Ziel gibt müsst ihr noch machen. Es ist duchaus beabsichtigt, das Hinternisse sich überschneiden oder auch mal das Ziel über eim Hinterniss liegt und dadurch nicht erreichbar ist.

    Hier das Codegrundgerüst mit einem kleinen Beispiel darin:

    Spoiler anzeigen
    [autoit]

    #include <GUIConstantsEx.au3>

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

    ;~ ÄNDERUNGEN NUR IM MARKIEREN BEREICH

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

    $Form = GUICreate("Form1", 600, 600, 192, 124)

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

    Dim $wallArray[1][5]

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

    For $i = 0 To Random(20, 30, 1) Step 1
    ReDim $wallArray[$i + 1][5]
    $wallArray[$i][3] = Random(25, 50, 1) ;- Breite
    $wallArray[$i][4] = Random(25, 50, 1) ;- Höhe
    $wallArray[$i][1] = Random(0, (600 - $wallArray[$i][3]), 1) ;- Abstand von links
    $wallArray[$i][2] = Random(0, (600 - $wallArray[$i][4]), 1) ;- Abstand von oben
    $wallArray[$i][0] = GUICtrlCreateButton("", $wallArray[$i][1], $wallArray[$i][2], $wallArray[$i][3], $wallArray[$i][4])
    Next

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

    $positionen = Random(0, 575, 1)

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

    Dim $player[1][5]
    $player[0][3] = 25 ;- Breite
    $player[0][4] = 25 ;- Höhe
    $player[0][1] = 0 ;- Abstand von links
    $player[0][2] = $positionen ;- Abstand von oben
    $player[0][0] = GUICtrlCreateButton("P", 0, $positionen, 25, 25)

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

    Dim $ziel[1][5]
    $ziel[0][3] = 25 ;- Breite
    $ziel[0][4] = 25 ;- Höhe
    $ziel[0][1] = 575 ;- Abstand von links
    $ziel[0][2] = 575 - $positionen ;- Abstand von oben
    $ziel[0][0] = GUICtrlCreateButton("Z", 575, 575 - $positionen, 25, 25)

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

    Func move($richtung, $schritte)
    Switch $richtung
    Case "hoch"
    For $i = 1 To $schritte Step 1
    sleep(50)
    $player[0][2] = $player[0][2] - 1
    GUICtrlSetPos($player[0][0], $player[0][1], $player[0][2])
    Next
    Case "runter"
    For $i = 1 To $schritte Step 1
    sleep(50)
    $player[0][2] = $player[0][2] + 1
    GUICtrlSetPos($player[0][0], $player[0][1], $player[0][2])
    Next
    Case "links"
    For $i = 1 To $schritte Step 1
    sleep(50)
    $player[0][1] = $player[0][1] - 1
    GUICtrlSetPos($player[0][0], $player[0][1], $player[0][2])
    Next
    Case "rechts"
    For $i = 1 To $schritte Step 1
    sleep(50)
    $player[0][1] = $player[0][1] + 1
    GUICtrlSetPos($player[0][0], $player[0][1], $player[0][2])
    Next
    EndSwitch
    EndFunc ;==>move

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

    GUISetState(@SW_SHOW)
    sleep(2000)
    ;~ ÄNDERUNGEN NUR IM MARKIEREN BEREICH

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

    ;~ HIER CODE EINFÜGEN

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

    move("hoch", 20)
    move("rechts", 50)
    move("runter", 30)
    move("links", 40)

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

    ;~ HIER CODE EINFÜGEN

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

    ;~ ÄNDERUNGEN NUR IM MARKIEREN BEREICH
    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit

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

    EndSwitch
    WEnd
    ;~ ÄNDERUNGEN NUR IM MARKIEREN BEREICH

    [/autoit]

    Informationen die ihr sonst noch direkt aus der Vorlage vekommt:

    $wallArray[x][5] = Behinhaltet Informationen der Hinternisse: Control-ID, Abstand von links, Abstand von Oben, Breite, Höhe
    $player[x][5] = Behinhaltet Informationen des Spielerblocks: Control-ID, Abstand von links, Abstand von Oben, Breite, Höhe
    $zil[x][5] = Behinhaltet Informationen der Zielblocks: Control-ID, Abstand von links, Abstand von Oben, Breite, Höhe
    Funktion move($richtung, $schritte) =$richtung: hoch, runter, links, rechts $schritte = Schritt welche in die jeweilige Richtung gemacht werden sollen.


    Bewertet werden foglende Punkte:

    - Schritte die gebraucht werden vom Start zum Ziel
    - Geamte Laufzeit des Scripte einschließlich aller Berechnungen
    - Logik des Scriptes, also ob z.b. unnötige Umwege gemacht werden


    Zu Auswertung werden drei statische Welten vorab generier über die jede Einsendung dann getestet wird und für alle die gleichen Vorraussetzung zu haben.

    Einsendeschluss ist der 07.08.2011

    Also dan viel Spaß gabei

    Andy hat mir ein Schnitzel gebacken aber da war ein Raupi drauf und bevor Oscar das Bugfixen konnte kam Alina und gab mir ein AspirinJunkie.

    2 Mal editiert, zuletzt von chip (8. August 2011 um 15:35)

  • Man könnte das ganze statt mit Buttons doch vllt mit GDI+ machen oder ?
    Ich setze mich mal eben dran und überarbeite das Teil. Dann siehts auch viel besser aus.

    Ich finde die Idee gut. Auch wenn ich befürchte, dass jeder ähnliche Lösungsansätze haben wird.

    .:Edit: Man kann hier auch einen Pseudozufallsalgorithmus einsetzen um die gleichen "Levels" immer wieder zu erhalten.
    So kann man verschiedene Lösungsskripte mit sehr wenig Aufwand mit verschiedenen Levels konfrontieren :.

    .:Edit2: Wenn ich versuche das ganze mit Bildern zu machen funktioniert garnichts mehr. (Gui bleibt unsichtbar. warum auch immer)
    Ich müsste alles von grund auf Neu machen. Da habe ich jetzt aber keine Lust drauf :P^^ :.

    lg
    M

  • Es geht darum die Wegfindung zu machen und nicht ein Design. Das Script oben ist simpel und für jeden einfach umsetzbar, von daher kein GDI+, keine Grafiken und sonst kein unnötiger schnickschnack. Man hat ja bei der Schach-Engine gesehen was unnötiges drumherrum bewirkt.

    Andy hat mir ein Schnitzel gebacken aber da war ein Raupi drauf und bevor Oscar das Bugfixen konnte kam Alina und gab mir ein AspirinJunkie.

  • Habe jetzt mal einen (relativ chaotischen) Lösungsweg implementiert.

    Der Lösungsweg ist komplett selbst ausgedacht und funktioniert meistens, aber nicht immer. (z.B. wenn irgendwo große Winkel sind frisst sich die Suche an den Innenecken fest. Da bin ich aber noch dran)

    Ich finde es sollte als Bewertungskriterium auch andere Sachen geben wie z.B.

    - Lustigste Lösungsidee
    - Kreativste Lösung
    (Nicht, dass ich darauf aus bin diese zu erhalten^^)

    Es ist zwar eine Kunst eine schon vorhandene Methode in AutoIt nachzubauen, aber es ist ebenso eine Kust eine Methode komplett selbst zu erfinden, auch wenn sie nicht so effektiv ist wie die schon bekannten Methoden.

    lg
    Mars(i)

    • Offizieller Beitrag

    Ich finde es sollte als Bewertungskriterium auch andere Sachen geben wie z.B.

    - Lustigste Lösungsidee
    - Kreativste Lösung

    Bei einem Problem, das geradezu nach purer Logik schreit, sind Lustigkeit und Kreativität wohl eher unangebracht. ;)
    Es ist sicher "lustig" statt 20*30 zu rechnen: 20+20+20+20.... - aber ist es sinnvoll?
    Wenn Kreativität andere, bessere Lösungen aufzeigt, dann immer gern. Wenn die Ergebnisse aber hinter anderen zurückbleiben: Wozu?

  • Um neben den Knallhart durchgeplanten, schnell arbeitenden, exakten Wegfindungsmaschinen auch welche zu erhalten die vllt etwas Spaß machen ;)

    Meine trifft inzwischen das ziel mit einem Umweg (im Vergleich zum Minimal nötigen Weg) von 2 - 500 px. Meistens liegt der Wert aber zwischen 10 und 20.
    Festfahren tuts sich jetzt auch nicht mehr so oft.

  • Und der Sieger in allen Kategoriene ist...*Trommelwirbel*.... Marsi

    Hier das Siegerscript:

    Spoiler anzeigen
    [autoit]

    #include <GUIConstantsEx.au3>

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

    ;~ ÄNDERUNGEN NUR IM MARKIEREN BEREICH

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

    Global $Form = GUICreate("Form1", 600, 600, 192, 124)

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

    Dim $wallArray[1][5]

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

    For $i = 0 To Random(20, 30, 1) Step 1
    ReDim $wallArray[$i + 1][5]
    $wallArray[$i][3] = Random(25, 50, 1) ;- Breite
    $wallArray[$i][4] = Random(25, 50, 1) ;- Höhe
    $wallArray[$i][1] = Random(0, (600 - $wallArray[$i][3]), 1) ;- Abstand von links
    $wallArray[$i][2] = Random(0, (600 - $wallArray[$i][4]), 1) ;- Abstand von oben
    $wallArray[$i][0] = GUICtrlCreateButton("", $wallArray[$i][1], $wallArray[$i][2], $wallArray[$i][3], $wallArray[$i][4])
    Next

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

    $positionen = Random(0, 575, 1)

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

    Dim $player[1][5]
    $player[0][3] = 25 ;- Breite
    $player[0][4] = 25 ;- Höhe
    $player[0][1] = 0 ;- Abstand von links
    $player[0][2] = $positionen ;- Abstand von oben
    $player[0][0] = GUICtrlCreateButton("P", 0, $positionen, 25, 25)

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

    Dim $ziel[1][5]
    $ziel[0][3] = 25 ;- Breite
    $ziel[0][4] = 25 ;- Höhe
    $ziel[0][1] = 575 ;- Abstand von links
    $ziel[0][2] = 575 - $positionen ;- Abstand von oben
    $ziel[0][0] = GUICtrlCreateButton("Z", 575, 575 - $positionen, 25, 25)

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

    Func move($Richtung, $Schritte)
    Switch $Richtung
    Case "hoch"
    For $i = 1 To $Schritte Step 1
    Sleep(10)
    $player[0][2] = $player[0][2] - 1
    GUICtrlSetPos($player[0][0], $player[0][1], $player[0][2])
    Next
    Case "runter"
    For $i = 1 To $Schritte Step 1
    Sleep(10)
    $player[0][2] = $player[0][2] + 1
    GUICtrlSetPos($player[0][0], $player[0][1], $player[0][2])
    Next
    Case "links"
    For $i = 1 To $Schritte Step 1
    Sleep(10)
    $player[0][1] = $player[0][1] - 1
    GUICtrlSetPos($player[0][0], $player[0][1], $player[0][2])
    Next
    Case "rechts"
    For $i = 1 To $Schritte Step 1
    Sleep(10)
    $player[0][1] = $player[0][1] + 1
    GUICtrlSetPos($player[0][0], $player[0][1], $player[0][2])
    Next
    EndSwitch
    EndFunc ;==>move

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

    GUISetState(@SW_SHOW)
    ;~ sleep(2000)
    ;~ ÄNDERUNGEN NUR IM MARKIEREN BEREICH

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

    ;~ HIER CODE EINFÜGEN

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

    #include <array.au3>
    #include <GDIPlus.au3>

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

    Local $P[4] = [$player[0][1], $player[0][2], $player[0][3], $player[0][4]]
    Local $Z[4] = [$ziel[0][1], $ziel[0][2], $ziel[0][3], $ziel[0][4]]
    Local $UBoundWand = UBound($wallArray, 1)
    Local $W[$UBoundWand][4]

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

    For $i = 0 To $UBoundWand - 1 Step 1
    $W[$i][0] = $wallArray[$i][1]
    $W[$i][1] = $wallArray[$i][2]
    $W[$i][2] = $wallArray[$i][3]
    $W[$i][3] = $wallArray[$i][4]
    Next

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

    Local $Ret = _Loesen($P, $Z, $W, $UBoundWand) ; Hier steckt die Funktion die die Wegpunkte zurückgibt wenn sie Erfolg hat.

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

    If $Ret = -4 Then MsgBox(0 + 48, 'Problem !', 'Das Ziel steckt vollständig in einem Hindernis')
    If $Ret = -2 Then MsgBox(0 + 48, 'Problem !', 'Der Spieler steckt Vollständig in einem Hindernis')

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

    If IsArray($Ret) Then
    _Bewegen($Ret, $P) ; Nachdem alles gelöst ist wird der Player zum Ziel bewegt.
    Else
    MsgBox(0 + 64, 'Leider keine Lösung', 'Die Methode hat keinen Lösungsweg gefunden')
    EndIf

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

    ;~ move("hoch", 20)
    ;~ move("rechts", 50)
    ;~ move("runter", 30)
    ;~ move("links", 40)

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

    Func _AbstandGrp2()
    If _Betrag($P[1] - $Z[1]) > $P[2] Then Return 1
    Return (_Betrag($P[1] - $Z[1]) / $P[2])
    EndFunc

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

    Func _Bewegen($Ret, $P)
    Local $Richtung, $Len = 0
    Local $Strecke = $Len
    Local $MinStrecke = Int(_E($P[0], $P[1], $Z[0], $Z[1]) - $P[2]+1 + (- $P[2] + 1)*_AbstandGrp2())

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

    _Optimieren($Ret)

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

    ;~ _ArrayDisplay($Ret)

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

    For $i = 1 To UBound($Ret) - 1 Step 1
    If $P[0] = $Ret[$i][0] Then ;er hat sich nicht in X Richtung Bewegt. also Oben oder Unten.
    If $P[1] > $Ret[$i][1] Then ; Y1 ist Größer als Y2 -> Nach Unten
    $Richtung = 'hoch'
    $Len = $P[1] - $Ret[$i][1]
    Else
    $Richtung = 'runter'
    $Len = $Ret[$i][1] - $P[1]
    EndIf
    Else
    If $P[0] > $Ret[$i][0] Then ; Rechts
    $Richtung = 'links'
    $Len = $P[0] - $Ret[$i][0]
    Else
    $Richtung = 'rechts'
    $Len = $Ret[$i][0] - $P[0]
    EndIf
    EndIf

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

    $Strecke += $Len
    move($Richtung, $Len) ; Hier wird Bewegt !

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

    $P[0] = $Ret[$i][0]
    $P[1] = $Ret[$i][1]
    ;~ GUICtrlSetPos($player[0][0], $P[0], $P[1])
    ;~ Sleep(100)

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

    Next

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

    ToolTip('Gelaufene Strecke: ' & $Strecke & ' px (optimiert)' & @CRLF & 'MindestStrecke (Ohne Hindernisse): ' & $MinStrecke & ' px' & @CRLF & 'Umweg: ' & $Strecke - $MinStrecke & ' px ( ' & Round((($Strecke-$MinStrecke)/$MinStrecke)*100,1)& '% )')
    EndFunc ;==>_Bewegen

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

    Func _WegLaenge($Ret)
    Local $Len = 0, $Strecke = 0
    Local $P2 = $P

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

    For $i = 1 To UBound($Ret) - 1 Step 1
    If $P2[0] = $Ret[$i][0] Then ;er hat sich nicht in X Richtung Bewegt. also Oben oder Unten.
    If $P2[1] > $Ret[$i][1] Then ; Y1 ist Größer als Y2 -> Nach Unten
    $Len = $P2[1] - $Ret[$i][1]
    Else
    $Len = $Ret[$i][1] - $P2[1]
    EndIf
    Else
    If $P[0] > $Ret[$i][0] Then ; Rechts
    $Len = $P2[0] - $Ret[$i][0]
    Else
    $Len = $Ret[$i][0] - $P2[0]
    EndIf
    EndIf

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

    $Strecke += $Len
    $P2[0] = $Ret[$i][0]
    $P2[1] = $Ret[$i][1]
    Next
    Return $Strecke
    EndFunc

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

    Func _Optimieren(ByRef $a) ; Schneidet unnötige Wegpunkte raus
    ;~ _ArrayDisplay($a)

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

    Local $u = UBound($a)

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

    For $o = 0 To $u * 2 Step 1
    $u = UBound($a)
    For $i = 2 To $u - 1 Step 1
    If $a[$i][0] = $a[$i-1][0] And $a[$i][0] = $a[$i-2][0] Then
    _ArrayDelete($a, $i - 1)
    ExitLoop
    EndIf
    If $a[$i][1] = $a[$i-1][1] And $a[$i][1] = $a[$i-2][1] Then
    _ArrayDelete($a, $i - 1)
    ExitLoop
    EndIf

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

    Next
    Next

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

    ;~ _ArrayDisplay($a)

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

    EndFunc

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

    Func _GDIPlus_BitmapGetPixel($hBitmap, $iX, $iY)
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipBitmapGetPixel", "hwnd", $hBitmap, "int", $iX, "int", $iY, "uint*", 0)
    Return $aResult[4]
    EndFunc ;==>_GDIPlus_BitmapGetPixel

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

    Func _Loesen($P, $Z, $W, $UBoundW)

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

    Local $ZielEckenInDerWand[4] = [0, 0, 0, 0]
    Local $PlayerInDerWand[4] = [0, 0, 0, 0]

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

    _GDIPlus_Startup()
    ;~ ConsoleWrite(@ScriptLineNumber & @CRLF)
    Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND($Form)
    ;~ ConsoleWrite(@ScriptLineNumber & @CRLF)
    Local $Bitmap = _GDIPlus_BitmapCreateFromGraphics(600, 600, $hGraphics)
    ;~ ConsoleWrite(@ScriptLineNumber & @CRLF)
    Local $hBuffer = _GDIPlus_ImageGetGraphicsContext($Bitmap)
    ;~ ConsoleWrite(@ScriptLineNumber & @CRLF)
    Local $Brush = _GDIPlus_BrushCreateSolid(0x10000000)
    Local $Brush2 = _GDIPlus_BrushCreateSolid(0x50FF0000)

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

    For $i = 0 To $UBoundW - 1 Step 1
    If _Kollision_Viereck_Punkt($Z[0], $Z[1], $W[$i][0], $W[$i][1], $W[$i][2], $W[$i][3]) Then $ZielEckenInDerWand[0] = 1
    If _Kollision_Viereck_Punkt($Z[0] + $Z[2], $Z[1], $W[$i][0], $W[$i][1], $W[$i][2], $W[$i][3]) Then $ZielEckenInDerWand[1] = 1
    If _Kollision_Viereck_Punkt($Z[0], $Z[1] + $Z[3], $W[$i][0], $W[$i][1], $W[$i][2], $W[$i][3]) Then $ZielEckenInDerWand[2] = 1
    If _Kollision_Viereck_Punkt($Z[0] + $Z[2], $Z[1] + $Z[3], $W[$i][0], $W[$i][1], $W[$i][2], $W[$i][3]) Then $ZielEckenInDerWand[3] = 1
    If _Kollision_Viereck_Punkt($P[0], $P[1], $W[$i][0], $W[$i][1], $W[$i][2], $W[$i][3]) Then $PlayerInDerWand[0] = 1
    If _Kollision_Viereck_Punkt($P[0] + $P[2], $P[1], $W[$i][0], $W[$i][1], $W[$i][2], $W[$i][3]) Then $PlayerInDerWand[1] = 1
    If _Kollision_Viereck_Punkt($P[0], $P[1] + $P[3], $W[$i][0], $W[$i][1], $W[$i][2], $W[$i][3]) Then $PlayerInDerWand[2] = 1
    If _Kollision_Viereck_Punkt($P[0] + $P[2], $P[1] + $P[3], $W[$i][0], $W[$i][1], $W[$i][2], $W[$i][3]) Then $PlayerInDerWand[3] = 1
    Next

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

    If _Summe($ZielEckenInDerWand) = 4 Then Return -4
    If _Summe($PlayerInDerWand) = 4 Then Return -2

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

    If _Summe($ZielEckenInDerWand) Then
    ;~ Exit
    If MsgBox(4 + 32, 'Problem !', 'Das Ziel steckt zum Teil in einem Hindernis' & @CRLF & 'Dennoch Versuchen ?') = 7 Then Return -3
    EndIf

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

    If _Summe($PlayerInDerWand) Then
    ;~ Exit
    If MsgBox(4 + 32, 'Problem !', 'Der Spieler steckt zum Teil in einem Hindernis' & @CRLF & 'Dennoch Versuchen ?') = 7 Then Return -1
    EndIf

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

    Local $GefundeneWege = 0
    Local $ProbierteSchritte = 0
    Local $P2 = $P ; Kopie des Players
    Local $Schrittlaenge = Int($P2[2] / 2) ; Breite des Spielers ist die Schrittlänge
    Local $TmpWeg[1][2] ; Enthält alle angesteuerten Wegpunkte
    Local $AktuellerWeg[1][2] ; Enthält Wegpunkte des kürzesten Weges

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

    Local $L, $R, $O, $U ; Ist True wenn der Weg möglich ist.
    Local $Richtung, $Schritte = 0, $Entfernung[4], $GebrauchteSchritte = 0, $GebrauchteSchritte_Alt = 0

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

    Local $Control = GUICtrlCreateEdit('Bitte' & @CRLF & 'Wart', $P2[0], $P2[1], $P[2], $P[3], 0, 0)
    GUICtrlSetFont(-1, 7)
    Local $MaxIndex, $FreieWege
    Local $Timer
    Local $Maxdiff = 10000 ; 100 ms pro Weg. Wenn das nicht reicht gilt der versuch als Fehlgeschlagen.

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

    Local $Wegfall = 3 ; 4 = Nichts entfällt, 0 = Alles Entfällt bis auf der Kürzeste
    Local $Durchlaeufe = 0

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

    Local $OriginalUbound = $UBoundW

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

    For $v = 0 To 19 Step 1 ;10 Versuche den kürzesten Weg zu finden.
    $Timer = TimerInit()
    $P2 = $P
    $Schritte = 1
    ReDim $TmpWeg[1][2]
    $GebrauchteSchritte = 0
    _GDIPlus_GraphicsClear($hBuffer, 0xFFFFFFFF)
    $UBoundW = $OriginalUbound
    ReDim $W[$UBoundW][4]
    While TimerDiff($Timer) < $Maxdiff
    $Schrittlaenge = Random(3, 17, 1)
    $GebrauchteSchritte += $Schrittlaenge
    $Wegfall = 0
    ;~ If $GefundeneWege < 3 Then $Wegfall = Random(3, 4, 1) ; Mit Wegfall 4 Mag das teil nur rumirren. aber es verfährt sich nicht so schnell.
    ;~ If $GefundeneWege >= 3 And $GefundeneWege < 10 Then $Wegfall = Random(1, 3, 1) ; Je mehr Wege gefunden wurden desto schärfer kann die Einstellung sein.
    ;~ If $GefundeneWege >= 10 And $GefundeneWege < 15 Then $Wegfall = Random(0, 2, 1) ; Nochmals eine verschärfung
    If $GefundeneWege >= 15 And $GefundeneWege < 18 Then $Wegfall = Random(0, 1, 1) ; Nochmals eine verschärfung
    ;~ ToolTip($Wegfall)
    $ProbierteSchritte += 1
    $Schritte += 1
    ReDim $TmpWeg[$Schritte][2]
    $TmpWeg[$Schritte - 1][0] = $P2[0]
    $TmpWeg[$Schritte - 1][1] = $P2[1]
    _GDIPlus_GraphicsFillRect($hBuffer, $P2[0], $P2[1], $P2[2], $P2[3], $Brush)

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

    If Int('0x' & StringRight(Hex(_GDIPlus_BitmapGetPixel($Bitmap, $P2[0]+$Schrittlaenge/2, $P2[1]+$Schrittlaenge/2)),2)) < 100 Then
    $UBoundW += 1
    ReDim $W[$UBoundW][4]
    $W[$UBoundW-1][0] = $P2[0] + 10
    $W[$UBoundW-1][1] = $P2[1] + 10
    $W[$UBoundW-1][2] = 5
    $W[$UBoundW-1][3] = 5
    EndIf

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

    ;~ For $bla = 0 To $UBoundW - 1 Step 1
    ;~ _GDIPlus_GraphicsFillRect($hBuffer, $W[$bla][0], $W[$bla][1], $W[$bla][2], $W[$bla][3], $Brush2)
    ;~ Next
    ;~ Sleep(100)

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

    ;~ _GDIPlus_GraphicsDrawImage($hGraphics, $Bitmap, 0, 0)

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

    $L = True
    $R = True
    $O = True
    $U = True

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

    For $i = 0 To $UBoundW - 1 Step 1
    If _Kollision_Viereck_Viereck($P2[0] - $Schrittlaenge, $P2[1], $P2[2], $P2[3], $W[$i][0], $W[$i][1], $W[$i][2], $W[$i][3]) Or ($P2[0] - $Schrittlaenge < 0) Then $L = False
    If _Kollision_Viereck_Viereck($P2[0] + $Schrittlaenge, $P2[1], $P2[2], $P2[3], $W[$i][0], $W[$i][1], $W[$i][2], $W[$i][3]) Or ($P2[0] + $Schrittlaenge > (600 - $P[2])) Then $R = False
    If _Kollision_Viereck_Viereck($P2[0], $P2[1] - $Schrittlaenge, $P2[2], $P2[3], $W[$i][0], $W[$i][1], $W[$i][2], $W[$i][3]) Or ($P2[1] - $Schrittlaenge < 0) Then $O = False
    If _Kollision_Viereck_Viereck($P2[0], $P2[1] + $Schrittlaenge, $P2[2], $P2[3], $W[$i][0], $W[$i][1], $W[$i][2], $W[$i][3]) Or ($P2[1] + $Schrittlaenge > 600 - $P[2]) Then $U = False
    Next

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

    If $L = False And $R = False And $O = False And $U = False Then ContinueLoop

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

    $FreieWege = 0
    If $L Then $FreieWege += 1
    If $R Then $FreieWege += 1
    If $O Then $FreieWege += 1
    If $U Then $FreieWege += 1

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

    ; Wege die Wegfallen können
    If $FreieWege > 1 Then
    For $blubb = 0 To $FreieWege - $Wegfall Step 1

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

    If $L Then
    $Entfernung[0] = _Entfernung_Punkt_Punkt($P2[0] + $P2[2] / 2 - $Schrittlaenge, $P2[1] + $P2[3] / 2, $Z[0] + $Z[2] / 2, $Z[1] + $Z[3] / 2)
    Else
    $Entfernung[0] = 0
    EndIf
    If $R Then
    $Entfernung[1] = _Entfernung_Punkt_Punkt($P2[0] + $P2[2] / 2 + $Schrittlaenge, $P2[1] + $P2[3] / 2, $Z[0] + $Z[2] / 2, $Z[1] + $Z[3] / 2)
    Else
    $Entfernung[1] = 0
    EndIf
    If $O Then
    $Entfernung[2] = _Entfernung_Punkt_Punkt($P2[0] + $P2[2] / 2, $P2[1] + $P2[3] / 2 - $Schrittlaenge, $Z[0] + $Z[2] / 2, $Z[1] + $Z[3] / 2)
    Else
    $Entfernung[2] = 0
    EndIf
    If $U Then
    $Entfernung[3] = _Entfernung_Punkt_Punkt($P2[0] + $P2[2] / 2, $P2[1] + $P2[3] / 2 + $Schrittlaenge, $Z[0] + $Z[2] / 2, $Z[1] + $Z[3] / 2)
    Else
    $Entfernung[3] = 0
    EndIf

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

    $MaxIndex = _Maximal($Entfernung)

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

    Switch $MaxIndex
    Case 0
    If $R Or $O Or $U Then $L = False
    Case 1
    If $L Or $O Or $U Then $R = False
    Case 2
    If $L Or $R Or $U Then $O = False
    Case 3
    If $L Or $R Or $O Then $U = False
    EndSwitch

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

    $FreieWege2 = 0
    If $L Then $FreieWege2 += 1
    If $R Then $FreieWege2 += 1
    If $O Then $FreieWege2 += 1
    If $U Then $FreieWege2 += 1

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

    If $FreieWege2 = 1 Then
    ;~ ToolTip('Ein Weg')
    ExitLoop
    EndIf

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

    Next

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

    EndIf

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

    $Richtung = -1

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

    If Not ($L = False And $R = False And $O = False And $U = False) Then
    $Durchlaeufe = 0
    While $Richtung = -1
    ;~ ConsoleWrite($Richtung & @CRLF)
    Switch Random(0, 3, 1)
    Case 0
    If $L And Not ($P2[0] - $Schrittlaenge < 0) Then $Richtung = 0
    Case 1
    If $R And Not ($P2[0] + $Schrittlaenge > (600 - $P[2])) Then $Richtung = 1
    Case 2
    If $O And Not ($P2[1] - $Schrittlaenge < 0) Then $Richtung = 2
    Case 3
    If $U And Not ($P2[1] + $Schrittlaenge > 600 - $P[2]) Then $Richtung = 3
    EndSwitch
    $Durchlaeufe += 1
    If $Durchlaeufe = 10 Then ; Es wird zwar vermiden durch die AußenWand zu gehen, aber nicht verboten...^^
    If $L Then $Richtung = 0
    If $R Then $Richtung = 1
    If $O Then $Richtung = 2
    If $U Then $Richtung = 3
    EndIf
    WEnd
    Else

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

    EndIf

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

    Switch $Richtung
    Case 0
    $P2[0] -= $Schrittlaenge
    Case 1
    $P2[0] += $Schrittlaenge
    Case 2
    $P2[1] -= $Schrittlaenge
    Case 3
    $P2[1] += $Schrittlaenge
    EndSwitch

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

    If _Kollision_Viereck_Viereck($P2[0], $P2[1], $P2[2], $P2[3], $Z[0], $Z[1], $Z[2], $Z[3]) Then

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

    $Schritte += 1
    ReDim $TmpWeg[$Schritte][2]
    $TmpWeg[$Schritte - 1][0] = $P2[0]
    $TmpWeg[$Schritte - 1][1] = $P2[1]

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

    ;~ _Optimieren($TmpWeg)
    ;~ $GebrauchteSchritte = _WegLaenge($TmpWeg)

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

    ToolTip('Mindestens gebrauchte Schritte: ' & $GebrauchteSchritte_Alt & @CRLF & 'Aktuell gebrauchte Schritte: ' & $GebrauchteSchritte)
    $GefundeneWege += 1
    If Not $GebrauchteSchritte_Alt Then
    $GebrauchteSchritte_Alt = $GebrauchteSchritte
    $AktuellerWeg = $TmpWeg
    EndIf
    If $GebrauchteSchritte < $GebrauchteSchritte_Alt Then
    $GebrauchteSchritte_Alt = $GebrauchteSchritte
    $AktuellerWeg = $TmpWeg
    EndIf
    ExitLoop
    EndIf

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

    ;~ GUICtrlSetPos($Control, $P2[0], $P2[1])
    ;~ Sleep(100)

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

    WEnd
    ;~ ToolTip($ProbierteSchritte & @CRLF & $v)
    Next

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

    GUICtrlDelete($Control)

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

    ToolTip('Es wurden ' & $GefundeneWege & ' Wege gefunden' & @CRLF & 'Der Kürzeste war: ' & $GebrauchteSchritte_Alt & ' Pixel lang (nicht Optimiert)' & @CRLF & 'Luftlinie: ' & Int(_E($P[0], $P[1], $Z[0], $Z[1]) - $P[2]+1 + (- $P[2] + 1)*_AbstandGrp2()) & @CRLF & _
    'Mindestweg (ohne Hindernisse): ' & Int(_E($P[0], $P[1], $Z[0], $Z[1]) - 2*$P[2]+2))

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

    _GDIPlus_BrushDispose($Brush)
    _GDIPlus_GraphicsDispose($hBuffer)
    _GDIPlus_BitmapDispose($Bitmap)
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_Shutdown()

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

    Return $AktuellerWeg

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

    EndFunc ;==>_Loesen

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

    #Region Sonstiges

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

    Func _Maximal($Array)
    Local $a = 0, $b = $Array[0]
    For $i = 0 To UBound($Array) - 1 Step 1
    If $b < $Array[$i] Then
    $b = $Array[$i]
    $a = $i
    EndIf
    Next
    Return $a
    EndFunc ;==>_Maximal

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

    Func _Summe($Array)
    Local $a = 0
    For $i = 0 To UBound($Array) - 1 Step 1
    $a += $Array[$i]
    Next
    Return $a
    EndFunc ;==>_Summe

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

    Func _E($x1, $y1, $x2, $y2)
    Return _Betrag($x1 - $x2) + _Betrag($y1 - $y2)
    EndFunc ;==>_E

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

    Func _Betrag($a)
    If $a > 0 Then Return $a
    Return -$a
    EndFunc ;==>_Betrag

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

    Func _Entfernung_Punkt_Punkt($x1, $y1, $x2, $y2)
    Return (($x1 - $x2) ^ 2 + ($y1 - $y2) ^ 2) ^ 0.5
    EndFunc ;==>_Entfernung_Punkt_Punkt

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

    Func _Kollision_Viereck_Punkt($x1, $y1, $x2, $y2, $b2, $h2) ;Selbsterklärend
    Return ($x1 > $x2 And $y1 > $y2 And $x1 < $x2 + $b2 And $y1 < $y2 + $h2)
    EndFunc ;==>_Kollision_Viereck_Punkt

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

    Func _Kollision_Viereck_Viereck($x1, $y1, $b1, $h1, $x2, $y2, $b2, $h2)
    Return ($x1 + $b1 > $x2 And $y1 + $h1 > $y2 And $x1 < $x2 + $b2 And $y1 < $y2 + $h2)
    EndFunc ;==>_Kollision_Viereck_Viereck

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

    #EndRegion - Sonstiges
    ;EndRegion - Sonstiges

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

    ;~ HIER CODE EINFÜGEN

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

    ;~ ÄNDERUNGEN NUR IM MARKIEREN BEREICH
    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit

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

    EndSwitch
    WEnd
    ;~ ÄNDERUNGEN NUR IM MARKIEREN BEREICH

    [/autoit]

    Andy hat mir ein Schnitzel gebacken aber da war ein Raupi drauf und bevor Oscar das Bugfixen konnte kam Alina und gab mir ein AspirinJunkie.

  • Ich glaube nicht^^

    Mein Skript war eigentlich mehr oder Weniger ein Test, ob man das ziel auch durch Zufall finden kann.
    Der Spieler läuft zufällig eine Zufällige Strecke. Mit einer Wahrscheinlichkeit ungleich 0 erreicht er so irgendwann das Ziel, sollte es erreichbar sein.

    Die Methode um das Ziel schneller zu erreichen ist gleichzeitig der Untergang, falls der Weg zu weit versperrt ist.
    Es werden Richtungen gestrichen die weiter vom Ziel weg führen, es sei denn alle Anderen Wege sind blockiert.
    Dadurch kann das Ziel mit fast optimalem Weg in relativ kurzer Zeit gefunden werden wenn es frei zugänglich ist.
    Sollte der Weg versperrt sein wird das skript aber endlos laufen und keine Lösung finden. Deshalb der Timer auf 20sek^^

    lg
    Mars(i)

  • Haben auch noch andere außer Marsi ein Skript eingesendet?
    Wenn ja wären diese Skripte vllt auch noch ganz interessant.

    Nope wurden keine weiteren hehe.

    Andy hat mir ein Schnitzel gebacken aber da war ein Raupi drauf und bevor Oscar das Bugfixen konnte kam Alina und gab mir ein AspirinJunkie.