Jump to content

Maze Generator


playjacob
 Share

Recommended Posts

Here the live view version:

;~ #AutoIt3Wrapper_Au3Check_Stop_OnWarning=y
;~ #AutoIt3Wrapper_AU3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7

;Thanks to MvGulik (http://www.autoitscript.com/forum/user/14111-mvgulik/)  for cleaning up the code. And for RND_SeedTimed function

#region Decleres and includes
;Add the needed includes
#include <Array.au3>
#include <GDIPlus.au3>

_GDIPlus_Startup()
Global $Progress = 0
Global $hBMP, $hGUI, $hGraphic, $show = False
Global Const $iW = 3, $iH = 3
AdlibRegister("ProgressUpdate") ; Run ProgressUpdate function each 500 ms.

#endregion Decleres and includes

___MAIN___(30, 30, 1234567890);First two paramenter are size. Third is Seed!

AdlibUnRegister("ProgressUpdate")

If $show Then
    Do
    Until GUIGetMsg() = -3
    GUIDelete()
    _GDIPlus_GraphicsDispose($hGraphic)
EndIf

_GDIPlus_Shutdown()
If @error Then Exit @error ;; allouw for normal exit in case there is no error. (as exit 0 will also register as forced exit)
Exit

Func ___MAIN___($iMazeX, $iMazeY, $iRndSeed = Default, $bShow = True)
    $iRndSeed = RND_SeedTimed($iRndSeed) ; 1% of progress
    ConsoleWrite('$iRndSeed = ' & $iRndSeed & @CRLF)
    $Progress += 1 ; increase progress by 1

    ;; ... like:
    Local $sBaseName = 'Maze_(' & String($iRndSeed) & ') (' & String($iMazeX) & 'x' & String($iMazeY) & ')'
    Local $aiSize[2] = [$iMazeX, $iMazeY] ;$aiSize[0] Equals Number of Rows in each colum and $aiSize[1] equals number of Colums

    ;Generate the maze it will be stored in $aCells
    Local $aCells = _;This is where the maze will be stored ; It will store witch walls are intact
    Generate_Maze($aiSize, $Progress) ; 25.5% of progress

    If $bShow Then
        $hGUI = GUICreate("Live", $iMazeX * $iW * $iH, $iMazeY * $iW * $iH)
        GUISetState()
        $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)
        $show = True
    EndIf

    Draw_Maze_Image($aiSize, $aCells, $sBaseName, $Progress) ; 24.5% of progress


    Local $aCurrentPath = Solve_Maze($aiSize, $aCells, $Progress) ; 25.5% of progress
    Solve_Maze_ImgDraw($aiSize, $aCurrentPath, $sBaseName, $Progress) ; 23.5% of progress

    ConsoleWrite($Progress&@CRLF)

    Return SetError(@error, @extended, 0)
EndFunc   ;==>___MAIN___

;; ============================================================================================================== ;;

