playjacob Posted July 1, 2012 Author Posted July 1, 2012 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?
MvGulik Posted July 1, 2012 Posted July 1, 2012 (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 July 1, 2012 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 ...
playjacob Posted July 1, 2012 Author Posted July 1, 2012 (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 July 1, 2012 by playjacob
MvGulik Posted July 1, 2012 Posted July 1, 2012 (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).)expandcollapse popup;~ #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"expandcollapse popup#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 July 2, 2012 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 ...
playjacob Posted July 1, 2012 Author Posted July 1, 2012 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!!!
MvGulik Posted July 1, 2012 Posted July 1, 2012 (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 July 1, 2012 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 ...
playjacob Posted July 2, 2012 Author Posted July 2, 2012 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.
UEZ Posted July 2, 2012 Posted July 2, 2012 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! 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!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ
playjacob Posted July 2, 2012 Author Posted July 2, 2012 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.
UEZ Posted July 2, 2012 Posted July 2, 2012 (edited) You have updated the code in your 1st post meanwhile. It looks ok now. Br, UEZ Edited July 2, 2012 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!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ
ValeryVal Posted July 3, 2012 Posted July 3, 2012 It's not aptly that your maze picture is OK just in rectangular case, ie if $iMazeX = $iMazeY. Try this GUIMaze.au3 expandcollapse popup#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
MvGulik Posted July 3, 2012 Posted July 3, 2012 Playing around with backtracking dead-ends.Maze_[15,15](0x499602D2)_Solved_Animated.gifMaze_[100,100](0x499602D2)_Solved_Modded.png (showing a limitation of this process)Its looping. "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 ...
ValeryVal Posted July 3, 2012 Posted July 3, 2012 GUIMaze.au3 with Progress bar window: expandcollapse popup#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
MvGulik Posted July 3, 2012 Posted July 3, 2012 (edited) Is there simple method/property to distinguish the mazes?? (distinguish what against what?) Edited July 3, 2012 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 ...
ValeryVal Posted July 3, 2012 Posted July 3, 2012 (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, rightand two state of move possibility - open (0), closed.(1) So sequence of four bites can code any cell of mazeie {0110} meanup and right are opendown and left are closed.How can you get this or other info (about cells) from maze picture? Edited July 3, 2012 by ValeryVal The point of world view
TheSaint Posted July 3, 2012 Posted July 3, 2012 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. Spoiler What is the Secret Key? Life is like a Donut 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 (be advised many downloads are not working due to ISP screwup with my storage)
MvGulik Posted July 3, 2012 Posted July 3, 2012 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 ...
MvGulik Posted July 3, 2012 Posted July 3, 2012 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 ...
ValeryVal Posted July 3, 2012 Posted July 3, 2012 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/RfidMaze identification results in something really useful. The point of world view
playjacob Posted July 3, 2012 Author Posted July 3, 2012 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
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now