2

I've been learning some batch programming, and decided to make a roguelike, as it's one of my favorite types of games. I have researched any information on making a roguelike in batch, but haven't found much. From the little bit I've gathered, this is the code I have so far:

@echo off

rem init starting position
set pos=6

:level
set c1=#
set c2=#
set c3=#
set c4=#

set c5=#
set c6=.
set c7=.
set c8=#

set c9=#
set c10=.
set c11=.
set c12=#

set c13=#
set c14=#
set c15=#
set c16=#

echo %c1%%c2%%c3%%c4%
echo %c5%%c6%%c7%%c8%
echo %c9%%c10%%c11%%c12%
echo %c13%%c14%%c15%%c16%

This works so far, and draws the simple 4x4 room.I made the room only 4x4 for testing purposes, so it would be simple.

Now I'm at a point where I'm not sure how to write the rest. I know I'll need to call subroutines, and get the input (WASD), but I don't know how to structure those subroutines in the file. I'd appreciate anyone's help on how to structure a batch roguelike, get input to move the player, or even just ideas about what could work.

Thanks.

Jeremy Darrach
  • 273
  • 1
  • 6
  • 18

2 Answers2

3

I give you here a technic without CHOICE and without an External command. It use Xcopy to get the INPUT (W,A,S,D). IN this Exemple i don't make any test of position (where is your object on the screen), So to test it go first right (D). It's just an exemple to help you.

@echo off

:level
set c1=#
set c2=#
set c3=#
set c4=#

set c5=#
set c6=.
set c7=.
set c8=#

set c9=#
set c10=.
set c11=.
set c12=#

set c13=#
set c14=#
set c15=#
set c16=#


@echo off
setlocal enableextensions enabledelayedexpansion

set haut=        
set larg=

:boucle
cls
echo WASD TO MOVE THE CURSOR Q TO QUIT&echo.
for %%a in ( !haut! ) do echo.
call:aff
Set "Key="
For /F "delims=" %%# In ('Xcopy /W "%~f0" "%~f0" 2^>Nul') Do If Not Defined Key Set "Key=%%#"
Set "Key=%Key:~-1%"
if /i %key%==q (exit /b)
if /i %key%==w goto:UP
if /i %key%==s goto:DOWN
if /i %key%==a goto:LEFT
if /i %key%==d goto:RIGHT

:LEFT
set larg=!larg:~0,-1!
goto boucle

:RIGHT
set larg= !larg!
goto boucle

:UP
set haut=!haut:~0,-2!
goto boucle

:DOWN
set haut=!haut! a
goto boucle


:aff
echo !larg!%c1%%c2%%c3%%c4%
echo !larg!%c5%%c6%%c7%%c8%
echo !larg!%c9%%c10%%c11%%c12%
echo !larg!%c13%%c14%%c15%%c16%
SachaDee
  • 9,245
  • 3
  • 23
  • 33
  • Thanks for the reply! I wrote this all out and ran it, but I'm not exactly sure what it does. When I push WASD, some text shows up to the left of the room, showing ~0,-2, or ~0,-2a. The main thing I don't understand is the for loop. If you could elaborate on what exactly these functions do I would really appreciate it. Thanks – Jeremy Darrach Dec 15 '13 at 00:36
  • Like i told you in my post you have to start going right with the D key. That's just an exemple to move aby obketc on the CMD windows using tje keys (W,A,S,D). The FOR is to recuperate the pressed key so you don't need the Choice command. I'll write the direction in English that you can anderstand. – SachaDee Dec 15 '13 at 00:42
  • Thanks a lot for your help man. Now, how could I add back in the position, and physically move the '@' symbol? – Jeremy Darrach Dec 15 '13 at 00:48
  • oh wow, I just copied your whole file into a new .bat file, and ran it, and mine doesn't do that! I must have written something wrong. I'll go back and check – Jeremy Darrach Dec 15 '13 at 01:02
  • If you want to move the `@` symbol put echo `!larg!@` in the place of `call:aff`. – SachaDee Dec 15 '13 at 01:04
1
@ECHO OFF
setlocal enableextensions enabledelayedexpansion

SET /a maxx=13
SET /a maxy=7
SET /a level=1
:: current x,y position in cx, cy - set start position
SET /a cx=3
SET /a cy=2

SET objdesc16=*Book of something
CALL :putobjects 1 6 3 16

SET userprompt=Q always Quits - MOVE WASD
SET moveoptions=wasd