Func Generate_Maze(Const ByRef $aiSize, ByRef $Progress)
    Local Const $iTotalCells = $aiSize[0] * $aiSize[1]
    Local $iMoveToCell ; What cell to move to
    Local $aCellstack[$iTotalCells][2];This stores with sequnce the cell got generated in. used for backtracing. First dimension is Row. Second is Colum
    Local $iCurrentCellStackNumber = 0 ; Current subscript number to write to in $aCellstack
    Local $aCurrentCellStack[2] ; USed as a temp storage of a bit of cellstack. First dimension is Row. Second is Colum
    Local $iUnvisitedCells = $iTotalCells ; Number of cell that are unvisited
    Local $sNeighbours = ''
    Local $sNeighbourOk
    Local $iRndDirection
    Local $aCurrentCellRowColum

    ;; setup cell array.
    Local $aCells[$iTotalCells];This is where the maze will be stored ; It will store witch walls are intact
    Local $iCurrentCell = Random(0, $iTotalCells - 1, 1) ;; set random start point/cell

    ;Make all walls be intact by filling the cells array with 1111
    array_filler($aCells, '1111')
    Local $aVisitedCells[$iTotalCells]
    array_filler($aVisitedCells, False)

    While 1
        ;Mark as visited and add to the cell stack
        $aCurrentCellRowColum = AddToCellStack($iCurrentCell, $iCurrentCellStackNumber, $aCellstack, $aiSize) ;; $iCurrentCell not used in function.
        ;Check to see if it sould stop createing the maze
        If $iUnvisitedCells <> 0 Then
            ;Check to see if the current cell has any neighbours there are unvisited
            $sNeighbours = _Neighbours($aCurrentCellRowColum, $iCurrentCell, $aVisitedCells, $aiSize)
            If $sNeighbours <> "0000" Then
                ;Choose a random unvisited Neighbour
                Do
                    $iRndDirection = Random(0, 3, 1)
                    $sNeighbourOk = StringMid($sNeighbours, $iRndDirection + 1, 1)
                Until $sNeighbourOk = "1"
                Switch $iRndDirection ;Witch side to move to
                    Case 0 ; Move Up
                        $iMoveToCell = $iCurrentCell - $aiSize[1]
                    Case 1 ; Move Right
                        $iMoveToCell = $iCurrentCell + 1
                    Case 2 ; Move Down
                        $iMoveToCell = $iCurrentCell + $aiSize[1]
                    Case 3 ; Move Left
                        $iMoveToCell = $iCurrentCell - 1
                EndSwitch
                BustWall($iCurrentCell, $iMoveToCell, $iRndDirection, $aCells)
                $iCurrentCell = $iMoveToCell
                ;Make the current cell visited
                $aVisitedCells[$iCurrentCell] = True
                $iUnvisitedCells -= 1
            Else
                $aCurrentCellStack[0] = $aCellstack[$iCurrentCellStackNumber - 2][0] ; Get row of last item in cellstack
                $aCurrentCellStack[1] = $aCellstack[$iCurrentCellStackNumber - 2][1] ; Get colum of last item in cellstack
                $iCurrentCell = _GetCellPos($aiSize, $aCurrentCellStack) ; Combine row and colum to get pos
                $iCurrentCellStackNumber -= 2 ; This will ensure that the used cell from the cellstack will be overwritten
            EndIf
        Else
            ExitLoop
        EndIf

        ;Update the progress
        $Progress = Map($iUnvisitedCells, $iTotalCells, 0, 0, 25.5) + 1
    WEnd

    $Progress = 25.5 ; Update progress

    Return $aCells
EndFunc   ;==>Generate_Maze

