Skip to content

Instantly share code, notes, and snippets.

@kdrnic
Last active June 22, 2017 00:27
Show Gist options
  • Save kdrnic/30107a676c27a43e3ea6bd8eb6849e83 to your computer and use it in GitHub Desktop.
Save kdrnic/30107a676c27a43e3ea6bd8eb6849e83 to your computer and use it in GitHub Desktop.
rem MIT License
rem
rem Copyright (c) 2014 kdrnic ( website: kdrnic.xyz )
rem
rem Permission is hereby granted, free of charge, to any person obtaining a copy
rem of this software and associated documentation files (the "Software"), to deal
rem in the Software without restriction, including without limitation the rights
rem to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
rem copies of the Software, and to permit persons to whom the Software is
rem furnished to do so, subject to the following conditions:
rem
rem The above copyright notice and this permission notice shall be included in all
rem copies or substantial portions of the Software.
rem
rem THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
rem IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
rem FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
rem AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
rem LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
rem OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
rem SOFTWARE.
@echo off
setlocal enabledelayedexpansion
rem Compatibility warning
if %CMDEXTVERSION% LSS 2 (
echo Warning: variable extension version may be too low - game may not be able to run
)
rem Play area buffer size - may be adjusted for performance
set cols=30
set rows=15
rem That is the line separating the drawing buffer from the rest of the text
set separator=--------------------------------
rem Set up dungeon 0 - the first level, with no enemies
set maplines[0]=##################################################
set maplines[1]=##################################################
set maplines[2]=##################################################
set maplines[3]=##################################################
set maplines[4]=##################################################
set maplines[5]=##################################################
set maplines[6]=##################################################
set maplines[7]=##################################################
set maplines[8]=##################################################
set maplines[9]=##################################################
set maplines[10]=##################################################
set maplines[11]=##################################################
set maplines[12]=##################################################
set maplines[13]=##################################################
set maplines[14]=##################################################
set maplines[15]=##############################....................
set maplines[16]=##############################....................
set maplines[17]=##############################....................
set maplines[18]=##############################....................
set maplines[19]=##############################...................v
set mapwidth=50
set mapheight=20
set level=0
rem The player starts at the top left corner of that triangle of dots
set player_x=30
set player_y=15
rem Set up the messages with the starting narration
set msg5=nullmsg
set msg4=You are in an old dungeon.
set msg3=The smell of mold is heavy in the air.
set msg2=At the corner, you see a stairway leading below.
set msg1=Who knows what treasures may await you...
rem If true, this variable will transport the player to a new dungeon
set descend=0
:mainloop
set /a scrollx=%player_x%-%cols%/2
set /a scrolly=%player_y%-%rows%/2
set x=%player_x%
set y=%player_y%
set char=@
call :copymap
call :putchar
cls
if "%msg5%" NEQ "nullmsg" ( echo %msg5% ) else echo.
if "%msg4%" NEQ "nullmsg" ( echo %msg4% ) else echo.
if "%msg3%" NEQ "nullmsg" ( echo %msg3% ) else echo.
if "%msg2%" NEQ "nullmsg" ( echo %msg2% ) else echo.
if "%msg1%" NEQ "nullmsg" ( echo %msg1% ) else echo.
call :drawbuffer
if %descend% NEQ 1 goto update
call :genmap
call :rendermap
call :findfreespot
set player_x=%x%
set player_y=%y%
set descend=0
goto mainloop
:update
set player_newx=%player_x%
set player_newy=%player_y%
call :getkeys
if %ERRORLEVEL% EQU 1 goto walkup
if %ERRORLEVEL% EQU 2 goto walkright
if %ERRORLEVEL% EQU 3 goto walkdown
if %ERRORLEVEL% EQU 4 goto walkleft
if %ERRORLEVEL% EQU 6 (
set > block.log
goto :eof
)
goto mainloop
:walkup
set /a player_newy=%player_y%-1
goto walkend
:walkdown
set /a player_newy=%player_y%+1
goto walkend
:walkleft
set /a player_newx=%player_x%-1
goto walkend
:walkright
set /a player_newx=%player_x%+1
goto walkend
:walkend
set x=%player_newx%
set y=%player_newy%
call :getmapchar
if %char% EQU # goto mainloop
if %char% EQU v goto downstairs
set player_x=%player_newx%
set player_y=%player_newy%
goto mainloop
:downstairs
set newmsg=You take the stairs and descend to a lower level of the dungeon...
call :pushmsg
set descend=1
goto mainloop
goto :eof
:pushmsg
set msg5=%msg4%
set msg4=%msg3%
set msg3=%msg2%
set msg2=%msg1%
set msg1=%newmsg%
goto :eof
rem Input will be quite annoying if choice.exe isn't available
:getkeys
if EXIST "CHOICE.EXE" goto getkeys_choice
set /p getkeys_k=Enter key:
if %getkeys_k%=="w" set ERRORLEVEL=1
if %getkeys_k%=="d" set ERRORLEVEL=2
if %getkeys_k%=="s" set ERRORLEVEL=3
if %getkeys_k%=="a" set ERRORLEVEL=4
if %getkeys_k%=="r" set ERRORLEVEL=5
if %getkeys_k%=="q" set ERRORLEVEL=6
goto :eof
:getkeys_choice
choice /n /c:wdsarq Enter key:
goto :eof
:wrapxy
set /a x=((%x% %% %mapwidth%) + %mapwidth%) %% %mapwidth%
set /a y=((%y% %% %mapheight%) + %mapheight%) %% %mapheight%
goto :eof
:findfreespot
set /a x=%random% %% %mapwidth%
set /a y=%random% %% %mapheight%
call :getmapchar
if %char% EQU # goto findfreespot
goto :eof
:genmap
set mapwidth=40
set mapheight=40
set x=0
:genmap_xloop
set y=0
:genmap_yloop
set map[%x%][%y%]=#
set /a y=%y%+1
if %y% LSS %mapheight% goto genmap_yloop
set /a x=%x%+1
if %x% LSS %mapwidth% goto genmap_xloop
set genmap_numcorridors=0
set genmap_maxcorridors=20
set /a x=%mapwidth%/2
set /a y=%mapheight%/2
set /a genmap_direction=%random% %% 4
set genmap_corridorlength=6
set genmap_roomsize=3
:genmap_loop
if %genmap_numcorridors% EQU 0 goto genmap_corridor
if %genmap_numcorridors% GTR %genmap_maxcorridors% goto genmap_loopend
:genmap_search
set /a x=%random% %% %mapwidth%
set /a y=%random% %% %mapheight%
if !map[%x%][%y%]! EQU # goto genmap_search
set /a genmap_direction=%random% %% 4
if %genmap_direction% EQU 0 set genmap_walkmax=%mapheight%
if %genmap_direction% EQU 1 set genmap_walkmax=%mapwidth%
if %genmap_direction% EQU 2 set genmap_walkmax=%mapheight%
if %genmap_direction% EQU 3 set genmap_walkmax=%mapwidth%
set genmap_walkcounter=0
:genmap_walk
set /a genmap_walkcounter=%genmap_walkcounter%+1
if %genmap_walkcounter% GTR %genmap_walkmax% goto genmap_search
if %genmap_direction% EQU 0 set /a y=%y%-1
if %genmap_direction% EQU 1 set /a x=%x%+1
if %genmap_direction% EQU 2 set /a y=%y%+1
if %genmap_direction% EQU 3 set /a x=%x%-1
set /a x=((%x% %% %mapwidth%) + %mapwidth%) %% %mapwidth%
set /a y=((%y% %% %mapheight%) + %mapheight%) %% %mapheight%
if !map[%x%][%y%]! EQU # goto genmap_corridor
goto genmap_walk
:genmap_corridor
set /a genmap_numcorridors=%genmap_numcorridors%+1
set genmap_corridorcounter=0
:genmap_corridorloop
set /a genmap_corridorcounter=%genmap_corridorcounter%+1
set map[%x%][%y%]=.
rem Check if next corridor tile is free
if %genmap_direction% EQU 0 set /a y=%y%-1
if %genmap_direction% EQU 1 set /a x=%x%+1
if %genmap_direction% EQU 2 set /a y=%y%+1
if %genmap_direction% EQU 3 set /a x=%x%-1
set /a x=((%x% %% %mapwidth%) + %mapwidth%) %% %mapwidth%
set /a y=((%y% %% %mapheight%) + %mapheight%) %% %mapheight%
if !map[%x%][%y%]! NEQ # goto genmap_loop
rem Check if the tile to the left of the next corridor tile is free
if %genmap_direction% EQU 0 set /a x=%x%-1
if %genmap_direction% EQU 1 set /a y=%y%+1
if %genmap_direction% EQU 2 set /a x=%x%+1
if %genmap_direction% EQU 3 set /a y=%y%-1
set /a x=((%x% %% %mapwidth%) + %mapwidth%) %% %mapwidth%
set /a y=((%y% %% %mapheight%) + %mapheight%) %% %mapheight%
if !map[%x%][%y%]! NEQ # goto genmap_loop
rem Check if the tile to the right of the next corridor tile is free
if %genmap_direction% EQU 0 set /a x=%x%+2
if %genmap_direction% EQU 1 set /a y=%y%-2
if %genmap_direction% EQU 2 set /a x=%x%-2
if %genmap_direction% EQU 3 set /a y=%y%+2
set /a x=((%x% %% %mapwidth%) + %mapwidth%) %% %mapwidth%
set /a y=((%y% %% %mapheight%) + %mapheight%) %% %mapheight%
if !map[%x%][%y%]! NEQ # goto genmap_loop
rem Move back to the corridor
if %genmap_direction% EQU 0 set /a x=%x%-1
if %genmap_direction% EQU 1 set /a y=%y%+1
if %genmap_direction% EQU 2 set /a x=%x%+1
if %genmap_direction% EQU 3 set /a y=%y%-1
set /a x=((%x% %% %mapwidth%) + %mapwidth%) %% %mapwidth%
set /a y=((%y% %% %mapheight%) + %mapheight%) %% %mapheight%
if %genmap_corridorcounter% GEQ %genmap_corridorlength% goto genmap_room
goto genmap_corridorloop
:genmap_room
rem place xy in the center of the room
if %genmap_direction% EQU 0 set /a y=%y%-1
if %genmap_direction% EQU 1 set /a x=%x%+1
if %genmap_direction% EQU 2 set /a y=%y%+1
if %genmap_direction% EQU 3 set /a x=%x%-1
set /a x=((%x% %% %mapwidth%) + %mapwidth%) %% %mapwidth%
set /a y=((%y% %% %mapheight%) + %mapheight%) %% %mapheight%
set map[%x%][%y%]=.
rem place xy to the left of the room
set /a x=%x%-1
set /a x=((%x% %% %mapwidth%) + %mapwidth%) %% %mapwidth%
set /a y=((%y% %% %mapheight%) + %mapheight%) %% %mapheight%
set map[%x%][%y%]=.
rem place xy in the bottom left corner of the room
set /a y=%y%+1
set /a x=((%x% %% %mapwidth%) + %mapwidth%) %% %mapwidth%
set /a y=((%y% %% %mapheight%) + %mapheight%) %% %mapheight%
set map[%x%][%y%]=.
rem place xy in the bottom of the room
set /a x=%x%+1
set /a x=((%x% %% %mapwidth%) + %mapwidth%) %% %mapwidth%
set /a y=((%y% %% %mapheight%) + %mapheight%) %% %mapheight%
set map[%x%][%y%]=.
rem place xy in the bottom right corner of the room
set /a x=%x%+1
set /a x=((%x% %% %mapwidth%) + %mapwidth%) %% %mapwidth%
set /a y=((%y% %% %mapheight%) + %mapheight%) %% %mapheight%
set map[%x%][%y%]=.
rem place xy in the right of the room
set /a y=%y%-1
set /a x=((%x% %% %mapwidth%) + %mapwidth%) %% %mapwidth%
set /a y=((%y% %% %mapheight%) + %mapheight%) %% %mapheight%
set map[%x%][%y%]=.
rem place xy in the top right corner of the room
set /a y=%y%-1
set /a x=((%x% %% %mapwidth%) + %mapwidth%) %% %mapwidth%
set /a y=((%y% %% %mapheight%) + %mapheight%) %% %mapheight%
set map[%x%][%y%]=.
rem place xy in the top of the room
set /a x=%x%-1
set /a x=((%x% %% %mapwidth%) + %mapwidth%) %% %mapwidth%
set /a y=((%y% %% %mapheight%) + %mapheight%) %% %mapheight%
set map[%x%][%y%]=.
rem place xy in the top left corner of the room
set /a x=%x%-1
set /a x=((%x% %% %mapwidth%) + %mapwidth%) %% %mapwidth%
set /a y=((%y% %% %mapheight%) + %mapheight%) %% %mapheight%
set map[%x%][%y%]=.
goto genmap_loop
:genmap_loopend
rem Find somewhere to place the stairs
:genmap_placestairs
set /a x=%random% %% %mapwidth%
set /a y=%random% %% %mapheight%
if !map[%x%][%y%]! EQU # goto genmap_placestairs
set genmap_dotcount=0
set /a x=%x%-1
call :wrapxy
if !map[%x%][%y%]! EQU . set /a genmap_dotcount=%genmap_dotcount%+1
set /a x=%x%+2
call :wrapxy
if !map[%x%][%y%]! EQU . set /a genmap_dotcount=%genmap_dotcount%+1
set /a x=%x%-1
set /a y=%y%-1
call :wrapxy
if !map[%x%][%y%]! EQU . set /a genmap_dotcount=%genmap_dotcount%+1
set /a y=%y%+2
call :wrapxy
if !map[%x%][%y%]! EQU . set /a genmap_dotcount=%genmap_dotcount%+1
if %genmap_dotcount% LSS 3 goto genmap_placestairs
set map[%x%][%y%]=v
goto :eof
:drawbuffer
set drawbuffer_y_=0
echo %separator%
:drawbuffer_yloop
set /a drawbuffer_y=%scrolly%+%drawbuffer_y_%
set /a drawbuffer_y=((%drawbuffer_y% %% %mapheight%) + %mapheight%) %% %mapheight%
set drawbuffer_x=%scrollx%
set /a drawbuffer_x=((%drawbuffer_x% %% %mapwidth%) + %mapwidth%) %% %mapwidth%
set drawbuffer_line=
set drawbuffer_linelength=0
:drawbuffer_xloop
set /a drawbuffer_pos=%drawbuffer_x% %% %mapwidth%
set /a drawbuffer_sublength=%mapwidth%-%drawbuffer_pos%
set /a drawbuffer_pluslength=%drawbuffer_linelength%+%drawbuffer_sublength%
if %drawbuffer_pluslength% GTR %cols% set /a drawbuffer_sublength=%cols%-%drawbuffer_linelength%
set drawbuffer_str=!buffer[%drawbuffer_y%]!
set drawbuffer_line=%drawbuffer_line%!drawbuffer_str:~%drawbuffer_pos%,%drawbuffer_sublength%!
set /a drawbuffer_linelength=%drawbuffer_linelength%+%drawbuffer_sublength%
set /a drawbuffer_x=%drawbuffer_x%+%drawbuffer_sublength%
if %drawbuffer_linelength% LSS %cols% goto drawbuffer_xloop
echo ^|%drawbuffer_line%^|
set /a drawbuffer_y_=%drawbuffer_y_%+1
if %drawbuffer_y_% LSS %rows% goto drawbuffer_yloop
echo %separator%
goto :eof
:copymap
set copymap_y=0
:copymap_loop
set buffer[%copymap_y%]=!maplines[%copymap_y%]!
set /a copymap_y=%copymap_y%+1
if %copymap_y% LSS %mapheight% goto copymap_loop
goto :eof
:putchar
set /a x=((%x% %% %mapwidth%) + %mapwidth%) %% %mapwidth%
set /a y=((%y% %% %mapheight%) + %mapheight%) %% %mapheight%
set renderchar_line=!buffer[%y%]!
set renderchar_newline=!renderchar_line:~0,%x%!
set renderchar_newline=%renderchar_newline%%char%
set /a renderchar_x=%x%+1
set renderchar_newline=%renderchar_newline%!renderchar_line:~%renderchar_x%!
set buffer[%y%]=%renderchar_newline%
goto :eof
:getmapchar
set /a x=((%x% %% %mapwidth%) + %mapwidth%) %% %mapwidth%
set /a y=((%y% %% %mapheight%) + %mapheight%) %% %mapheight%
set getchar_line=!maplines[%y%]!
set char=!getchar_line:~%x%,1!
goto :eof
:rendermap
set rendermap_y=0
:rendermap_yloop
set rendermap_x=0
set rendermap_line=
:rendermap_xloop
set rendermap_char=!map[%rendermap_x%][%rendermap_y%]!
set map[%rendermap_x%][%rendermap_y%]=
set rendermap_line=%rendermap_line%%rendermap_char%
set /a rendermap_x=%rendermap_x%+1
if %rendermap_x% LSS %mapwidth% goto rendermap_xloop
set maplines[%rendermap_y%]=%rendermap_line%
set /a rendermap_y=%rendermap_y%+1
if %rendermap_y% LSS %mapheight% goto rendermap_yloop
goto :eof
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment