Sign in to follow this  
Followers 0

Maze Generator


47 posts in this topic

#21 ·  Posted

Erm ... right, broke something again while trying to reformat the OP's code. ... back to debugging >_<

Anyway, here's something that might be of some use in relation to slapping a ID on a particular maze. (needs maze size dimensions to of course to complete the reproducibility.)

;; use
dim $iUsedSeed = RND_SeedTimed() ;; return used random seed value. [int32]
;; or
dim $iUsedSeed = RND_SeedTimed(1234567890) ;; uses given seed. (Should be a Int32-range value. CQ: Anything else is untested.)

;; UDF code
Global Const $INT31u = Int('0x0080000000') ;; (2^31), int64(2147483648)
Global Const $INT32u = Int('0x0100000000') ;; (2^32), int64(4294967296)
Func RND_SeedTimed($iSeed=Default) ;; Set seed base on current timer value. Returns used seed value.
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 $iSeed
EndFunc

You want me to add that code?

Where?

I don't totally know what it's for.

So what's it doing?

Share this post


Link to post
Share on other sites



#22 ·  Posted (edited)

When AutoIt starts it sets a random seed (I think, not tested it again for some time). Which determent's the random data output sequence. (same seed, same random date. Or same maze.)

But that initial used seed is unknown. This function will do about the same, while spitting out the used Seed value for the random generator. (So, in case there is some odd maze that's triggering a problem case. You can reproduce it, if you know the used RndSeed.

If you have, or see, some use for it. You can used it (in any way you see fit). If not, your free to ignore it.

[missing text, ...]

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 ...
 

Share this post


Link to post
Share on other sites

#23 ·  Posted (edited)

When AutoIt starts it sets a random seed (I think, not tested it again for some time). Which determent's the random data output sequence. (same seed, same random date. Or same maze.)

But that initial used seed is unknown. This function will do about the same, while spitting out the used Seed value for the random generator. (So, in case there is some odd maze that's triggering a problem case. You can reproduce it, if you know the used RndSeed.

If you have, or see, some use for it. You can used it (in any way you see fit). If not, your free to ignore it.

[missing text, ...]

Do i understand it corrently that the function will set a random seed and output it so that i can generate the same mazes if i got the seed and the size.

If so the i'll defendly add it to the script.

Also: [missing text, ...] ???????

Edited by playjacob

Share this post


Link to post
Share on other sites

#24 ·  Posted (edited)

Yep.

---

Code Rewrite. (Again, You can used what you like and ignore what you don't.)

(Note: I will probably, after some time, clear this code again. See no need for old and stale code version hanging around (just a personal thing).)

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

#cs
    General reformat of maze-generator code posted ... around 1 juli 2012
    (http://www.autoitscript.com/forum/topic/141892-maze-generator/)
    - Turned all root code into appropiate aeperate functions.
    - Ditched all Global variable use.
    - Added leading type characters to variable names.
    - some other minor stuff.
    - Left rest as much as it was.
    Personal:
    - Added Random seed feedback (console only)
    - Added Gui Proccess bar. (mainly as some debug helper)
    -- needs aditional UDF code. See other code block in same post. And the re-enabling of the [PBAR] codes here.
    - This message: http://www.autoitscript.com/forum/topic/141892-maze-generator/page__st__20#entry999212
#ce

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

#region Decleres and includes
;Add the needed includes
#include <Array.au3>
#include "BMP3.au3" ; Downloaded from http://www.autoitscript.com/forum/topic/27362-bitmap-library/
;~ #include "GUI_PBarWin.au3" ;; personal Progress bar UDF [PBAR]

#endregion Decleres and includes

___MAIN___("Maze", 15, 15, 1234567890)
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___($sBaseName, $iMazeX, $iMazeY, $iRndSeed = Default)
    $iRndSeed = RND_SeedTimed($iRndSeed)
    ConsoleWrite('$iRndSeed = ' & $iRndSeed & @CRLF) ;; Could be used to be add to maze name ... if needed ...

    ;; ... like:
    $sBaseName = 'Maze_(' & String($iRndSeed) & ')'
    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)
    Draw_Maze_Image($aiSize, $aCells, $sBaseName)

    Local $aCurrentPath = Solve_Maze($aiSize, $aCells)
    Solve_Maze_ImgDraw($aiSize, $aCurrentPath, $sBaseName)

    Return SetError(@error, @extended, 0)
EndFunc

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

Func Generate_Maze(Const ByRef $aiSize)
    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)

    #cs [PBAR]
        ;; PBAR SETUP - using $iUnvisitedCells, max to zero, needs to be scaled.
        Local $PBar_iD = 0, $PBar_fScale = $iTotalCells / 100, $PBar_iNext = $iUnvisitedCells, $PBar_iStep = 2
        GUI_PBarGui($PBar_iD, 'Generate_Maze', 300, 20)
    #ce
    While 1
        #cs [PBAR]
            ;; PBar ... probebly buged with cell count near and below 100.
            If $iUnvisitedCells <= $PBar_iNext Then
            $PBar_iNext = 100 - Round($iUnvisitedCells / $iTotalCells * 100)
            GUI_PBarUpdate($PBar_iD, $PBar_iNext)
            $PBar_iNext = $iTotalCells - Round($PBar_fScale * ($PBar_iNext + $PBar_iStep))
            EndIf
        #ce

        ;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
    WEnd
    #cs [PBAR]
        GUI_PBarGui($PBar_iD)
    #ce

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

    Local $aImageRowColum
    Local $tBMP = _BMPCreate($aiSize[1] * 9, $aiSize[0] * 9) ;Define the size of the maze (in bmp)

    #cs [PBAR]
        ;; PBAR SETUP - using $iUnvisitedCells, max to zero, needs to be scaled.
        Local $PBar_iD = 0, $PBar_fScale = $iTotalCells / 100, $PBar_iNext = 0, $PBar_iStep = 5
        GUI_PBarGui($PBar_iD, 'Generating with all walls down', 300, 20)
    #ce
    ;Draw the maze with no walls
    For $i = 0 To $iTotalCells - 1
        #cs [PBAR]
            ;; PBAR - probebly buged with cell count near and below 100.
            If $i <= $PBar_iNext Then
            $PBar_iNext = Round($i / $iTotalCells * 100)
            GUI_PBarUpdate($PBar_iD, $PBar_iNext)
            $PBar_iNext = Round($PBar_fScale * ($PBar_iNext + $PBar_iStep))
            EndIf
        #ce
        $aImageRowColum = _GetCellPos($aiSize, $i)
        Draw3By3($tBMP, $aImageRowColum[0] * 9, $aImageRowColum[1] * 9)
        Draw3By3($tBMP, 6 + $aImageRowColum[0] * 9, $aImageRowColum[1] * 9)
        Draw3By3($tBMP, $aImageRowColum[0] * 9, 6 + $aImageRowColum[1] * 9)
        Draw3By3($tBMP, 6 + $aImageRowColum[0] * 9, 6 + $aImageRowColum[1] * 9)
    Next
    #cs [PBAR]
        GUI_PBarGui($PBar_iD)
    #ce
    #cs [PBAR]
        $PBar_fScale = $iTotalCells / 100
        $PBar_iNext = 0
        GUI_PBarGui($PBar_iD, 'Generating with walls', 300, 20)
    #ce
    ;Then Draw the wall on the cells
    For $i = 0 To $iTotalCells - 1
        #cs [PBAR]
            ;; PBAR - probebly buged with cell count near and below 100.
            If $i <= $PBar_iNext Then
            $PBar_iNext = Round($i / $iTotalCells * 100)
            GUI_PBarUpdate($PBar_iD, $PBar_iNext)
            $PBar_iNext = Round($PBar_fScale * ($PBar_iNext + $PBar_iStep))
            EndIf
        #ce

        $aImageRowColum = _GetCellPos($aiSize, $i)
        If StringMid($aCells[$i], 1, 1) = "1" Then
            Draw3By3($tBMP, 3 + $aImageRowColum[1] * 9, $aImageRowColum[0] * 9)
        EndIf
        If StringMid($aCells[$i], 2, 1) = "1" Then
            Draw3By3($tBMP, 6 + $aImageRowColum[1] * 9, 3 + $aImageRowColum[0] * 9)
        EndIf
        If StringMid($aCells[$i], 3, 1) = "1" Then
            Draw3By3($tBMP, 3 + $aImageRowColum[1] * 9, 6 + $aImageRowColum[0] * 9)
        EndIf
        If StringMid($aCells[$i], 4, 1) = "1" Then
            Draw3By3($tBMP, $aImageRowColum[1] * 9, 3 + $aImageRowColum[0] * 9)
        EndIf
    Next

    ;Draw start and exit.
    ;Start will be green and exit will be red
    Draw3By3($tBMP, 3, 3, '00FF00') ; 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
    Draw3By3($tBMP, 3 + + $aImageRowColum[1] * 9, 3 + $aImageRowColum[0] * 9, 'FF0000') ; Draw a red cube in the last cell (Buttom right corner)

    ;And finaly save the bmp as Maze.bmp
    _BMPWrite($tBMP, @ScriptDir & "" & $sFilename & ".bmp")

    #cs [PBAR]
        GUI_PBarGui($PBar_iD)
    #ce

EndFunc
Func Solve_Maze(Const ByRef $aiSize, ByRef $aCells)
    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

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

    ;This region will use functions from the Drawing Functions region
    ;Open The Generated maze as a bmp handle
    Local $tBMP = _BMPOpen(@ScriptDir & "" & $sFilename & ".bmp")

    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])
            Draw3By3($tBMP, 9 * $aCurrentRowAndColum[1] + 3, 9 * $aCurrentRowAndColum[0] + 3, 'FFFF00')
            If $aCurrentPath[$i] - $aiSize[0] = $aCurrentPath[$i + 1] Then ; Up
                Draw3By3($tBMP, 9 * $aCurrentRowAndColum[1] + 3, 9 * $aCurrentRowAndColum[0], 'FFFF00')
                Draw3By3($tBMP, 9 * $aCurrentRowAndColum[1] + 3, 9 * $aCurrentRowAndColum[0] - 3, 'FFFF00')
            ElseIf $aCurrentPath[$i] + 1 = $aCurrentPath[$i + 1] Then ;Right
                Draw3By3($tBMP, 9 * $aCurrentRowAndColum[1] + 6, 9 * $aCurrentRowAndColum[0] + 3, 'FFFF00')
                Draw3By3($tBMP, 9 * $aCurrentRowAndColum[1] + 9, 9 * $aCurrentRowAndColum[0] + 3, 'FFFF00')
            ElseIf $aCurrentPath[$i] + $aiSize[0] = $aCurrentPath[$i + 1] Then ; Down
                Draw3By3($tBMP, 9 * $aCurrentRowAndColum[1] + 3, 9 * $aCurrentRowAndColum[0] + 6, 'FFFF00')
                Draw3By3($tBMP, 9 * $aCurrentRowAndColum[1] + 3, 9 * $aCurrentRowAndColum[0] + 9, 'FFFF00')
            ElseIf $aCurrentPath[$i] - 1 = $aCurrentPath[$i + 1] Then ;LEft
                Draw3By3($tBMP, 9 * $aCurrentRowAndColum[1], 9 * $aCurrentRowAndColum[0] + 3, 'FFFF00')
                Draw3By3($tBMP, 9 * $aCurrentRowAndColum[1] - 3, 9 * $aCurrentRowAndColum[0] + 3, 'FFFF00')
            EndIf
        EndIf
    Next

    ;reDraw start and exit.
    ;Start will be green and exit will be red
    Draw3By3($tBMP, 3, 3, '00FF00') ; Draw a green cube in the first cell(Top Left Corner)
    Local $aImageRowColum = _GetCellPos($aiSize, $iTotalCells - 1);Get row and colum of the last cell in the maze
    Draw3By3($tBMP, 3 + + $aImageRowColum[1] * 9, 3 + $aImageRowColum[0] * 9, 'FF0000') ; Draw a red cube in the last cell (Buttom right corner)

    ;And finaly save th bmp as Maze.bmp
    _BMPWrite($tBMP, @ScriptDir & "" & $sFilename & "_Solved.bmp")