Func Draw_Maze_Image(Const ByRef $aiSize, ByRef Const $aCells, ByRef Const $sFilename, ByRef $Progress)
    Local Const $iTotalCells = $aiSize[0] * $aiSize[1]

    Local $aImageRowColum
    $hBMP = _GDIPlus_BitmapCreateFromScan0($aiSize[1] * 9, $aiSize[0] * 9) ;Define the size of the maze (in bmp)
    Local $hCtx=  _GDIPlus_ImageGetGraphicsContext($hBMP)
    Local $hBrush = _GDIPlus_BrushCreateSolid(0xFF000000)
    ;Draw the maze with no walls
    For $i = 0 To $iTotalCells - 1
        $aImageRowColum = _GetCellPos($aiSize, $i)
        _GDIPlus_GraphicsFillRect($hCtx, $aImageRowColum[0] * 9, $aImageRowColum[1] * 9, $iW, $iH, $hBrush)
        _GDIPlus_GraphicsFillRect($hCtx,  6 + $aImageRowColum[0] * 9, $aImageRowColum[1] * 9, $iW, $iH, $hBrush)
        _GDIPlus_GraphicsFillRect($hCtx,  $aImageRowColum[0] * 9, 6 + $aImageRowColum[1] * 9, $iW, $iH, $hBrush)
        _GDIPlus_GraphicsFillRect($hCtx, 6 + $aImageRowColum[0] * 9, 6 + $aImageRowColum[1] * 9, $iW, $iH, $hBrush)
        If $show Then
            _GDIPlus_GraphicsFillRect($hGraphic, $aImageRowColum[0] * 9, $aImageRowColum[1] * 9, $iW, $iH, $hBrush)
            _GDIPlus_GraphicsFillRect($hGraphic,  6 + $aImageRowColum[0] * 9, $aImageRowColum[1] * 9, $iW, $iH, $hBrush)
            _GDIPlus_GraphicsFillRect($hGraphic,  $aImageRowColum[0] * 9, 6 + $aImageRowColum[1] * 9, $iW, $iH, $hBrush)
            _GDIPlus_GraphicsFillRect($hGraphic, 6 + $aImageRowColum[0] * 9, 6 + $aImageRowColum[1] * 9, $iW, $iH, $hBrush)
        EndIf
        $Progress = Map($i, 0, $iTotalCells-1, 0, 10) + 26.5 ; Update progress
    Next

    ;Then Draw the wall on the cells
    For $i = 0 To $iTotalCells - 1

        $aImageRowColum = _GetCellPos($aiSize, $i)
        If StringMid($aCells[$i], 1, 1) = "1" Then
            _GDIPlus_GraphicsFillRect($hCtx, 3 + $aImageRowColum[1] * 9, $aImageRowColum[0] * 9, $iW, $iH, $hBrush)
            If $show Then _GDIPlus_GraphicsFillRect($hGraphic, 3 + $aImageRowColum[1] * 9, $aImageRowColum[0] * 9, $iW, $iH, $hBrush)
        EndIf
        If StringMid($aCells[$i], 2, 1) = "1" Then
            _GDIPlus_GraphicsFillRect($hCtx, 6 + $aImageRowColum[1] * 9, 3 + $aImageRowColum[0] * 9, $iW, $iH, $hBrush)
            If $show Then _GDIPlus_GraphicsFillRect($hGraphic, 6 + $aImageRowColum[1] * 9, 3 + $aImageRowColum[0] * 9, $iW, $iH, $hBrush)
        EndIf
        If StringMid($aCells[$i], 3, 1) = "1" Then
            _GDIPlus_GraphicsFillRect($hCtx, 3 + $aImageRowColum[1] * 9, 6 + $aImageRowColum[0] * 9, $iW, $iH, $hBrush)
            If $show Then _GDIPlus_GraphicsFillRect($hGraphic, 3 + $aImageRowColum[1] * 9, 6 + $aImageRowColum[0] * 9, $iW, $iH, $hBrush)
        EndIf
        If StringMid($aCells[$i], 4, 1) = "1" Then
            _GDIPlus_GraphicsFillRect($hCtx, $aImageRowColum[1] * 9, 3 + $aImageRowColum[0] * 9, $iW, $iH, $hBrush)
            If $show Then _GDIPlus_GraphicsFillRect($hGraphic, $aImageRowColum[1] * 9, 3 + $aImageRowColum[0] * 9, $iW, $iH, $hBrush)
        EndIf

        $Progress = Map($i, 0, $iTotalCells-1, 0, 10) + 36.5 ; Update progress
    Next

    ;Draw start and exit.
    ;Start will be green and exit will be red
    _GDIPlus_BrushSetSolidColor($hBrush, 0xFF00FF00)
    _GDIPlus_GraphicsFillRect($hCtx, 3, 3, $iW, $iH, $hBrush) ; Draw a green cube in the first cell(Top Left Corner)
    If $show Then _GDIPlus_GraphicsFillRect($hGraphic, 3, 3, $iW, $iH, $hBrush) ; Draw a green cube in the first cell(Top Left Corner)
    $aImageRowColum = _GetCellPos($aiSize, $iTotalCells - 1);Get row and colum of the last cell in the maze
    _GDIPlus_BrushSetSolidColor($hBrush, 0xFFFF0000)
    _GDIPlus_GraphicsFillRect($hCtx, 3 + $aImageRowColum[1] * 9, 3 + $aImageRowColum[0] * 9, $iW, $iH, $hBrush) ; Draw a red cube in the last cell (Buttom right corner)
    If $show Then _GDIPlus_GraphicsFillRect($hGraphic, 3 + $aImageRowColum[1] * 9, 3 + $aImageRowColum[0] * 9, $iW, $iH, $hBrush) ; Draw a red cube in the last cell (Buttom right corner)
    $Progress += 1.5 ; Update progress

    ;And finaly save the bmp as Maze.bmp
    _GDIPlus_ImageSaveToFile($hBMP, @ScriptDir & "" & $sFilename & ".png")

    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_GraphicsDispose($hCtx)

    $Progress = 51 ; Update progress

EndFunc   ;==>Draw_Maze_Image

Func Solve_Maze(Const ByRef $aiSize, ByRef $aCells, ByRef $Progress)
    Local Const $iTotalCells = $aiSize[0] * $aiSize[1]
    Local $aCurrentPath[$iTotalCells] ; Will store the current solved path

    Local $aSolveVisitedCells[$iTotalCells] ;This will store if the solver has been to a cell yet or not
    Local $iCurrentPathSubscriptNumber = -1 ; Current subscript number to write to in $aCurrentPath
    Local $iCurrentCell = 0

    AddToCurrentPath($iCurrentCell, $iCurrentPathSubscriptNumber, $aCurrentPath) ; Add the cell the the path
    $aSolveVisitedCells[$iCurrentCell] = 1;Mark cell as visited

    ;Loop until the path has been found
    Local $CanGoOrNot
    Local $aYX[2] ; Store Y and X in an array ; used in solveing the maze
    While 1
        ;Find a direction to go
        For $iDirection = 0 To 3
            ;;If $iDirection = 4 Then ExitLoop
            $aYX = _GetCellPos($aiSize, $iCurrentCell); Convert it to rows and colums
            $CanGoOrNot = CanGo($aYX[0], $aYX[1], $iDirection, $aCells, $aSolveVisitedCells, $aiSize) ; Check if it can go there
            If $CanGoOrNot = 1 Then ExitLoop
        Next
        If $iDirection <> 4 Then
            Switch $iDirection
                Case 0 ; Up
                    $iCurrentCell -= $aiSize[0]
                Case 1 ; Right
                    $iCurrentCell += 1
                Case 2 ; Down
                    $iCurrentCell += $aiSize[0]
                Case 3 ; Left
                    $iCurrentCell -= 1
            EndSwitch
            AddToCurrentPath($iCurrentCell, $iCurrentPathSubscriptNumber, $aCurrentPath) ; Add the cell the the path
            $aSolveVisitedCells[$iCurrentCell] = True;Mark cell as visited
        Else
            If $iCurrentPathSubscriptNumber > 0 Then
                $iCurrentCell = $aCurrentPath[$iCurrentPathSubscriptNumber - 1]

                $iCurrentPathSubscriptNumber -= 1
                ;Else
                ; $iCurrentPathSubscriptNumber -= 1
            EndIf
        EndIf
        If $iCurrentCell = $iTotalCells - 1 Then ExitLoop
    WEnd

    $Progress = 76.5 ; Update progress

    Return $aCurrentPath
EndFunc   ;==>Solve_Maze