:newlevel
:: Set physical map
CALL :map%level%
:loop
CALL :showmap
CALL :getmove
IF /i "%key%"=="Q" GOTO :eof
CALL :makemove
GOTO loop

:getmove
ECHO(%userprompt%
SET "userprompt="
:getmovel
Set "key="
For /F "delims=" %%Z In ('Xcopy /W "%~f0" "%~f0" 2^>Nul') Do If Not Defined Key Set "key=%%Z"
IF NOT DEFINED key GOTO getmovel
Set "key=%key:~-1%"
IF /i "%key%"=="Q" GOTO :eof
IF /i "%moveoptions%"=="!moveoptions:%key%=!" GOTO getmovel
GOTO :eof

:: make a move given KEY

:makemove
if /i %key%==w CALL :movedir 0 -1
if /i %key%==a CALL :movedir -1 0
if /i %key%==s CALL :movedir 0 1
if /i %key%==d CALL :movedir 1 0
GOTO :eof

:movedir
SET /a $m=%1+%cx%
SET /a $n=%2+%cy%
CALL :mapsquare %$m% %$n%
IF "%$s%"=="." SET cy=%$n%&SET cx=%$m%&CALL :setprompt wasd&GOTO :EOF
IF "%$s%"=="#" CALL :setprompt ouch&GOTO :EOF
GOTO :eof

:: standard userprompts

:setprompt
IF /i "%1"=="wasd" SET userprompt=MOVE WASD&GOTO :EOF 
IF /i "%1"=="ouch" SET userprompt=OUCH!&GOTO :EOF 
GOTO :EOF


:map1
CALL :initmap
:: Special map symbols for level 1 (stairs, etc)
CALL :mapsymbol 4 2 ?

GOTO :eof

:mapsymbol
SET "c_%1_%2=%3"
GOTO :eof

:: set border to '#', internal to '.'
:initmap
FOR /l %%y IN (0,1,%maxy%) DO ( 
 FOR /l %%x IN (0,1,%maxx%) DO ( 
  SET c_%%x_%%y=.
  IF %%x==0 SET c_%%x_%%y=#
  IF %%y==0 SET c_%%x_%%y=#
  IF %%x==%maxx% SET c_%%x_%%y=#
  IF %%y==%maxy% SET c_%%x_%%y=#
 )
)
GOTO :eof

:: map on new screen

:showmap
CLS
FOR /l %%y IN (0,1,%maxy%) DO (
 SET "mapline="
 FOR /l %%x IN (0,1,%maxx%) DO ( 
  CALL :mapsquare %%x %%y
  SET mapline=!mapline!!$s!
 )
 ECHO(!mapline!
)
GOTO :eof

:: get the symbol to show in x,y

:mapsquare
:: From map
SET $s=!c_%1_%2!
:: Object
IF DEFINED obj%level%_%1_%2 CALL :getobj %level%_%1_%2
:: Character
IF %cx%==%1 IF %cy%==%2 SET $s=@
SET $s=%$s:~0,1%
GOTO :eof

:: Get object description for object (%1) to $s

:getobj
SET $s=!obj%1!
SET $s=!objdesc%$s%!
GOTO :eof

:: PUTOBJECTS onlevel at-x at-y object#

:putobjects 1 1 3 16
SET "obj%1_%2_%3=%4"
GOTO :eof

This code may be useful.

The main loop simply repeats showmap, getmove, makemove.

makemove is the critical routine that needs to be expanded to build your game. The principle is to see which moves are valid for the next input, place those in moveoptions and generate an appropriate userprompt

Otherwise, your mapcells are in c_x_y and objects in obj_level_x_y I simply chose the object-description to be displaysymbolDESCRIPTION in objdescX where the X is stored in obj_level_x_y. In this way, you can set up extra object characteristics simply by setting variables like objhitbonusX or objdosesX.

You could extend the scheme to opponenthealthX opponentweaponX etc.

You'd not that GOTOs are minimised to avoid spaghetti-code.

Magoo
  • 77,302
  • 8
  • 62
  • 84
  • thanks for the reply! I tested it out, and it works great. I was wondering if there is any way to reduce the "redraw effect". It's not a big deal, just wondering if it's possible. Anyway, I'll keep reading through the code so I understand what everything does. :) Thanks again – Jeremy Darrach Dec 15 '13 at 16:43
  • You'd need a way to control the cursor which sadly is a thing of the past AFAIAA. You used to be able to load ANSI.SYS and send an escape-sequence, but it seems that is no longer possible because the system has been "improved." I'm quite happy for someone to demonstrate how if it can be done though! – Magoo Dec 15 '13 at 17:11