EndFunc

#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

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

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
#endregion Maze generation functions

#region Drawing Functions
Func Draw3By3(ByRef $tBMP, $x, $y, $Colur = '000000') ; This function will draw a 3*3 Cube at a given x and y on the $tBMP
    _PixelWrite($tBMP, $x, $y, $Colur)
    _PixelWrite($tBMP, $x + 1, $y, $Colur)
    _PixelWrite($tBMP, $x + 2, $y, $Colur)
    _PixelWrite($tBMP, $x, $y + 1, $Colur)
    _PixelWrite($tBMP, $x + 1, $y + 1, $Colur)
    _PixelWrite($tBMP, $x + 2, $y + 1, $Colur)
    _PixelWrite($tBMP, $x, $y + 2, $Colur)
    _PixelWrite($tBMP, $x + 1, $y + 2, $Colur)
    _PixelWrite($tBMP, $x + 2, $y + 2, $Colur)
EndFunc
#endregion Drawing 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

Func AddToCurrentPath(ByRef Const $Cell, ByRef $iCurrentPathSubscriptNumber, ByRef $aCurrentPath)
    $iCurrentPathSubscriptNumber += 1
    $aCurrentPath[$iCurrentPathSubscriptNumber] = $Cell
EndFunc
#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

Func FlipDirection_br(ByRef $iDirection) ; Flips the direction
    If $iDirection > 1 Then
        $iDirection -= 2
    Else
        $iDirection += 2
    EndIf