Func Solve_Maze_ImgDraw(Const ByRef $aiSize, ByRef $aCurrentPath, Const ByRef $sFilename, ByRef $Progress)
    Local Const $iTotalCells = $aiSize[0] * $aiSize[1]

    ;This function will use functions from the Drawing Functions region
    ;Open The Generated maze as a bmp handle
    Local $hBMP = _GDIPlus_BitmapCreateFromFile(@ScriptDir & "" & $sFilename & ".png")
    Local $hCtx=  _GDIPlus_ImageGetGraphicsContext($hBMP)
    Local $hBrush = _GDIPlus_BrushCreateSolid(0xFFFFFF00)
    Local $aCurrentRowAndColum

    ;Go thoug all the cells one by one
    For $i = 0 To UBound($aCurrentPath) - 1
        If $aCurrentPath[$i] = $iTotalCells - 1 Then ExitLoop
        If $aCurrentPath[$i] <> "" Then

            $aCurrentRowAndColum = _GetCellPos($aiSize, $aCurrentPath[$i])
            _GDIPlus_GraphicsFillRect($hCtx, 9 * $aCurrentRowAndColum[1] + 3, 9 * $aCurrentRowAndColum[0] + 3, $iW, $iH, $hBrush)
            If $show Then _GDIPlus_GraphicsFillRect($hGraphic, 9 * $aCurrentRowAndColum[1] + 3, 9 * $aCurrentRowAndColum[0] + 3, $iW, $iH, $hBrush)
            If $aCurrentPath[$i] - $aiSize[0] = $aCurrentPath[$i + 1] Then ; Up
                _GDIPlus_GraphicsFillRect($hCtx, 9 * $aCurrentRowAndColum[1] + 3, 9 * $aCurrentRowAndColum[0], $iW, $iH, $hBrush)
                _GDIPlus_GraphicsFillRect($hCtx, 9 * $aCurrentRowAndColum[1] + 3, 9 * $aCurrentRowAndColum[0] - 3, $iW, $iH, $hBrush)
                If $show Then
                    _GDIPlus_GraphicsFillRect($hGraphic, 9 * $aCurrentRowAndColum[1] + 3, 9 * $aCurrentRowAndColum[0], $iW, $iH, $hBrush)
                    _GDIPlus_GraphicsFillRect($hGraphic, 9 * $aCurrentRowAndColum[1] + 3, 9 * $aCurrentRowAndColum[0] - 3, $iW, $iH, $hBrush)
                EndIf
            ElseIf $aCurrentPath[$i] + 1 = $aCurrentPath[$i + 1] Then ;Right
                _GDIPlus_GraphicsFillRect($hCtx, 9 * $aCurrentRowAndColum[1] + 6, 9 * $aCurrentRowAndColum[0] + 3, $iW, $iH, $hBrush)
                _GDIPlus_GraphicsFillRect($hCtx, 9 * $aCurrentRowAndColum[1] + 9, 9 * $aCurrentRowAndColum[0] + 3, $iW, $iH, $hBrush)
                If $show Then
                    _GDIPlus_GraphicsFillRect($hGraphic, 9 * $aCurrentRowAndColum[1] + 6, 9 * $aCurrentRowAndColum[0] + 3, $iW, $iH, $hBrush)
                    _GDIPlus_GraphicsFillRect($hGraphic, 9 * $aCurrentRowAndColum[1] + 9, 9 * $aCurrentRowAndColum[0] + 3, $iW, $iH, $hBrush)
                EndIf
            ElseIf $aCurrentPath[$i] + $aiSize[0] = $aCurrentPath[$i + 1] Then ; Down
                _GDIPlus_GraphicsFillRect($hCtx, 9 * $aCurrentRowAndColum[1] + 3, 9 * $aCurrentRowAndColum[0] + 6, $iW, $iH, $hBrush)
                _GDIPlus_GraphicsFillRect($hCtx, 9 * $aCurrentRowAndColum[1] + 3, 9 * $aCurrentRowAndColum[0] + 9, $iW, $iH, $hBrush)
                If $show Then
                    _GDIPlus_GraphicsFillRect($hGraphic, 9 * $aCurrentRowAndColum[1] + 3, 9 * $aCurrentRowAndColum[0] + 6, $iW, $iH, $hBrush)
                    _GDIPlus_GraphicsFillRect($hGraphic, 9 * $aCurrentRowAndColum[1] + 3, 9 * $aCurrentRowAndColum[0] + 9, $iW, $iH, $hBrush)
                EndIf
            ElseIf $aCurrentPath[$i] - 1 = $aCurrentPath[$i + 1] Then ;LEft
                _GDIPlus_GraphicsFillRect($hCtx, 9 * $aCurrentRowAndColum[1], 9 * $aCurrentRowAndColum[0] + 3, $iW, $iH, $hBrush)
                _GDIPlus_GraphicsFillRect($hCtx, 9 * $aCurrentRowAndColum[1] - 3, 9 * $aCurrentRowAndColum[0] + 3, $iW, $iH, $hBrush)
                If $show Then
                    _GDIPlus_GraphicsFillRect($hGraphic, 9 * $aCurrentRowAndColum[1], 9 * $aCurrentRowAndColum[0] + 3, $iW, $iH, $hBrush)
                    _GDIPlus_GraphicsFillRect($hGraphic, 9 * $aCurrentRowAndColum[1] - 3, 9 * $aCurrentRowAndColum[0] + 3, $iW, $iH, $hBrush)
                EndIf
            EndIf
        EndIf

        $Progress = Map($i, 0, UBound($aCurrentPath) - 1, 0, 22.5) + 76.5 ; Update progress
    Next

    ;reDraw start and exit.
    ;Start will be green and exit will be red
    _GDIPlus_BrushSetSolidColor($hBrush, 0xFF00FF00)
    _GDIPlus_GraphicsFillRect($hCtx, 3, 3, $iW, $iH, $hBrush) ; Draw a green cube in the first cell(Top Left Corner)
    If $show Then _GDIPlus_GraphicsFillRect($hGraphic, 3, 3, $iW, $iH, $hBrush)
    Local $aImageRowColum = _GetCellPos($aiSize, $iTotalCells - 1);Get row and colum of the last cell in the maze
    _GDIPlus_BrushSetSolidColor($hBrush, 0xFFFF0000)
    _GDIPlus_GraphicsFillRect($hCtx, 3 + $aImageRowColum[1] * 9, 3 + $aImageRowColum[0] * 9, $iW, $iH, $hBrush) ; Draw a red cube in the last cell (Buttom right corner)
    If $show Then _GDIPlus_GraphicsFillRect($hGraphic, 3 + $aImageRowColum[1] * 9, 3 + $aImageRowColum[0] * 9, $iW, $iH, $hBrush)
    ;And finaly save th bmp as Maze.bmp
    _GDIPlus_ImageSaveToFile($hBMP, @ScriptDir & "" & $sFilename & "_Solved.png")

    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_BitmapDispose($hBMP)
    _GDIPlus_GraphicsDispose($hCtx)

    $Progress = 100 ; Update progress
