Hallo AutoIt Gemeinde,
seit kurzem hat mich das schlechte Wetter wider zu AutoIt gebracht und da ich nichts zu tun wusste hab ich aus Spaß ein Labyrinth Generator erstellt
wärend die c Version des scriptes langsam ein funktionalen zustand erreicht würde mich eure Meinung zu diesem Erguss interessieren
AutoIt: Maze
; ===============================================================================================================================
; Title .........: Maze_generator
; AutoIt Version : 3.3.12.0
; Description ...: Script zum erzeugen beliebig großer Labyrinthe Rechteckigem uhrsprungs
; Author ........: Matthias
; Modified ......:
; ===============================================================================================================================
#include <Gdiplus.au3>
#include <Misc.au3>
Global $swapcolour = 0
Global $maze, $xBlocks, $yBlocks, $backup, $cpx, $cpy, $Solution_GUI, $kasten = 0, $dir, $error, $startx, $starty, $endex, $endey, $loesung, $timer, $splitter, $zeitcounter, $zeit, $hGraphics, $ES_NUMBER = 8192, $solvex, $solvey
HotKeySet("{ESC}", "_exit")
_GDIPlus_Startup()
$Main_GUI = GUICreate("Maze", 289, 342, 192, 124)
$Input_X_Blocks = GUICtrlCreateInput(150, 40, 20, 121, 21, $ES_NUMBER)
$Input_Y_Blocks = GUICtrlCreateInput(150, 40, 60, 121, 21, $ES_NUMBER)
$Input_startx = GUICtrlCreateInput(1, 40, 140, 121, 21, $ES_NUMBER)
$Input_starty = GUICtrlCreateInput(1, 40, 180, 121, 21, $ES_NUMBER)
$Input_endex = GUICtrlCreateInput(150, 40, 220, 121, 21, $ES_NUMBER)
$Input_endey = GUICtrlCreateInput(150, 40, 260, 121, 21, $ES_NUMBER)
GUICtrlCreateLabel("X Blocks", 176, 20, 236, 17)
GUICtrlCreateLabel("Y Blocks", 176, 60, 236, 17)
$id_LABEL_AnzahlBlocks = GUICtrlCreateLabel("Anzahl an Feldern " & GUICtrlRead($Input_X_Blocks) * GUICtrlRead($Input_Y_Blocks), 40, 100, 236, 17)
GUICtrlCreateLabel("START X", 176, 140, 236, 17)
GUICtrlCreateLabel("START Y", 176, 180, 236, 17)
GUICtrlCreateLabel("ENDE X", 176, 220, 236, 17)
GUICtrlCreateLabel("ENDE Y", 176, 260, 236, 17)
$Button_Create = GUICtrlCreateButton("Create", 40, 296, 75, 25)
$Progress1 = GUICtrlCreateProgress(4, 320, 280, 20)
GUISetState(@SW_SHOW)
While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case -3
_exit()
Case $Input_X_Blocks
GUICtrlSetData($Input_endex, GUICtrlRead($Input_X_Blocks))
GUICtrlSetData($id_LABEL_AnzahlBlocks, "Anzahl an Feldern " & GUICtrlRead($Input_X_Blocks) * GUICtrlRead($Input_Y_Blocks))
Case $Input_Y_Blocks
GUICtrlSetData($Input_endey, GUICtrlRead($Input_Y_Blocks))
GUICtrlSetData($id_LABEL_AnzahlBlocks, "Anzahl an Feldern " & GUICtrlRead($Input_X_Blocks) * GUICtrlRead($Input_Y_Blocks))
Case $Button_Create
$xBlocks = GUICtrlRead($Input_X_Blocks) + 2
$yBlocks = GUICtrlRead($Input_Y_Blocks) + 2
$startx = GUICtrlRead($Input_startx)
$starty = GUICtrlRead($Input_starty)
$endex = GUICtrlRead($Input_endex)
$endey = GUICtrlRead($Input_endey)
Select;falscheingaben abfangen
Case $xBlocks < 4
MsgBox(0, "", "Wert in X Blocks zu klein, mindestens 2")
Case $yBlocks < 4
MsgBox(0, "", "Wert in Y Blocks zu klein, mindestens 2")
Case $startx < 1 Or $startx > $xBlocks - 2
MsgBox(0, "", "Startwert x liegt außerhalb")
Case $starty < 1 Or $starty > $yBlocks - 2
MsgBox(0, "", "Startwert y liegt außerhalb")
Case $endex > $xBlocks - 2 Or $endex < 1
MsgBox(0, "", "Ziel x liegt außerhalb")
Case $endey > $yBlocks - 2 Or $endey < 1
MsgBox(0, "", "Ziel y liegt außerhalb")
Case Else;wenn alle falscheingaben gefiltert sind (start/ziel identisch ist kein fehler nur Dumm)
$cpx = $startx;$cpx=current position x
$cpy = $starty;$cpx=current position y
$anzahlblocks = (($xBlocks - 2) * ($yBlocks - 2) - 1)
Dim $maze[$xBlocks][$yBlocks];2D Feld Array
$wi = (@DesktopHeight - 40) / (($xBlocks < $yBlocks) ? $yBlocks : $xBlocks) * 0.98;Breite/Höhe der Kästchen, abhängig von der Anzahl
_setwalls();ränder erstellen
;~ SRandom(255); Setseed für tests (geschwindigkeit) immer die gleichen zahlenfolgen ergeben immer das selbe Ergebnis
$timer = TimerInit()
_createMaze();erzeugen des feldes
$timer1Diff = Round((TimerDiff($timer) / 1000), 2)
_drawmaze();zeichnen
EndSelect
EndSwitch
WEnd
Func _setwalls();Randbegrenzungen als solche festlegen
For $i1 = 0 To $xBlocks - 1
$maze[$i1][0] = 16;16 als rand da beim zeichnen die ersten 4 bits die 4 wände darstellen, sind alle 0 werden alle gezeichnet
$maze[$i1][$yBlocks - 1] = 16
Next
For $i1 = 0 To $yBlocks - 1
$maze[0][$i1] = 16
$maze[$xBlocks - 1][$i1] = 16
Next
EndFunc ;==>_setwalls
Func _createMaze()
AdlibRegister("update_progress")
Do
$dir = Random(1, 4, 1);bewegungsrichtung
If $cpx = $endex And $cpy = $endey Then $loesung = $backup;ziel erreicht
If ($maze[$cpx][$cpy - 0x1] And $maze[$cpx][$cpy + 0x1] And $maze[$cpx + 0x1][$cpy] And $maze[$cpx - 0x1][$cpy]) Then;alle felder belegt(backstep) oder noch eins frei(math)
_backstep()
Else
_math()
EndIf
Until $anzahlblocks = $kasten ;bis alle blöcke betreten wurden(außer rand)
AdlibUnRegister("update_progress")
EndFunc ;==>_createMaze
Func _math()
Switch $dir
Case 1
If Not $maze[$cpx][$cpy - 0x1] Then;N
$maze[$cpx][$cpy] += 0x1;aktuelle position updaten +1 nach oben offen
$cpy -= 0x1 ;positionsupdate
$maze[$cpx][$cpy] = 0x4 ;zielposition updaten +4 nach unten offen
$backup &= $dir ;Um zurückzufinden richtung speichern
$kasten += 0x1 ;anzahl der betretenen kästchen erhöhen
EndIf
Case 2
If Not $maze[$cpx + 0x1][$cpy] Then;O
$maze[$cpx][$cpy] += 0x2
$cpx += 0x1
$maze[$cpx][$cpy] = 0x8
$backup &= $dir
$kasten += 0x1
EndIf
Case 3
If Not $maze[$cpx][$cpy + 0x1] Then;S
$maze[$cpx][$cpy] += 0x4
$cpy += 0x1
$maze[$cpx][$cpy] = 0x1
$backup &= $dir
$kasten += 0x1
EndIf
Case 4
If Not $maze[$cpx - 0x1][$cpy] Then;W
$maze[$cpx][$cpy] += 0x8
$cpx -= 0x1
$maze[$cpx][$cpy] = 0x2
$backup &= $dir
$kasten += 0x1
EndIf
EndSwitch
EndFunc ;==>_math
Func _backstep()
$backupteil = StringRight($backup, 1);letzte ziffer holen
$backup = StringTrimRight($backup, 1);letzte ziffer abschneiden
Switch $backupteil
Case 1
$cpy += 0x1
Case 2
$cpx -= 0x1
Case 3
$cpy -= 0x1
Case 4
$cpx += 0x1
EndSwitch
EndFunc ;==>_backstep
Func _exit()
_GDIPlus_Shutdown()
Exit
EndFunc ;==>_exit
Func _drawmaze()
$Solution_GUI = GUICreate("", @DesktopHeight - 40, @DesktopHeight - 40, -1, -1, 0x80000000);gui mit $WS_POPUP style
GUISetBkColor(($swapcolour ? 0xFF000000 : 0xFFFFFFFF), $Solution_GUI)
GUISetState(@SW_SHOW, $Solution_GUI)
GUISetState(@SW_HIDE, $Main_GUI)
$hGraphics = _GDIPlus_GraphicsCreateFromHWND($Solution_GUI)
_GDIPlus_GraphicsClear($hGraphics, ($swapcolour ? 0xFFFFFFFF : 0xFF000000))
_GDIPlus_GraphicsSetSmoothingMode($hGraphics, 2)
$bitmap = _GDIPlus_BitmapCreateFromGraphics(@DesktopHeight - 40, @DesktopHeight - 40, $hGraphics)
$buffer = _GDIPlus_ImageGetGraphicsContext($bitmap)
Global $black = $swapcolour ? _GDIPlus_PenCreate(0xFF000000) : _GDIPlus_PenCreate(0xFFFFFFFF)
$red = _GDIPlus_PenCreate(0xFFFF0000)
$red2 = _GDIPlus_PenCreate(0xFFFF0000, $wi * 0.8);Stift für läufer
$start = _GDIPlus_PenCreate(0xFF00FF00, $wi);Stift für start
$Temp_01 = 10 + ($wi / 2)
$solvex = $startx
$solvey = $starty
GDIPlus_GraphicsDrawLine($buffer, 10, ($yBlocks - 1) * $wi + 10 + $wi, $xBlocks * $wi + 10, ($yBlocks - 1) * $wi + 10 + $wi);fehlende Südwand
GDIPlus_GraphicsDrawLine($buffer, 10, 10, 10, ($yBlocks - 1) * $wi + $wi + 10);fehlende Westwand
For $i1 = 0 To $xBlocks - 1
$wi2 = $i1 * $wi + 10
For $i2 = 0 To $yBlocks - 1
If (BitAND($maze[$i1][$i2], 0x1) = 0) Then GDIPlus_GraphicsDrawLine($buffer, $wi2, $i2 * $wi + 10, $wi2 + $wi, $i2 * $wi + 10) ;Norden und
If (BitAND($maze[$i1][$i2], 0x2) = 0) Then GDIPlus_GraphicsDrawLine($buffer, $wi2 + $wi, $i2 * $wi + 10 + $wi, $wi2 + $wi, $i2 * $wi + 10);Osten reichen wenn man sie bei jedem Feld zeichnet (Fehlender Rand im Westen und Süden wurde oben behoben)
Next
Next
GDIPlus_GraphicsDrawLine($buffer, ($startx * $wi - ($wi / 2)) + $wi + 10, ($starty * $wi) + 10, ($startx * $wi - ($wi / 2)) + $wi + 10, ($starty * $wi + $wi) + 10, $start);start
GDIPlus_GraphicsDrawLine($buffer, ($endex * $wi - ($wi / 2)) + $wi + 10, ($endey * $wi) + 10, ($endex * $wi - ($wi / 2)) + $wi + 10, ($endey * $wi + $wi) + 10, $red2);ende
_GDIPlus_GraphicsDrawImage($buffer, $bitmap, 0, 0)
_GDIPlus_GraphicsDrawImage($hGraphics, $bitmap, 0, 0)
If MsgBox(4, "LÖSEN?", "es hat " & $timer1Diff & " Sekunden gedauert " & $anzahlblocks + 1 & " felder zu erstellen" & @CRLF & "Soll das Labyrint gelöst werden?") = 6 Then
$splitter = StringSplit($loesung, "")
For $1a = 1 To (UBound($splitter) - 1);lösungsweg zeichnen
Switch $splitter[$1a]
Case 1;N
GDIPlus_GraphicsDrawLine($buffer, $solvex * $wi + $Temp_01, $solvey * $wi + $Temp_01, $solvex * $wi + $Temp_01, $solvey * $wi + $Temp_01 - $wi, $red)
$solvey -= 1
Case 2;O
GDIPlus_GraphicsDrawLine($buffer, $solvex * $wi + $Temp_01, $solvey * $wi + $Temp_01, $solvex * $wi + $Temp_01 + $wi, $solvey * $wi + $Temp_01, $red)
$solvex += 1
Case 3;S
GDIPlus_GraphicsDrawLine($buffer, $solvex * $wi + $Temp_01, $solvey * $wi + $Temp_01, $solvex * $wi + $Temp_01, $solvey * $wi + $Temp_01 + $wi, $red)
$solvey += 1
Case 4;W
GDIPlus_GraphicsDrawLine($buffer, $solvex * $wi + $Temp_01, $solvey * $wi + $Temp_01, $solvex * $wi + $Temp_01 - $wi, $solvey * $wi + $Temp_01, $red)
$solvex -= 1
EndSwitch
Next
_GDIPlus_GraphicsDrawImage($hGraphics, $bitmap, 0, 0)
$solvex = 0;keine fertig meldung beim automatisch lösen
EndIf
_GDIPlus_GraphicsDrawImage($buffer, $bitmap, 0, 0)
$hGraphics = _GDIPlus_GraphicsCreateFromHWND($Solution_GUI)
_GDIPlus_GraphicsClear($hGraphics, ($swapcolour ? 0xFFFFFFFF : 0xFF000000))
_GDIPlus_GraphicsDrawImage($hGraphics, $bitmap, 0, 0)
GDIPlus_GraphicsDrawLine($hGraphics, ($solvex * $wi - ($wi / 2)) + $wi + 10, 2 + (($solvey * $wi) + 10), ($solvex * $wi - ($wi / 2)) + $wi + 10, (($solvey * $wi + $wi) + 10) - 2, $red2)
Do
Sleep(100)
If _IsPressed(57) And BitAND($maze[$solvex][$solvey], 1) = 1 Then;bewegung und wandtest N
$solvey -= 1;w
$Temp_01 = 1
EndIf
If _IsPressed(41) And BitAND($maze[$solvex][$solvey], 8) = 8 Then;bewegung und wandtest W
$solvex -= 1;a
$Temp_01 = 1
EndIf
If _IsPressed(53) And BitAND($maze[$solvex][$solvey], 4) = 4 Then;bewegung und wandtest S
$solvey += 1;s
$Temp_01 = 1
EndIf
If _IsPressed(44) And BitAND($maze[$solvex][$solvey], 2) = 2 Then;bewegung und wandtest O
$solvex += 1;d
$Temp_01 = 1
EndIf
If $Temp_01 Then;Anzeige updaten
_GDIPlus_GraphicsClear($hGraphics, ($swapcolour ? 0xFFFFFFFF : 0xFF000000))
_GDIPlus_GraphicsDrawImage($hGraphics, $bitmap, 0, 0)
GDIPlus_GraphicsDrawLine($hGraphics, ($solvex * $wi - ($wi / 2)) + $wi + 10, 2 + (($solvey * $wi) + 10), ($solvex * $wi - ($wi / 2)) + $wi + 10, (($solvey * $wi + $wi) + 10) - 2, $red2)
$Temp_01 = 0
EndIf
If $solvex = $endex And $solvey = $endey Then;am Ende angekommen
MsgBox(0, "", "Sie haben gewonnen!!")
_GDIPlus_BitmapDispose($bitmap);Aufräumen
_GDIPlus_PenDispose($red)
_GDIPlus_PenDispose($red2)
_GDIPlus_PenDispose($start)
_GDIPlus_GraphicsDispose($hGraphics)
_exit();beenden
EndIf
Until GUIGetMsg() = -3
EndFunc ;==>_drawmaze
Func update_progress()
GUICtrlSetData($Progress1, 100 / ($xBlocks * $yBlocks - $xBlocks - $yBlocks) * $kasten, "")
EndFunc ;==>update_progress
Func GDIPlus_GraphicsDrawLine($hGraphics, $iX1, $iY1, $iX2, $iY2, $hPen = $black);kein errorhandling kein zeitverlust :D
DllCall($__g_hGDIPDll, "int", "GdipDrawLineI", "handle", $hGraphics, "handle", $hPen, "int", $iX1, "int", $iY1, "int", $iX2, "int", $iY2)
EndFunc ;==>GDIPlus_GraphicsDrawLine
Alles anzeigen
€: C Version im Anhang mit Visual Studio 2015 erstellt Maze in C++.zip