EndFunc
Func FlipDirection($iDirection) ; Flips the direction
    If $iDirection > 1 Then Return $iDirection - 2
    Return $iDirection + 2
;~     Switch $iDirection
;~         Case 0 ; Top
;~             $iDirection = 2 ; Down
;~         Case 1 ; Right
;~             $iDirection = 3 ; left
;~         Case 2 ; down
;~             $iDirection = 0 ; top
;~         Case 3 ; left
;~             $iDirection = 1 ;right
;~     EndSwitch
;~     Return $iDirection
EndFunc
#endregion Global Functions

#region Global code to Function
Func array_filler(ByRef $aArray, $vFiller)
    For $i = 0 To UBound($aArray) - 1
        $aArray[$i] = $vFiller
    Next
EndFunc
;~ Func default_maze_array_fill(ByRef $aCells, ByRef $aVisitedCells) ;; OFF - not used anymore. -> array_filler()
;~ EndFunc
#endregion Global code to Function

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

;; EOF ;;

"GUI_PBarGui.au3"

#include-once
;; NOTE: experimental stuff. Cq: working for me. (so far), cleared of debug litter.
;~ #AutoIt3Wrapper_Au3Check_Stop_OnWarning=y
;~ #AutoIt3Wrapper_AU3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7

#include <WindowsConstants.au3>
Func GUI_PBarGui(ByRef $iPBar, $iTitle = 'Progress.', $iWidth = 400, $iHeight = 20, $iLeft = -1, $iTop = -1, $hPWin = 0, $fOnTop = False) ;; ...
    Local Enum $_ind_
    If Not $iPBar Then ;; optional Default Kw support.
        If $iTitle = Default Then $iTitle = 'ProgressBar.'
        If $iWidth = Default Then $iWidth = 400
        If $iHeight = Default Then $iHeight = 20
        If $iLeft = Default Then $iLeft = -1
        If $iTop = Default Then $iTop = -1
        If $hPWin = Default Then $hPWin = 0
        If $fOnTop = Default Then $fOnTop = False
    EndIf
    Local $aTemp[1][2] = [[0]]
    Local Static $PB_294573_avPB
    If not IsArray($PB_294573_avPB) then $PB_294573_avPB = $aTemp
    Local Static $iGUIOnEvent = Opt("GUIOnEventMode")

    Local Const $GUI_EVENT_CLOSE = -3 ;; <GUIConstants.au3>
    Local Const $PBS_SMOOTH = 1 ;; <GUIConstants.au3>
    Local $hWin

    If $iPBar Then ;; delete target pbar.
        If __GUI_PBar_PopBar($iPBar, $hWin, $PB_294573_avPB) Then
            GUICtrlDelete($iPBar)
            GUIDelete($hWin)
            $iPBar = 0
            $hWin = 0
            If Not $PB_294573_avPB[$_ind_][$_ind_] Then _
                    Opt("GUIOnEventMode", $iGUIOnEvent)
        EndIf

    Else ;; create new pbar.
        Local $iStyle, $iStyleExt
        $iStyle = BitOR($GUI_SS_DEFAULT_GUI, 0)
        $iStyleExt = -1
        If $fOnTop Then $iStyleExt = $WS_EX_TOPMOST
        If Not $PB_294573_avPB[$_ind_][$_ind_] Then
            $iGUIOnEvent = Opt("GUIOnEventMode", 1)
        Elseif Not $iTitle Then
            $iStyle = BitOR($WS_POPUP, $WS_THICKFRAME )
            $hPWin = $PB_294573_avPB[1][1]
        EndIf

        $hWin = GUICreate($iTitle, $iWidth, $iHeight, $iLeft, $iTop, $iStyle, $iStyleExt, $hPWin)
        GUISetOnEvent($GUI_EVENT_CLOSE, '__GUI_PBarExit') ;; linkup ... unconditional full script stop. (same on all pbar's.)
        $iPBar = GUICtrlCreateProgress(0, 0, $iWidth, $iHeight, $PBS_SMOOTH)
        __GUI_PBar_PushBar($PB_294573_avPB, $iPBar, $hWin) ;; add to pbar array.
        GUISetState()
    EndIf
    Return 1
EndFunc
Func GUI_PBarUpdate($iPBar, $iProgress = 0)
    GUICtrlSetData($iPBar, $iProgress)
EndFunc
Func __GUI_PBarExit() ;; ...
    ;; this is for support to stop the script when the gui-bar-window is closed.
    ;; - window minimize option is there to get the pbar out of the way.
    ;; -- erm: only works for the first bpar.?
    Exit
EndFunc
Func __GUI_PBar_PopBar(ByRef Const $iPBar, ByRef $hWin, ByRef $aPB) ;; Return and remove target pbar-data from pbar array.
    Local Enum $_ind_
    Local Enum $_hPBar_, $_hWin_, $iFields_pbar
    Local $iErr = 0
    Do ;; dummy loop.
        For $iRow = 1 To $aPB[$_ind_][$_ind_] ;; find pbar entry
            If $aPB[$iRow][$_hPBar_] = $iPBar Then
                $hWin = $aPB[$iRow][$_hWin_]
                $aPB[$_ind_][$_ind_] -= 1 ;; update index
                For $i = $iRow To $aPB[$_ind_][$_ind_]
                    $aPB[$i][$_hPBar_] = $aPB[$i + 1][$_hPBar_]
                    $aPB[$i][$_hWin_] = $aPB[$i + 1][$_hWin_]
                Next
                ReDim $aPB[$i][$iFields_pbar]
                ExitLoop 2
            EndIf
        Next
        $iErr = 1
    Until 1
    Return SetError($iErr, 0, $iErr = 0)
EndFunc
Func __GUI_PBar_PushBar(ByRef $aPB, ByRef Const $iPBar, ByRef Const $hWin) ;; add new pbar-data to pbar array.
    Local Enum $_ind_
    Local Enum $_hPBar_, $_hWin_, $iFields_pbar
    Local $iRow = $aPB[$_ind_][$_ind_] + 1
    ReDim $aPB[1 + $iRow][$iFields_pbar]
    $aPB[$_ind_][$_ind_] = $iRow
    $aPB[$iRow][$_hWin_] = $hWin
    $aPB[$iRow][$_hPBar_] = $iPBar
EndFunc

;; EOF ;;

[little additional tidy and comments cleanup]

[+ this post link] ... [Which seems to be missing?. Re-added it]

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 ...
 

Share this post


Link to post
Share on other sites

#25 ·  Posted

Yep.

---

Code Rewrite. (Again, You can used what you like and ignore what you don't.)

(Note: I will probably, after some time, clear this code again. See no need for old and stale code version hanging around (just a personal thing).)

[+ this post link]

[little additional tidy and comments cleanup]

I really like it :)

But there seam to be a problem with the RND_SeedTimed function.

I get the error: F:\dokumenter\Autoit3\Maze-Generator-Done.au3(442,67) : ERROR: Int() [built-in] called with wrong number of args.

$iSeed = Int(Mod(Int(TimerInit()), $INT32u) - ($INT31u), 1)

Also what's the difence of FlipDirection and FlipDirection_br?

When the RND_SeedRandom function is working i'll use this code in the first post.

What credits do i have to give to you?

Can i remove the header?

I will properly remove the PBAR sections when i add it.

Next step will be to make it into a command line tool and then use au3Irrlicht2 to make a 3d maze game.

Thank you for cleaning up my scirpt, it's awesome!!!

Share this post


Link to post
Share on other sites

#26 ·  Posted (edited)

But there seam to be a problem with the RND_SeedTimed function.

I get the error: F:dokumenterAutoit3Maze-Generator-Done.au3(442,67) : ERROR: Int() [built-in] called with wrong number of args.

$iSeed = Int(Mod(Int(TimerInit()), $INT32u) - ($INT31u), 1)

Aha. Think your using a older AutoIt version. (ditching the second int() parameter) is not really a problem.)