EndFunc   ;==>Solve_Maze_ImgDraw

#region Maze generation functions
Func BustWall($Cell1, $Cell2, $iDirection, ByRef $aCells) ; This function will remove the walls in two adjacent cells. Direction is from first cell to second. Direction can be from 0 - 3. 0 = Up, 1 = Right, 2 = Down, 3 = Left
    $aCells[$Cell1] = StringReplace($aCells[$Cell1], $iDirection + 1, "0", 1, 2) ; Bust the wall between cell1 and cell2 in cell1
    FlipDirection_br($iDirection)
    $aCells[$Cell2] = StringReplace($aCells[$Cell2], $iDirection + 1, "0", 1, 2) ; Bust the wall between cell1 and cell2 in cell2
EndFunc   ;==>BustWall

Func AddToCellStack($iCurrentCell, ByRef $iCurrentCellStackNumber, ByRef $aCellstack, Const ByRef $aiSize); This function will add the $Cell to the $aCellstack at the subscript of $CurretCellStackNumber
    ;Convert to Rows and colums
    Local $aCurrentCellRowColum = _GetCellPos($aiSize, $iCurrentCell)
    ;Add cell to the cell stack
    $aCellstack[$iCurrentCellStackNumber][0] = $aCurrentCellRowColum[0]
    $aCellstack[$iCurrentCellStackNumber][1] = $aCurrentCellRowColum[1]
    ;Add one to $iCurrentCellStackNumber
    $iCurrentCellStackNumber += 1
    Return $aCurrentCellRowColum
EndFunc   ;==>AddToCellStack

Func _Neighbours(Const ByRef $aCurrentCellRowColum, $Cell, ByRef Const $aVisitedCells, Const ByRef $aiSize) ; Check for Neighbours and store them in a string an 1 means that the neighbour has not been visited and an 0 means the neighbour has been visited it also checks for the edge of the maze.
    Local $NeighbourRowColum, $sNeighbours = ''

    Local Const $iTotalCells = $aiSize[0] * $aiSize[1]

    ;Check Clockwise
    ;Check Above cell
    If ($Cell - $aiSize[1] >= 0) And ($aVisitedCells[$Cell - $aiSize[1]] = False) Then
        $sNeighbours &= "1"
    Else
        $sNeighbours &= "0"
    EndIf
    ;Check Right Cell
    $NeighbourRowColum = _GetCellPos($aiSize, $Cell + 1)
    If ($aCurrentCellRowColum[0] >= $NeighbourRowColum[0]) And ($Cell + 1 < $iTotalCells) And ($aVisitedCells[$Cell + 1] = False) Then
        $sNeighbours &= "1"
    Else
        $sNeighbours &= "0"
    EndIf
    ;Check Buttom Cell
    If ($Cell + $aiSize[1] < $iTotalCells) And ($aVisitedCells[$Cell + $aiSize[1]] = False) Then
        $sNeighbours &= "1"
    Else
        $sNeighbours &= "0"
    EndIf
    ;Check Left Cell
    $NeighbourRowColum = _GetCellPos($aiSize, $Cell - 1)
    If ($aCurrentCellRowColum[0] <= $NeighbourRowColum[0]) And ($Cell - 1 >= 0) And ($aVisitedCells[$Cell - 1] = False) Then
        $sNeighbours &= "1"
    Else
        $sNeighbours &= "0"
    EndIf
    Return $sNeighbours
