95 lines
3.8 KiB
Batchfile
95 lines
3.8 KiB
Batchfile
:amaze Rows Cols [wall char]
|
|
:: A stack-less, iterative, depth-first maze generator in native WinNT batch.
|
|
:: Rows and Cols must each be >1 and Rows*Cols cannot exceed 2096.
|
|
:: Default wall character is #, [wall char] is used if provided.
|
|
|
|
@ECHO OFF
|
|
SETLOCAL EnableDelayedExpansion
|
|
|
|
:: check for valid input, else GOTO :help
|
|
IF /I "%~2" EQU "" GOTO :amaze_help
|
|
FOR /F "tokens=* delims=0123456789" %%A IN ("%~1%~2") DO IF "%%~A" NEQ "" GOTO :amaze_help
|
|
SET /A "rows=%~1, cols=%~2, mTmp=rows*cols"
|
|
IF !rows! LSS 2 GOTO :amaze_help
|
|
IF !cols! LSS 2 GOTO :amaze_help
|
|
IF !mTmp! GTR 2096 GOTO :amaze_help
|
|
|
|
:: set map characters and use 1st character of %3 for wall, if defined
|
|
SET "wall=#"
|
|
SET "hall= "
|
|
SET "crumb=."
|
|
IF "%~3" NEQ "" SET "wall=%~3"
|
|
SET "wall=!wall:~0,1!"
|
|
|
|
:: assign width, height, cursor position, loop count, and offsets for NSEW
|
|
SET /A "cnt=0, wide=cols*2-1, high=rows*2-1, size=wide*high, N=wide*-2, S=wide*2, E=2, W=-2"
|
|
|
|
:: different random entrance points
|
|
:: ...on top
|
|
:: SET /A "start=(!RANDOM! %% cols)*2"
|
|
:: ...on bottom
|
|
:: SET /A "start=size-(!RANDOM! %% cols)*2-1"
|
|
:: ...on top or bottom
|
|
:: SET /A ch=cols*2, ch=!RANDOM! %% ch
|
|
:: IF !ch! GEQ !cols! ( SET /A "start=size-(ch-cols)*2-1"
|
|
:: ) ELSE SET /A start=ch*2
|
|
:: random entrance inside maze
|
|
SET /A "start=(!RANDOM! %% cols*2)+(!RANDOM! %% rows*2)*wide"
|
|
SET /A "curPos=start, cTmp=curPos+1, loops=cols*rows*2+1"
|
|
|
|
:: fill the maze with 8186 wall characters, clip to size, and open 1st cell
|
|
SET "mz=!wall!"
|
|
FOR /L %%A IN (1,1,6) DO SET mz=!mz!!mz!!mz!!mz!
|
|
SET bdr=!mz:~-%wide%!
|
|
SET mz=!mz:~3!!mz:~3!
|
|
SET mz=!mz:~-%size%!
|
|
SET mz=!mz:~0,%curPos%!!hall!!mz:~%cTmp%!
|
|
|
|
:: iterate #cells*2+1 steps of random depth-first search
|
|
FOR /L %%@ IN (1,1,%loops%) DO (
|
|
SET "rand=" & SET "crmPos="
|
|
REM set values for NSEW cell and wall positions
|
|
SET /A "rCnt=rTmp=0, cTmp=curPos+1, np=curPos+N, sp=curPos+S, ep=curPos+E, wp=curPos+W, wChk=curPos/wide*wide, eChk=wChk+wide, nw=curPos-wide, sw=curPos+wide, ew=curPos+1, ww=curPos-1"
|
|
REM examine adjacent cells, build direction list, and find last crumb position
|
|
FOR /F "tokens=1-8" %%A IN ("!np! !sp! !ep! !wp! !nw! !sw! !ew! !ww!") DO (
|
|
IF !np! GEQ 0 IF "!mz:~%%A,1!" EQU "!wall!" ( SET /A rCnt+=1 & SET "rand=n !rand!"
|
|
) ELSE IF "!mz:~%%E,1!" EQU "!crumb!" SET /A crmPos=np, cw=nw
|
|
IF !sp! LEQ !size! IF "!mz:~%%B,1!" EQU "!wall!" ( SET /A rCnt+=1 & SET "rand=s !rand!"
|
|
) ELSE IF "!mz:~%%F,1!" EQU "!crumb!" SET /A crmPos=sp, cw=sw
|
|
IF !ep! LEQ !eChk! IF "!mz:~%%C,1!" EQU "!wall!" ( SET /A rCnt+=1 & SET "rand=e !rand!"
|
|
) ELSE IF "!mz:~%%G,1!" EQU "!crumb!" SET /A crmPos=ep, cw=ew
|
|
IF !wp! GEQ !wChk! IF "!mz:~%%D,1!" EQU "!wall!" ( SET /A rCnt+=1 & SET "rand=w !rand!"
|
|
) ELSE IF "!mz:~%%H,1!" EQU "!crumb!" SET /A crmPos=wp, cw=ww
|
|
)
|
|
IF DEFINED rand ( REM adjacent unvisited cell is available
|
|
SET /A rCnt=!RANDOM! %% rCnt
|
|
FOR %%A IN (!rand!) DO ( REM pick random cell + wall
|
|
IF !rTmp! EQU !rCnt! SET /A "curPos=!%%Ap!, cTmp=curPos+1, mw=!%%Aw!, mTmp=mw+1"
|
|
SET /A rTmp+=1
|
|
)
|
|
REM write the 2 new characters into the maze
|
|
FOR /F "tokens=1-4" %%A IN ("!mw! !mTmp! !curPos! !cTmp!") DO (
|
|
SET "mz=!mz:~0,%%A!!crumb!!mz:~%%B!"
|
|
SET "mz=!mz:~0,%%C!!hall!!mz:~%%D!"
|
|
)
|
|
) ELSE IF DEFINED crmPos ( REM follow the crumbs backward
|
|
SET /A mTmp=cw+1
|
|
REM erase the crumb character and set new cursor position
|
|
FOR /F "tokens=1-2" %%A IN ("!cw! !mTmp!") DO SET "mz=!mz:~0,%%A!!hall!!mz:~%%B!"
|
|
SET "curPos=!crmPos!"
|
|
)
|
|
)
|
|
SET /A open=cols/2*2, mTmp=open+1
|
|
ECHO !wall!!bdr:~0,%open%!!hall!!bdr:~%mTmp%!!wall!
|
|
FOR /L %%A IN (0,!wide!,!size!) DO IF %%A LSS !size! ECHO !wall!!mz:~%%A,%wide%!!wall!
|
|
ECHO !wall!!bdr:~0,%open%!!hall!!bdr:~%mTmp%!!wall!
|
|
ENDLOCAL
|
|
EXIT /B 0
|
|
|
|
:amaze_help
|
|
ECHO Usage: %~0 Rows Cols [wall char]
|
|
ECHO Rows^>1, Cols^>1, and Rows*Cols^<=2096
|
|
ECHO Example: %~0 11 39 @
|
|
ENDLOCAL
|
|
EXIT /B 0
|