23rd December, 2011 - v3.3.8.0

...

Changed: Dec(), Int(), Number() have second optional parameter defining non-default behavior.

Also what's the difence of FlipDirection and FlipDirection_br?

FlipDirection() will have the new direction value as function return output. While FlipDirection_br() will change the input variable that was used as function parameter.

Or:

$iDirection = FlipDirection($iDirection)
;; versus
FlipDirection_br($iDirection)

See Function Documentatio on Byref

When the RND_SeedRandom function is working i'll use this code in the first post.

What credits do i have to give to you?

Can i remove the header?

I will properly remove the PBAR sections when i add it.

1) No credit is needed. (but thanks for asking. :) )

2) Sure.

3) Not a problem either

Next step will be to make it into a command line tool and then use au3Irrlicht2 to make a 3d maze game.

Thank you for cleaning up my scirpt, it's awesome!!!

Thanks. Good luck.

[wrong word fix]

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 ...
 

Share this post


Link to post
Share on other sites

#27 ·  Posted

Update:

Added MvGulik's cleaned code.

Added MvGulik's RND_SeedTimed function.

Progress will now be written to the console.

Maze filename will now include both seed and size.

Minor tweeks and spelling corrections.

Code's in the first post!

Again thanks to MvGulik for cleaning the code and for the RND_SeedTimed function.

Share this post


Link to post
Share on other sites

#28 ·  Posted

You forgot the backshlash in the path when you save/load the bitmap.

E.g.:

$BMP = _BMPOpen(@ScriptDir & "Maze.bmp")

Br,

UEZ


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

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯

Share this post


Link to post
Share on other sites

#29 ·  Posted

You forgot the backshlash in the path when you save/load the bitmap.

E.g.:

$BMP = _BMPOpen(@ScriptDir & "Maze.bmp")

Br,

UEZ

Where?

I don't see it anywhere.

Share this post


Link to post
Share on other sites

#30 ·  Posted (edited)

You have updated the code in your 1st post meanwhile.

It looks ok now.

Br,

UEZ

Edited by UEZ

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

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯

Share this post


Link to post
Share on other sites

#31 ·  Posted

It's not aptly that your maze picture is OK just in rectangular case, ie if $iMazeX = $iMazeY.

Try this GUIMaze.au3

#include <GuiConstantsEx.au3>
#include <ScreenCapture.au3>
#include <Misc.au3>
#include <WinAPI.au3>
#include <Array.au3>
; Downloaded from http://www.autoitscript.com/forum/topic/27362-bitmap-library/
#include "BMP3.au3"
#include <GDIPlus.au3>
Global $Caption = "Maze Generator"
Global $FileSaved = @ScriptDir & "Maze.bmp"
Global $vDLL_user32 = DllOpen("user32.dll")
Global $hPic, $Pic
Global $iMazeX = 15, $iMazeY = 15
Global $Generate
Global $Progress = 0
Global $sBaseName = 'Maze'
Global $aiSize[2]
Global $aCells
; Create GUI
$hGUI = GUICreate($Caption, 900, 800)
$Generate = GUICtrlCreateButton('Generate', 10, 10, 100, 20)
$Solve = GUICtrlCreateButton('Solve', 150, 10, 100, 20)
$ToPng = GUICtrlCreateButton('ToPng', 300, 10, 100, 20)

$MazeX_Label = GuiCtrlCreateLabel("Rows:", 10, 60, 60, 20)
GUICtrlSetFont(-1,8,300)
$MazeX_Edit = GuiCtrlCreateInput('25', 70, 60, 100, 20)
GUICtrlSetFont(-1,8,300)
$MazeY_Label = GuiCtrlCreateLabel("Cols:", 10, 90, 60, 20)
GUICtrlSetFont(-1,8,300)
$MazeY_Edit = GuiCtrlCreateInput('25', 70, 90, 100, 20)
GUICtrlSetFont(-1,8,300)
If FileExists($FileSaved) then
$Pic = GUICtrlCreatePic($FileSaved, 190, 60, 700, 700)
else
$Pic = GUICtrlCreatePic("", 190, 60, 700, 700)
endif
$hPic = GUICtrlGetHandle($Pic)
GUISetState()
While 1
$Msg = GUIGetMsg()
switch $Msg
  case $GUI_EVENT_CLOSE
   ExitLoop
  case $Generate
   $Progress = 1
   $iMazeX = GuiCtrlRead($MazeX_Edit)
   $aiSize[0] = Round($iMazeX)
   $iMazeY = GuiCtrlRead($MazeY_Edit)
   $aiSize[1] = Round($iMazeY)
   $aCells = Generate_Maze($aiSize, $Progress)
   Draw_Maze_Image($aiSize, $aCells, $sBaseName, $Progress)
   GUICtrlSetImage ($Pic, @ScriptDir & "" & $sBaseName & ".bmp")
  case $Solve
   $Progress = 1
   $aCurrentPath = Solve_Maze($aiSize, $aCells, $Progress)
   Solve_Maze_ImgDraw($aiSize, $aCurrentPath, $sBaseName, $Progress)
   Draw_Maze_Image($aiSize, $aCells, $sBaseName, $Progress)
   GUICtrlSetImage ($Pic, @ScriptDir & "" & $sBaseName & "_Solved.bmp")
  case $ToPng
    _SaveAsPNG(@ScriptDir & "" & $sBaseName & ".bmp")
    _SaveAsPNG(@ScriptDir & "" & $sBaseName & "_Solved.bmp")
  case else
endswitch
WEnd
_GDIPlus_Shutdown()
DllClose($vDLL_user32)
Exit

;; ============================================================================================================== ;;
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
    Local $tBMP = _BMPCreate($aiSize[1] * 9, $aiSize[0] * 9) ;Define the size of the maze (in bmp)
    ;Draw the maze with no walls
    For $i = 0 To $iTotalCells - 1
        $aImageRowColum = _GetCellPos($aiSize, $i)
        Draw3By3($tBMP, $aImageRowColum[0] * 9, $aImageRowColum[1] * 9)
        Draw3By3($tBMP, 6 + $aImageRowColum[0] * 9, $aImageRowColum[1] * 9)
        Draw3By3($tBMP, $aImageRowColum[0] * 9, 6 + $aImageRowColum[1] * 9)
        Draw3By3($tBMP, 6 + $aImageRowColum[0] * 9, 6 + $aImageRowColum[1] * 9)
        $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
            Draw3By3($tBMP, 3 + $aImageRowColum[1] * 9, $aImageRowColum[0] * 9)
        EndIf
        If StringMid($aCells[$i], 2, 1) = "1" Then
            Draw3By3($tBMP, 6 + $aImageRowColum[1] * 9, 3 + $aImageRowColum[0] * 9)
        EndIf
        If StringMid($aCells[$i], 3, 1) = "1" Then
            Draw3By3($tBMP, 3 + $aImageRowColum[1] * 9, 6 + $aImageRowColum[0] * 9)
        EndIf
        If StringMid($aCells[$i], 4, 1) = "1" Then
            Draw3By3($tBMP, $aImageRowColum[1] * 9, 3 + $aImageRowColum[0] * 9)
        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
    Draw3By3($tBMP, 3, 3, '00FF00') ; 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
    Draw3By3($tBMP, 3 + + $aImageRowColum[1] * 9, 3 + $aImageRowColum[0] * 9, 'FF0000') ; Draw a red cube in the last cell (Buttom right corner)
    $Progress += 1.5 ; Update progress
    ;And finaly save the bmp as Maze.bmp
    _BMPWrite($tBMP, @ScriptDir & "" & $sFilename & ".bmp")
    $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 $tBMP = _BMPOpen(@ScriptDir & "" & $sFilename & ".bmp")
    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])
            Draw3By3($tBMP, 9 * $aCurrentRowAndColum[1] + 3, 9 * $aCurrentRowAndColum[0] + 3, 'FFFF00')
            If $aCurrentPath[$i] - $aiSize[0] = $aCurrentPath[$i + 1] Then ; Up
                Draw3By3($tBMP, 9 * $aCurrentRowAndColum[1] + 3, 9 * $aCurrentRowAndColum[0], 'FFFF00')
                Draw3By3($tBMP, 9 * $aCurrentRowAndColum[1] + 3, 9 * $aCurrentRowAndColum[0] - 3, 'FFFF00')
            ElseIf $aCurrentPath[$i] + 1 = $aCurrentPath[$i + 1] Then ;Right
                Draw3By3($tBMP, 9 * $aCurrentRowAndColum[1] + 6, 9 * $aCurrentRowAndColum[0] + 3, 'FFFF00')
                Draw3By3($tBMP, 9 * $aCurrentRowAndColum[1] + 9, 9 * $aCurrentRowAndColum[0] + 3, 'FFFF00')
            ElseIf $aCurrentPath[$i] + $aiSize[0] = $aCurrentPath[$i + 1] Then ; Down
                Draw3By3($tBMP, 9 * $aCurrentRowAndColum[1] + 3, 9 * $aCurrentRowAndColum[0] + 6, 'FFFF00')
                Draw3By3($tBMP, 9 * $aCurrentRowAndColum[1] + 3, 9 * $aCurrentRowAndColum[0] + 9, 'FFFF00')
            ElseIf $aCurrentPath[$i] - 1 = $aCurrentPath[$i + 1] Then ;LEft
                Draw3By3($tBMP, 9 * $aCurrentRowAndColum[1], 9 * $aCurrentRowAndColum[0] + 3, 'FFFF00')
                Draw3By3($tBMP, 9 * $aCurrentRowAndColum[1] - 3, 9 * $aCurrentRowAndColum[0] + 3, 'FFFF00')
            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
    Draw3By3($tBMP, 3, 3, '00FF00') ; Draw a green cube in the first cell(Top Left Corner)
    Local $aImageRowColum = _GetCellPos($aiSize, $iTotalCells - 1);Get row and colum of the last cell in the maze
    Draw3By3($tBMP, 3 + + $aImageRowColum[1] * 9, 3 + $aImageRowColum[0] * 9, 'FF0000') ; Draw a red cube in the last cell (Buttom right corner)
    ;And finaly save th bmp as Maze.bmp
    _BMPWrite($tBMP, @ScriptDir & "" & $sFilename & "_Solved.bmp")
    $Progress = 100 ; Update progress