EndFunc   ;==>_Neighbours
#endregion Maze generation functions

#region Maze solveing Functions
Func CanGo($y, $x, ByRef Const $iDirection, ByRef Const $aCells, ByRef Const $aSolveVisitedCells, Const ByRef $aiSize);Returns 1 if the direction can the traveled and if not it will return 0. $Y = Row, $x = Colum, $iDirection = Direction
    Local $aYX[2] = [$y, $x]
    If StringMid($aCells[_GetCellPos($aiSize, $aYX)], $iDirection + 1, 1) = "0" Then
        Switch $iDirection
            Case 0 ; Up
                $aYX[0] -= 1
            Case 1 ; Right
                $aYX[1] += 1
            Case 2 ; Down
                $aYX[0] += 1
            Case 3 ; Left
                $aYX[1] -= 1
        EndSwitch
        If ($aSolveVisitedCells[_GetCellPos($aiSize, $aYX)] <> True) Then Return 1 ; IF cell has not been seen before by the solver
    EndIf
    Return 0
EndFunc   ;==>CanGo

Func AddToCurrentPath(ByRef Const $Cell, ByRef $iCurrentPathSubscriptNumber, ByRef $aCurrentPath)
    $iCurrentPathSubscriptNumber += 1
    $aCurrentPath[$iCurrentPathSubscriptNumber] = $Cell
EndFunc   ;==>AddToCurrentPath
#endregion Maze solveing Functions

#region Global Functions
Func _GetCellPos(Const ByRef $aiSize, $vFind) ; This function will make a row and a colum into a Pos to be used with $aCells or $aCellstack, Or it will Make a Pos into an array with row and colum
    If IsArray($vFind) Then
        Local $CellPos = $vFind[0] * $aiSize[1] + $vFind[1]
        Return $CellPos
    Else
        Local $aCellRowColum[2] ; Will be used in the _GetCellPos function to temp.. store an array
        $aCellRowColum[0] = Int($vFind / $aiSize[1])
        $aCellRowColum[1] = $vFind - ($aCellRowColum[0] * $aiSize[1])
        Return $aCellRowColum
    EndIf
EndFunc   ;==>_GetCellPos

Func FlipDirection_br(ByRef $iDirection) ; Flips the direction
    If $iDirection > 1 Then
        $iDirection -= 2
    Else
        $iDirection += 2
    EndIf
EndFunc   ;==>FlipDirection_br

Func FlipDirection($iDirection) ; Flips the direction
    If $iDirection > 1 Then Return $iDirection - 2
    Return $iDirection + 2
EndFunc   ;==>FlipDirection

Func array_filler(ByRef $aArray, $vFiller) ; Fills $aArray with $vFiller
    For $i = 0 To UBound($aArray) - 1
        $aArray[$i] = $vFiller
    Next
EndFunc   ;==>array_filler

Func RND_SeedTimed($iSeed = Default) ;; Set seed base on current timer value. Returns used seed value.
    Local Const $INT31u = Int('0x0080000000') ;; (2^31), int64. (2147483648)
    Local Const $INT32u = Int('0x0100000000') ;; (2^32), int64. (4294967296)
    If Not IsNumber($iSeed) Then
        $iSeed = Int(Mod(Int(TimerInit()), $INT32u) - ($INT31u), 1) ;; wraps to [-2^31 and 2^31-1]. (has value shift)
    EndIf
    SRandom($iSeed)
    Return SetError(@error, @extended, $iSeed)
EndFunc   ;==>RND_SeedTimed

Func Map($iValue, $iFromLow, $iFromHigh, $iToLow, $iToHigh)
    Return ($iValue - $iFromLow) * ($iToHigh - $iToLow) / ($iFromHigh - $iFromLow) + $iTolow