EndFunc   ;==>Solve_Maze_ImgDraw
;=====================================
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
;=====================================
Func Draw3By3(ByRef $tBMP, $x, $y, $Colur = '000000') ; This function will draw a 3*3 Cube at a given x and y on the $tBMP
    _PixelWrite($tBMP, $x, $y, $Colur)
    _PixelWrite($tBMP, $x + 1, $y, $Colur)
    _PixelWrite($tBMP, $x + 2, $y, $Colur)
    _PixelWrite($tBMP, $x, $y + 1, $Colur)
    _PixelWrite($tBMP, $x + 1, $y + 1, $Colur)
    _PixelWrite($tBMP, $x + 2, $y + 1, $Colur)
    _PixelWrite($tBMP, $x, $y + 2, $Colur)
    _PixelWrite($tBMP, $x + 1, $y + 2, $Colur)
    _PixelWrite($tBMP, $x + 2, $y + 2, $Colur)
EndFunc   ;==>Draw3By3
#endregion Drawing 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
;=====================================
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 _SaveAsPNG($BMPFile)
Local $hImage, $sCLSID
; Initialize GDI+ library
_GDIPlus_Startup()
; Load image
$hImage = _GDIPlus_ImageLoadFromFile($BMPFile)
; Get PNG encoder CLSID
$sCLSID = _GDIPlus_EncodersGetCLSID("PNG")
; Save image with rotation
_GDIPlus_ImageSaveToFileEx($hImage, StringReplace($BMPFile,".bmp",".png"), $sCLSID)
; Clean up resources
_GDIPlus_ImageDispose($hImage)
; Shut down GDI+ library
_GDIPlus_Shutdown()
EndFunc   ;==>_SaveAsPNG

BTW This script allows to convert big sized bmp into png images.

Thank you


The point of world view

Share this post


Link to post
Share on other sites

#32 ·  Posted

Playing around with backtracking dead-ends.

Maze_[15,15](0x499602D2)_Solved_Animated.gif

Posted Image

Maze_[100,100](0x499602D2)_Solved_Modded.png (showing a limitation of this process)

Posted Image

Its looping. :D


"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 ...
 

Share this post


Link to post
Share on other sites

#33 ·  Posted

GUIMaze.au3 with Progress bar window:

#include <GuiConstantsEx.au3>
#include <ScreenCapture.au3>
#include <Misc.au3>
#include <WinAPI.au3>
#include <Array.au3>
; Downloaded from http://www.autoitscript.com/forum/topic/27362-bitmap-library/
#include "BMP3.au3"
#include <GDIPlus.au3>
Global $Caption = "Maze Generator"
Global $FileSaved = @ScriptDir & "Maze.bmp"
Global $vDLL_user32 = DllOpen("user32.dll")
Global $hPic, $Pic
Global $iMazeX = 15, $iMazeY = 15
Global $Generate
Global $Progress = 0
Global $sBaseName = 'Maze'
Global $aiSize[2]
Global $aCells
; Create GUI
$hGUI = GUICreate($Caption, 900, 800)
$Generate = GUICtrlCreateButton('Generate', 10, 10, 100, 20)
$Solve = GUICtrlCreateButton('Solve', 150, 10, 100, 20)
$ToPng = GUICtrlCreateButton('ToPng', 300, 10, 100, 20)

$MazeX_Label = GuiCtrlCreateLabel("Rows:", 10, 60, 60, 20)
GUICtrlSetFont(-1,8,300)
$MazeX_Edit = GuiCtrlCreateInput('15', 70, 60, 100, 20)
GUICtrlSetFont(-1,8,300)
$MazeY_Label = GuiCtrlCreateLabel("Cols:", 10, 90, 60, 20)
GUICtrlSetFont(-1,8,300)
$MazeY_Edit = GuiCtrlCreateInput('15', 70, 90, 100, 20)
GUICtrlSetFont(-1,8,300)
If FileExists($FileSaved) then
$Pic = GUICtrlCreatePic($FileSaved, 190, 60, 700, 700)
else
$Pic = GUICtrlCreatePic("", 190, 60, 700, 700)
endif
$hPic = GUICtrlGetHandle($Pic)
GUISetState()
While 1
$Msg = GUIGetMsg()
switch $Msg
  case $GUI_EVENT_CLOSE
   ExitLoop
  case $Generate
   $Progress = 1
   $iMazeX = GuiCtrlRead($MazeX_Edit)
   $aiSize[0] = Round($iMazeX)
   $iMazeY = GuiCtrlRead($MazeY_Edit)
   $aiSize[1] = Round($iMazeY)
   ProgressOn("Maze progress", "Working...", "0 percent")
   $aCells = Generate_Maze($aiSize, $Progress)
   Draw_Maze_Image($aiSize, $aCells, $sBaseName, $Progress)
   sleep(500)
   ProgressOff()
   GUICtrlSetImage ($Pic, @ScriptDir & "" & $sBaseName & ".bmp")
  case $Solve
   $Progress = 1
   $aCurrentPath = Solve_Maze($aiSize, $aCells, $Progress)
   ProgressOn("Maze Solving progress", "Working...", "0 percent")
   Solve_Maze_ImgDraw($aiSize, $aCurrentPath, $sBaseName, $Progress)
   Draw_Maze_Image($aiSize, $aCells, $sBaseName, $Progress)
   sleep(500)
   ProgressOff()
   GUICtrlSetImage ($Pic, @ScriptDir & "" & $sBaseName & "_Solved.bmp")
  case $ToPng
    _SaveAsPNG(@ScriptDir & "" & $sBaseName & ".bmp")
    _SaveAsPNG(@ScriptDir & "" & $sBaseName & "_Solved.bmp")
  case else