EndFunc

Func ProgressUpdate()
    ConsoleWrite($Progress&@CRLF)
EndFunc
#endregion Global Functions

#region GDI+
Func _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight, $iStride = 0, $iPixelFormat = 0x0026200A, $pScan0 = 0)
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $iWidth, "int", $iHeight, "int", $iStride, "int", $iPixelFormat, "ptr", $pScan0, "int*", 0)
    If @error Then Return SetError(@error, @extended, 0)
    Return $aResult[6]
EndFunc   ;==>_GDIPlus_BitmapCreateFromScan0
#endregion

Br,

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

  • Replies 46
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Posted Images

Maze identification results in something really useful.

Hold on. Maze identification is something different than comparing two mazes. (As I'm reading 'comparing' as actually doing something with the differences between two mazes.

If your looking for some unique ID, that is not limited or related to the Autoit generated mazes. You just glue all those cell data parts together and generate a check-sum code on then. Like MD5, CRC, etc

Something like: $ID = MD5("0110" + "1001" + ...)

How would you do that?

I have no idea on how to add extra dificulty to a maze witch was made useing the recursive backtracker algorithm.

Currently ... I don't know either. Maybe someone else knows something about this.

Here the live view version:

:sorcerer:

Nice :)

---

http://en.wikipedia.org/wiki/Maze (seems a good page on mazes, for starters)

- http://www.mazeworks.com/mazegen/index.htm

- http://en.wikipedia.org/wiki/Maze_generation_algorithm

- http://en.wikipedia.org/wiki/Maze_solving_algorithm

Edited by MvGulik

"Straight_and_Crooked_Thinking" : A "classic guide to ferreting out untruths, half-truths, and other distortions of facts in political and social discussions."
"The Secrets of Quantum Physics" : New and excellent 2 part documentary on Quantum Physics by Jim Al-Khalili. (Dec 2014)

"Believing what you know ain't so" ...

Knock Knock ...
 

Link to comment
Share on other sites

Here the live view version:

@UEZ

Try this maze (30x40):

___MAIN___(30, 40, 1234567890)

or (40x30)

___MAIN___(40, 30, 1234567890)

Your script is failed.

:(

Like MD5, CRC, etc

@MvGulik:

Line "0110" can be expressed as hexadecimal 6, "1001" = 9, "1111" = F.

If so then some maze (4x4) can be written (identified) by following 4 binary lines ID without CRC or others :

1AFC

AB63

4532

FFBB

Contrariwise: Any binary is some maze!

Edited by ValeryVal

The point of world view

Link to comment
Share on other sites

@ValeryVal: I only added the GDI+ stuff without changing anything of the maze code. It crashed also with code from post#1. ;)

Br,

UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Line "0110" can be expressed as hexadecimal 6, "1001" = 9, "1111" = F.

If so then some maze (4x4) can be written (identified) by following 4 binary lines ID without CRC or others :

Hex: I know about the Hex, or better, the BitMask way. (already been using those it in my own maze testing codes.).

No Crc: Not to sure If I get you right. But not using a check-sum value for generating a unique maze ID is not a good way. It might seem ok for small mazes. But something like that also needs to work on really big mazes. (your just putting the whole maze into a string-stream form. That's not really a ID. Its just the maze data put in a none graphical form.)

Crash: ... ?

Its generally a good thing to check your own, and others, code with the general Au3Check lines.

#AutoIt3Wrapper_Au3Check_Stop_OnWarning=y
#AutoIt3Wrapper_AU3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7

[[doh. bugged code box cleanup.]

Edited by MvGulik

"Straight_and_Crooked_Thinking" : A "classic guide to ferreting out untruths, half-truths, and other distortions of facts in political and social discussions."
"The Secrets of Quantum Physics" : New and excellent 2 part documentary on Quantum Physics by Jim Al-Khalili. (Dec 2014)

"Believing what you know ain't so" ...

Knock Knock ...
 

Link to comment
Share on other sites

UPDATED:

Now with gui!

Option to solve the maze or not.

Progress bar.

Seeds, uses a random if none are given.

Minor spelling fixes.

Edit: Anyone knows how to rename a topic?

Edited by playjacob
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...