endswitch
WEnd
_GDIPlus_Shutdown()
DllClose($vDLL_user32)
Exit

;; ============================================================================================================== ;;
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 = Round(Map($iUnvisitedCells, $iTotalCells, 0, 0, 25.5) + 1)
        ProgressSet( $Progress*2, $Progress*2 & " percent")
    WEnd
    $Progress = Round(25.5) ; Update progress
    ProgressSet( $Progress*2, $Progress*2 & " percent")
    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
    Local $tBMP = _BMPCreate($aiSize[1] * 9, $aiSize[0] * 9) ;Define the size of the maze (in bmp)
    ;Draw the maze with no walls
    For $i = 0 To $iTotalCells - 1
        $aImageRowColum = _GetCellPos($aiSize, $i)
        Draw3By3($tBMP, $aImageRowColum[0] * 9, $aImageRowColum[1] * 9)
        Draw3By3($tBMP, 6 + $aImageRowColum[0] * 9, $aImageRowColum[1] * 9)
        Draw3By3($tBMP, $aImageRowColum[0] * 9, 6 + $aImageRowColum[1] * 9)
        Draw3By3($tBMP, 6 + $aImageRowColum[0] * 9, 6 + $aImageRowColum[1] * 9)
        $Progress = Round(Map($i, 0, $iTotalCells-1, 0, 10) + 26.5) ; Update progress
        ProgressSet( $Progress*2, $Progress*2 & " percent")
    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
            Draw3By3($tBMP, 3 + $aImageRowColum[1] * 9, $aImageRowColum[0] * 9)
        EndIf
        If StringMid($aCells[$i], 2, 1) = "1" Then
            Draw3By3($tBMP, 6 + $aImageRowColum[1] * 9, 3 + $aImageRowColum[0] * 9)
        EndIf
        If StringMid($aCells[$i], 3, 1) = "1" Then
            Draw3By3($tBMP, 3 + $aImageRowColum[1] * 9, 6 + $aImageRowColum[0] * 9)
        EndIf
        If StringMid($aCells[$i], 4, 1) = "1" Then
            Draw3By3($tBMP, $aImageRowColum[1] * 9, 3 + $aImageRowColum[0] * 9)
        EndIf
        $Progress = Round(Map($i, 0, $iTotalCells-1, 0, 10) + 36.5) ; Update progress
        ProgressSet($Progress*2, $Progress*2 & " percent")
    Next
    ;Draw start and exit.
    ;Start will be green and exit will be red
    Draw3By3($tBMP, 3, 3, '00FF00') ; 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
    Draw3By3($tBMP, 3 + + $aImageRowColum[1] * 9, 3 + $aImageRowColum[0] * 9, 'FF0000') ; Draw a red cube in the last cell (Buttom right corner)
    $Progress += 1.5 ; Update progress
    ProgressSet( Round($Progress)*2, Round($Progress)*2 & " percent")
    ;And finaly save the bmp as Maze.bmp
    _BMPWrite($tBMP, @ScriptDir & "" & $sFilename & ".bmp")
    $Progress = 50 ; Update progress
    ProgressSet( $Progress*2, $Progress*2 & " percent")
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 = Round(76.5) ; Update progress
    ProgressSet( ($Progress-50)*2, ($Progress-50)*2 & " percent")
    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 $tBMP = _BMPOpen(@ScriptDir & "" & $sFilename & ".bmp")
    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])
            Draw3By3($tBMP, 9 * $aCurrentRowAndColum[1] + 3, 9 * $aCurrentRowAndColum[0] + 3, 'FFFF00')
            If $aCurrentPath[$i] - $aiSize[0] = $aCurrentPath[$i + 1] Then ; Up
                Draw3By3($tBMP, 9 * $aCurrentRowAndColum[1] + 3, 9 * $aCurrentRowAndColum[0], 'FFFF00')
                Draw3By3($tBMP, 9 * $aCurrentRowAndColum[1] + 3, 9 * $aCurrentRowAndColum[0] - 3, 'FFFF00')
            ElseIf $aCurrentPath[$i] + 1 = $aCurrentPath[$i + 1] Then ;Right
                Draw3By3($tBMP, 9 * $aCurrentRowAndColum[1] + 6, 9 * $aCurrentRowAndColum[0] + 3, 'FFFF00')
                Draw3By3($tBMP, 9 * $aCurrentRowAndColum[1] + 9, 9 * $aCurrentRowAndColum[0] + 3, 'FFFF00')
            ElseIf $aCurrentPath[$i] + $aiSize[0] = $aCurrentPath[$i + 1] Then ; Down
                Draw3By3($tBMP, 9 * $aCurrentRowAndColum[1] + 3, 9 * $aCurrentRowAndColum[0] + 6, 'FFFF00')
                Draw3By3($tBMP, 9 * $aCurrentRowAndColum[1] + 3, 9 * $aCurrentRowAndColum[0] + 9, 'FFFF00')
            ElseIf $aCurrentPath[$i] - 1 = $aCurrentPath[$i + 1] Then ;LEft
                Draw3By3($tBMP, 9 * $aCurrentRowAndColum[1], 9 * $aCurrentRowAndColum[0] + 3, 'FFFF00')
                Draw3By3($tBMP, 9 * $aCurrentRowAndColum[1] - 3, 9 * $aCurrentRowAndColum[0] + 3, 'FFFF00')
            EndIf
        EndIf
        $Progress = Map($i, 0, UBound($aCurrentPath) - 1, 0, 22.5) + 76.5 ; Update progress
        ProgressSet(Round($Progress-50)*2, Round($Progress-50)*2 & " percent")
    Next
    ;reDraw start and exit.
    ;Start will be green and exit will be red
    Draw3By3($tBMP, 3, 3, '00FF00') ; Draw a green cube in the first cell(Top Left Corner)
    Local $aImageRowColum = _GetCellPos($aiSize, $iTotalCells - 1);Get row and colum of the last cell in the maze
    Draw3By3($tBMP, 3 + + $aImageRowColum[1] * 9, 3 + $aImageRowColum[0] * 9, 'FF0000') ; Draw a red cube in the last cell (Buttom right corner)
    ;And finaly save th bmp as Maze.bmp
    _BMPWrite($tBMP, @ScriptDir & "" & $sFilename & "_Solved.bmp")
    $Progress = 100 ; Update progress
    ProgressSet( ($Progress-50)*2, ($Progress-50)*2 & " percent")
EndFunc   ;==>Solve_Maze_ImgDraw
;=====================================
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
;=====================================
Func Draw3By3(ByRef $tBMP, $x, $y, $Colur = '000000') ; This function will draw a 3*3 Cube at a given x and y on the $tBMP
    _PixelWrite($tBMP, $x, $y, $Colur)
    _PixelWrite($tBMP, $x + 1, $y, $Colur)
    _PixelWrite($tBMP, $x + 2, $y, $Colur)
    _PixelWrite($tBMP, $x, $y + 1, $Colur)
    _PixelWrite($tBMP, $x + 1, $y + 1, $Colur)
    _PixelWrite($tBMP, $x + 2, $y + 1, $Colur)
    _PixelWrite($tBMP, $x, $y + 2, $Colur)
    _PixelWrite($tBMP, $x + 1, $y + 2, $Colur)
    _PixelWrite($tBMP, $x + 2, $y + 2, $Colur)
EndFunc   ;==>Draw3By3
#endregion Drawing 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
;=====================================
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 _SaveAsPNG($BMPFile)
Local $hImage, $sCLSID
; Initialize GDI+ library
_GDIPlus_Startup()
; Load image
$hImage = _GDIPlus_ImageLoadFromFile($BMPFile)
; Get PNG encoder CLSID
$sCLSID = _GDIPlus_EncodersGetCLSID("PNG")
; Save image with rotation
_GDIPlus_ImageSaveToFileEx($hImage, StringReplace($BMPFile,".bmp",".png"), $sCLSID)
; Clean up resources
_GDIPlus_ImageDispose($hImage)
; Shut down GDI+ library
_GDIPlus_Shutdown()
EndFunc   ;==>_SaveAsPNG

Is there simple method/property to distinguish the mazes?


The point of world view

Share this post


Link to post
Share on other sites

#34 ·  Posted (edited)

Is there simple method/property to distinguish the mazes?

? (distinguish what against what?) 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 ...
 

Share this post


Link to post
Share on other sites

#35 ·  Posted (edited)

? (distinguish what against what?)

One maze (for example 25x25) against other maze (25x25).

Is there equality between mazes?

The maze path (path from start to end!) can not be attribute of equality, I think.

There is a following aparent method of maze identification:

Every cell of maze has four possible direction of move - up, down, left, right

and two state of move possibility - open (0), closed.(1)

So sequence of four bites can code any cell of maze

ie

{0110} mean

up and right are open

down and left are closed.

How can you get this or other info (about cells) from maze picture?

Edited by ValeryVal

The point of world view

Share this post


Link to post
Share on other sites

#36 ·  Posted

One of my favorite pastimes, Mazes.

Thanks for sharing!


 Make sure brain is in gear before opening mouth!
Remember, what is not said, can be just as important as what is said.
If I put effort into communication, I expect you to read properly & fully, or just not comment.

Ignoring those who try to divert conversation with irrelevancies. If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it. I'm only big and bad, to those who have an over-active imagination.

I may have the Artistic Liesense ;) to disagree with you. TheSaint's Toolbox

Share this post


Link to post
Share on other sites

#37 ·  Posted

One maze (for example 25x25) against other maze (25x25).

Is there equality between mazes?

The maze path (path from start to end!) can not be attribute of equality, I think.

Don't think that comparing different mazes (with same size) on a cell by cell base will result in anything really useful. Scanning a image should not be that difficult. If you break the image up in its basic properties. Like path width and full cell width and the used colors. After that it should just be a matter of scanning some pixels.)

Adding some sort of difficult level classification to a maze seems more useful.

More longer dead-end's -> more difficult. Looped paths, like in that solved 100x100 maze image I posted, also add a additional difficult level. (Mmm, There's probably some web side about this.)


"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 ...
 

Share this post


Link to post
Share on other sites

#38 ·  Posted

One of my favorite pastimes, Mazes.

Thanks for sharing!

Other than reading, writing and posting? ;)

"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 ...
 

Share this post


Link to post
Share on other sites

#39 ·  Posted

Don't think that comparing different mazes (with same size) on a cell by cell base will result in anything really useful.

Maze comparing remind me Electronic Product Code which designed as a universal identifier that provides a unique identity for every physical object anywhere in the world.

http://en.wikipedia.org/wiki/Electronic_Product_Code

There is also RFID mandates.

http://en.wikipedia.org/wiki/Rfid

Maze identification results in something really useful.

:(


The point of world view

Share this post


Link to post
Share on other sites

#40 ·  Posted

Don't think that comparing different mazes (with same size) on a cell by cell base will result in anything really useful. Scanning a image should not be that difficult. If you break the image up in its basic properties. Like path width and full cell width and the used colors. After that it should just be a matter of scanning some pixels.)

Adding some sort of difficult level classification to a maze seems more useful.

More longer dead-end's -> more difficult. Looped paths, like in that solved 100x100 maze image I posted, also add a additional difficult level. (Mmm, There's probably some web side about this.)

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.

GUIMaze.au3 with Progress bar window:

I really like your _SaveToPng function.

And i do wanna add a gui.

But i don't really like your code. [No ofensive]

I'll try to update the code today with a gui

Share this post


Link to post
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
Sign in to follow this  
Followers 0