Discussion forum for all Windows batch related topics.
Moderator: DosItHelp
-
Lowsun
- Posts: 29
- Joined: 14 Apr 2019 17:22
#1
Post
by Lowsun » 06 Nov 2019 10:10
I've always been fascinated by isometric designs, and so I decided one day to make an isometric grid generator. Naturally, I thought that it would be a really unique perspective to try to make a game in. It is just showcase of an isometric movement system using purely ASCII characters. I really tried to go for style+efficiency in this script. Here's a screenshot
and here's the code:
Code: Select all
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
IF not "%~1" == "" (
GOTO :%~1
)
FOR /F %%A in ('ECHO prompt $E^| cmd') DO SET "ESC=%%A"
SET mv[W]="y[#]-=1","x[#]+=1"
SET mv[A]="x[#]-=3"
SET mv[S]="y[#]+=1","x[#]-=1"
SET mv[D]="x[#]+=3"
SET up=%ESC%[nA
SET dn=%ESC%[nB
SET bk=%ESC%[nD
SET nx=%ESC%[nC
SET col=%ESC%[38;2;cm
SET bcl=%ESC%[48;2;cm
SET framerate=FOR /L %%J in (1,40,1000000) DO REM
SET every="1/(((~(0-(count %% #))>>31)&1)&((~((count %% #)-0)>>31)&1))"
SET /A "grid[x]=13","grid[y]=6","grid[bk]=(grid[x]*3)+1","x[u]=grid[x]+grid[y]","y[u]=6","score=0"
FOR /L %%X in (1, 1, %grid[x]%) DO (
SET "grid[xlen]=!grid[xlen]!/_/"
SET "grid[tlen]=!grid[tlen]!__ "
)
SET "grid[disp]=!nx:n=%grid[y]%!%grid[tlen]%%dn:n=1%!bk:n=%grid[bk]%!"
FOR /L %%Y in (1, 1, %grid[y]%) DO (
SET "grid[disp]=!grid[disp]!%grid[xlen]%%dn:n=1%!bk:n=%grid[bk]%!"
)
ECHO %ESC%[?25l
IF exist "%temp%\%~n0_signal.txt" (
DEL "%temp%\%~n0_signal.txt"
)
"%~F0" CONTROL >"%temp%\%~n0_signal.txt" | "%~F0" GAME <"%temp%\%~n0_signal.txt"
EXIT /B
:GAME
FOR /L %%# in () DO (
SET /P "rec="
TITLE Score : !score!
ECHO %ESC%[2J%col:c=222;218;206%%ESC%[5;10H%grid[disp]%%col:c=135;245;233%!p[dp]!%col:c=222;201;131%%ESC%[!y[u]!;!x[u]!Hß%bk:n=1%%up:n=1%Û
SET /A "count+=1"
FOR %%G in (!rec!) DO (
(SET /A "y[t]=y[u]","x[t]=x[u]",!mv[%%G]:#=t!,"1/((((5-y[t])>>31)&1)&(((y[t]-(grid[y]+6))>>31)&1)&((((((grid[y]-(y[t]-5)))+10)-x[t])>>31)&1)&(((x[t]-((((grid[y]-(y[t]-5)))+10)+(3*grid[x])))>>31)&1))" 2>NUL) && (
SET /A !mv[%%G]:#=u!
)
)
2>NUL SET /A !every:#=15! && (
SET /A "p[ct]+=1","d[y]=(!RANDOM!*grid[y]/32768+1)+5","d[x]=((grid[y]-(d[y]-5)))+5","d[max]=((grid[y]-(d[y]-5)))+11+(3*grid[x])"
SET /A "p[!p[ct]!]=d[max]<<16|d[y]<<8|d[x]"
SET "p[li]=!p[li]! [!p[ct]!]"
)
2>NUL SET /A !every:#=2! && (
SET "p[dp]="
FOR %%Q in (!p[li]!) DO (
SET /A "d[x]=(p%%Q>>0&255)+3","d[y]=(p%%Q>>8&255)","d[max]=(p%%Q>>16&255)","p%%Q=d[max]<<16|d[y]<<8|d[x]"
IF !d[x]! EQU !d[max]! (
SET /A "score+=1"
SET "p[li]=!p[li]:%%Q=!"
) else (
SET "p[dp]=!p[dp]!%ESC%[!d[y]!;!d[x]!H^>%bk:n=2%Í"
)
IF "!x[u]!;!y[u]!" == "!d[x]!;!d[y]!" (
TITLE You died...
ECHO %ESC%[2J%col:c=222;218;206%%ESC%[5;10H%grid[disp]%%col:c=135;245;233%!p[dp]!%col:c=219;29;55%%up:n=1%Û
EXIT /B
)
)
)
SET "rec="
%framerate%
)
:CONTROL
FOR /L %%C in () do (
FOR /F "tokens=*" %%A in ('CHOICE /C:WASD /N') DO (
<NUL SET /P ".=%%A"
)
)
GOTO :EOF
The game is pretty simple, just use WASD to move.
Lowsun
-
dbenham
- Expert
- Posts: 2461
- Joined: 12 Feb 2011 21:02
- Location: United States (east coast)
#2
Post
by dbenham » 06 Nov 2019 13:24
Nicely done. I assume you've seen
SNAKE.BAT.
It didn't take much to enhance your code to allow cleanly exiting the game. My added/modified code is in lower case. Press Q to exit the game. This could be before or after you die. Either way, your final score is printed.
Code: Select all
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
IF not "%~1" == "" (
GOTO :%~1
)
FOR /F %%A in ('ECHO prompt $E^| cmd') DO SET "ESC=%%A"
SET mv[W]="y[#]-=1","x[#]+=1"
SET mv[A]="x[#]-=3"
SET mv[S]="y[#]+=1","x[#]-=1"
SET mv[D]="x[#]+=3"
SET up=%ESC%[nA
SET dn=%ESC%[nB
SET bk=%ESC%[nD
SET nx=%ESC%[nC
SET col=%ESC%[38;2;cm
SET bcl=%ESC%[48;2;cm
SET framerate=FOR /L %%J in (1,40,1000000) DO REM
SET every="1/(((~(0-(count %% #))>>31)&1)&((~((count %% #)-0)>>31)&1))"
SET /A "grid[x]=13","grid[y]=6","grid[bk]=(grid[x]*3)+1","x[u]=grid[x]+grid[y]","y[u]=6","score=0"
FOR /L %%X in (1, 1, %grid[x]%) DO (
SET "grid[xlen]=!grid[xlen]!/_/"
SET "grid[tlen]=!grid[tlen]!__ "
)
SET "grid[disp]=!nx:n=%grid[y]%!%grid[tlen]%%dn:n=1%!bk:n=%grid[bk]%!"
FOR /L %%Y in (1, 1, %grid[y]%) DO (
SET "grid[disp]=!grid[disp]!%grid[xlen]%%dn:n=1%!bk:n=%grid[bk]%!"
)
ECHO %ESC%[?25l
IF exist "%temp%\%~n0_signal.txt" (
DEL "%temp%\%~n0_signal.txt"
)
"%~F0" CONTROL >"%temp%\%~n0_signal.txt" | "%~F0" GAME <"%temp%\%~n0_signal.txt" & set /a score=!errorlevel!
echo(
echo(
echo(
echo(
echo(
echo(
if %score% lss 0 (
echo You died!
set /a score=score*-1-1
)
echo Score: %score%
echo(
EXIT /B
:GAME
FOR /L %%# in () DO (
SET /P "rec="
TITLE Score : !score!
ECHO %ESC%[2J%col:c=222;218;206%%ESC%[5;10H%grid[disp]%%col:c=135;245;233%!p[dp]!%col:c=222;201;131%%ESC%[!y[u]!;!x[u]!Hß%bk:n=1%%up:n=1%Û
SET /A "count+=1"
if !rec! == Q exit !score!
FOR %%G in (!rec!) DO (
(SET /A "y[t]=y[u]","x[t]=x[u]",!mv[%%G]:#=t!,"1/((((5-y[t])>>31)&1)&(((y[t]-(grid[y]+6))>>31)&1)&((((((grid[y]-(y[t]-5)))+10)-x[t])>>31)&1)&(((x[t]-((((grid[y]-(y[t]-5)))+10)+(3*grid[x])))>>31)&1))" 2>NUL) && (
SET /A !mv[%%G]:#=u!
)
)
2>NUL SET /A !every:#=15! && (
SET /A "p[ct]+=1","d[y]=(!RANDOM!*grid[y]/32768+1)+5","d[x]=((grid[y]-(d[y]-5)))+5","d[max]=((grid[y]-(d[y]-5)))+11+(3*grid[x])"
SET /A "p[!p[ct]!]=d[max]<<16|d[y]<<8|d[x]"
SET "p[li]=!p[li]! [!p[ct]!]"
)
2>NUL SET /A !every:#=2! && (
SET "p[dp]="
FOR %%Q in (!p[li]!) DO (
SET /A "d[x]=(p%%Q>>0&255)+3","d[y]=(p%%Q>>8&255)","d[max]=(p%%Q>>16&255)","p%%Q=d[max]<<16|d[y]<<8|d[x]"
IF !d[x]! EQU !d[max]! (
SET /A "score+=1"
SET "p[li]=!p[li]:%%Q=!"
) else (
SET "p[dp]=!p[dp]!%ESC%[!d[y]!;!d[x]!H^>%bk:n=2%Í"
)
IF "!x[u]!;!y[u]!" == "!d[x]!;!d[y]!" (
title You died... Press Q to continue
ECHO %ESC%[2J%col:c=222;218;206%%ESC%[5;10H%grid[disp]%%col:c=135;245;233%!p[dp]!%col:c=219;29;55%%up:n=1%Û
set /a score+=1
exit -!score!
)
)
)
SET "rec="
%framerate%
)
:CONTROL
FOR /L %%C in () do (
FOR /F "tokens=*" %%A in ('CHOICE /C:WASDQ /N') DO (
<NUL SET /P ".=%%A"
if %%A == Q exit
)
)
GOTO :EOF
Dave Benham
-
Lowsun
- Posts: 29
- Joined: 14 Apr 2019 17:22
#3
Post
by Lowsun » 06 Nov 2019 18:04
Ya, SNAKE.bat is pretty inspirational. I like your modifications, but could I ask why you set errorlevel in the EXIT to a negative number? Does it have something to do with having a score of 1 or 0?
-
dbenham
- Expert
- Posts: 2461
- Joined: 12 Feb 2011 21:02
- Location: United States (east coast)
#4
Post
by dbenham » 06 Nov 2019 22:39
So I could differentiate between quit while alive and death. That allows me to ECHO out "You died" when appropriate. The window title is reset once the child processes are terminated.
-
dbenham
- Expert
- Posts: 2461
- Joined: 12 Feb 2011 21:02
- Location: United States (east coast)
#5
Post
by dbenham » 07 Nov 2019 07:35
But your mention of 0 vs 1 reminded me that I forgot to subtract one from the score upon returning from the pipe when you die. I fixed the code a few posts back.
-
Lowsun
- Posts: 29
- Joined: 14 Apr 2019 17:22
#6
Post
by Lowsun » 07 Nov 2019 18:36
Ahhhh yes that makes a lot more sense. Thanks for the suggestions! I ended up not using that bit and instead just made Q for when you die. I guess if you press Q when playing you can't move, but I don't really see a way around that. Here's a final version with a proper menu and different map sizes.
Code: Select all
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
MODE 60, 25
IF not "%~1" == "" (
GOTO :%~1
)
FOR /F %%A in ('ECHO prompt $E^| cmd') DO SET "ESC=%%A"
SET "score=0"
SET mv[W]="y[#]-=1","x[#]+=1"
SET mv[A]="x[#]-=3"
SET mv[S]="y[#]+=1","x[#]-=1"
SET mv[D]="x[#]+=3"
SET up=%ESC%[nA
SET dn=%ESC%[nB
SET bk=%ESC%[nD
SET nx=%ESC%[nC
SET col=%ESC%[38;2;cm
SET bcl=%ESC%[48;2;cm
SET framerate=FOR /L %%J in (1,40,1000000) DO REM
SET every="1/(((~(0-(count %% #))>>31)&1)&((~((count %% #)-0)>>31)&1))"
ECHO %ESC%[?25l
:MENU
TITLE Dodge Dungeon
ECHO %ESC%[2J%ESC%[0m%ESC%[2;2HLowsun 2019%ESC%[7;10H__ __ __ __ ___%dn:n=1%%bk:n=24%^| \ / \ ^| \ / _` ^|__%dn:n=1%%bk:n=23%^|__/ \__/ ^|__/ \__^> ^|___%dn:n=1%%bk:n=23%%col:c=135;245;233%^<Í D U N G E O N Í^>%ESC%[0m%ESC%[15;9H1) Large%dn:n=2%%ESC%[9G2) Medium%dn:n=2%%ESC%[9G3) Small%ESC%[11;10HSCORE : !score!
CHOICE /C 123 /N>NUL
SET /A "grid[x]=16-(3*%errorlevel%)","grid[y]=13-(3*%errorlevel%)","grid[bk]=(grid[x]*3)+1","score=0","p[rt]=15","margin=20-grid[x]","x[u]=16","y[u]=7"
FOR /L %%X in (1, 1, %grid[x]%) DO (
SET "grid[xlen]=!grid[xlen]!/_/"
SET "grid[tlen]=!grid[tlen]!__ "
)
SET "grid[disp]=!nx:n=%grid[y]%!%grid[tlen]%%dn:n=1%!bk:n=%grid[bk]%!"
FOR /L %%Y in (1, 1, %grid[y]%) DO (
SET "grid[disp]=!grid[disp]!%grid[xlen]%%dn:n=1%!bk:n=%grid[bk]%!"
)
IF exist "%temp%\%~n0_signal.txt" (
DEL "%temp%\%~n0_signal.txt"
)
"%~F0" CONTROL >"%temp%\%~n0_signal.txt" | "%~F0" GAME <"%temp%\%~n0_signal.txt" & SET /A "score=!errorlevel!" & SET "grid[xlen]=" & SET "grid[tlen]="
GOTO :MENU
:GAME
FOR /L %%# in () DO (
SET /P "rec="
TITLE Score : !score!
ECHO %ESC%[2J%col:c=222;218;206%%ESC%[5;%margin%H%grid[disp]%%ESC%[1B%ESC%[%margin%GUse WASD to move%col:c=135;245;233%!p[dp]!%col:c=222;201;131%%ESC%[!y[u]!;!x[u]!Hß%bk:n=1%%up:n=1%Û
SET /A "count+=1"
FOR %%G in (!rec!) DO (
(SET /A "y[t]=y[u]","x[t]=x[u]",!mv[%%G]:#=t!,"1/((((5-y[t])>>31)&1)&(((y[t]-(grid[y]+6))>>31)&1)&((((((grid[y]-(y[t]-5)))+%margin%)-x[t])>>31)&1)&(((x[t]-((((grid[y]-(y[t]-5)))+%margin%)+(3*grid[x])))>>31)&1))" 2>NUL) && (
SET /A !mv[%%G]:#=u!
)
)
FOR %%Q in (!p[rt]!) DO (
2>NUL SET /A !every:#=%%Q! && (
SET /A "p[ct]+=1","d[y]=(!RANDOM!*grid[y]/32768+1)+5","d[x]=((grid[y]-(d[y]-5)))+5","d[max]=((grid[y]-(d[y]-5)))+(%margin%+1)+(3*grid[x])"
SET /A "p[!p[ct]!]=d[max]<<16|d[y]<<8|d[x]"
SET "p[li]=!p[li]! [!p[ct]!]"
)
)
2>NUL SET /A !every:#=50! && (
IF !p[rt]! GTR 2 (
SET /A "p[rt]-=1"
)
)
2>NUL SET /A !every:#=2! && (
SET "p[dp]="
FOR %%Q in (!p[li]!) DO (
SET /A "d[x]=(p%%Q>>0&255)+3","d[y]=(p%%Q>>8&255)","d[max]=(p%%Q>>16&255)","p%%Q=d[max]<<16|d[y]<<8|d[x]"
IF !d[x]! EQU !d[max]! (
SET /A "score+=1"
SET "p[li]=!p[li]:%%Q=!"
) else (
SET "p[dp]=!p[dp]!%ESC%[!d[y]!;!d[x]!H^>%bk:n=2%Í"
)
IF "!x[u]!;!y[u]!" == "!d[x]!;!d[y]!" (
ECHO %ESC%[2J%col:c=222;218;206%%ESC%[5;%margin%H%grid[disp]%%ESC%[1B%ESC%[%margin%GOuch^^! Press Q to continue%col:c=135;245;233%!p[dp]!%col:c=219;29;55%%up:n=1%Û
EXIT !score!
)
)
)
SET "rec="
%framerate%
)
:CONTROL
FOR /L %%C in () do (
FOR /F "tokens=*" %%A in ('CHOICE /C:WASQD /N') DO (
<NUL SET /P ".=%%A"
IF "%%A" == "Q" (
EXIT
)
)
)
GOTO :EOF
-
dbenham
- Expert
- Posts: 2461
- Joined: 12 Feb 2011 21:02
- Location: United States (east coast)
#7
Post
by dbenham » 08 Nov 2019 18:18
An alternative to adding the Q key that can freeze the game is to use the presence of a file as a signal that the player has died. I used that technique for multiple purposes in SNAKE.BAT.
and, Doh! you forgot to add a Quit option to the Menu
Here is the modified code
Code: Select all
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
MODE 60, 25
IF not "%~1" == "" (
GOTO :%~1
)
FOR /F %%A in ('ECHO prompt $E^| cmd') DO SET "ESC=%%A"
SET "score=0"
SET mv[W]="y[#]-=1","x[#]+=1"
SET mv[A]="x[#]-=3"
SET mv[S]="y[#]+=1","x[#]-=1"
SET mv[D]="x[#]+=3"
SET up=%ESC%[nA
SET dn=%ESC%[nB
SET bk=%ESC%[nD
SET nx=%ESC%[nC
SET col=%ESC%[38;2;cm
SET bcl=%ESC%[48;2;cm
SET framerate=FOR /L %%J in (1,40,1000000) DO REM
SET every="1/(((~(0-(count %% #))>>31)&1)&((~((count %% #)-0)>>31)&1))"
ECHO %ESC%[?25l
del "%~dpn0.quit" 2>nul
:MENU
TITLE Dodge Dungeon
ECHO %ESC%[2J%ESC%[0m%ESC%[2;2HLowsun 2019%ESC%[7;10H__ __ __ __ ___%dn:n=1%%bk:n=24%^| \ / \ ^| \ / _` ^|__%dn:n=1%%bk:n=23%^|__/ \__/ ^|__/ \__^> ^|___%dn:n=1%%bk:n=23%%col:c=135;245;233%^<Í D U N G E O N Í^>%ESC%[0m%ESC%[15;9H1) Large%dn:n=2%%ESC%[9G2) Medium%dn:n=2%%ESC%[9G3) Small%dn:n=2%%ESC%[9GQ) Quit%ESC%[11;10HSCORE : !score!
CHOICE /C 123Q /N>NUL
if %errorlevel% == 4 cls & exit /b
SET /A "grid[x]=16-(3*%errorlevel%)","grid[y]=13-(3*%errorlevel%)","grid[bk]=(grid[x]*3)+1","score=0","p[rt]=15","margin=20-grid[x]","x[u]=16","y[u]=7"
FOR /L %%X in (1, 1, %grid[x]%) DO (
SET "grid[xlen]=!grid[xlen]!/_/"
SET "grid[tlen]=!grid[tlen]!__ "
)
SET "grid[disp]=!nx:n=%grid[y]%!%grid[tlen]%%dn:n=1%!bk:n=%grid[bk]%!"
FOR /L %%Y in (1, 1, %grid[y]%) DO (
SET "grid[disp]=!grid[disp]!%grid[xlen]%%dn:n=1%!bk:n=%grid[bk]%!"
)
IF exist "%temp%\%~n0_signal.txt" (
DEL "%temp%\%~n0_signal.txt"
)
"%~F0" CONTROL >"%temp%\%~n0_signal.txt" | "%~F0" GAME <"%temp%\%~n0_signal.txt" & SET /A "score=!errorlevel!" & SET "grid[xlen]=" & SET "grid[tlen]="
GOTO :MENU
:GAME
FOR /L %%# in () DO (
SET /P "rec="
TITLE Score : !score!
ECHO %ESC%[2J%col:c=222;218;206%%ESC%[5;%margin%H%grid[disp]%%ESC%[1B%ESC%[%margin%GUse WASD to move%col:c=135;245;233%!p[dp]!%col:c=222;201;131%%ESC%[!y[u]!;!x[u]!Hß%bk:n=1%%up:n=1%Û
SET /A "count+=1"
FOR %%G in (!rec!) DO (
(SET /A "y[t]=y[u]","x[t]=x[u]",!mv[%%G]:#=t!,"1/((((5-y[t])>>31)&1)&(((y[t]-(grid[y]+6))>>31)&1)&((((((grid[y]-(y[t]-5)))+%margin%)-x[t])>>31)&1)&(((x[t]-((((grid[y]-(y[t]-5)))+%margin%)+(3*grid[x])))>>31)&1))" 2>NUL) && (
SET /A !mv[%%G]:#=u!
)
)
FOR %%Q in (!p[rt]!) DO (
2>NUL SET /A !every:#=%%Q! && (
SET /A "p[ct]+=1","d[y]=(!RANDOM!*grid[y]/32768+1)+5","d[x]=((grid[y]-(d[y]-5)))+5","d[max]=((grid[y]-(d[y]-5)))+(%margin%+1)+(3*grid[x])"
SET /A "p[!p[ct]!]=d[max]<<16|d[y]<<8|d[x]"
SET "p[li]=!p[li]! [!p[ct]!]"
)
)
2>NUL SET /A !every:#=50! && (
IF !p[rt]! GTR 2 (
SET /A "p[rt]-=1"
)
)
2>NUL SET /A !every:#=2! && (
SET "p[dp]="
FOR %%Q in (!p[li]!) DO (
SET /A "d[x]=(p%%Q>>0&255)+3","d[y]=(p%%Q>>8&255)","d[max]=(p%%Q>>16&255)","p%%Q=d[max]<<16|d[y]<<8|d[x]"
IF !d[x]! EQU !d[max]! (
SET /A "score+=1"
SET "p[li]=!p[li]:%%Q=!"
) else (
SET "p[dp]=!p[dp]!%ESC%[!d[y]!;!d[x]!H^>%bk:n=2%Í"
)
IF "!x[u]!;!y[u]!" == "!d[x]!;!d[y]!" (
ECHO %ESC%[2J%col:c=222;218;206%%ESC%[5;%margin%H%grid[disp]%%ESC%[1B%ESC%[%margin%GOuch^^! Press any of WASD to continue%col:c=135;245;233%!p[dp]!%col:c=219;29;55%%up:n=1%Û
copy nul "%~dpn0.quit" >nul
EXIT !score!
)
)
)
SET "rec="
%framerate%
)
:CONTROL
FOR /L %%C in () do (
FOR /F "tokens=*" %%A in ('CHOICE /C:WASD /N') DO (
if exist "%~dpn0.quit" del "%~dpn0.quit" & exit
<NUL SET /P ".=%%A"
)
)
GOTO :EOF
Dave Benham
-
Lowsun
- Posts: 29
- Joined: 14 Apr 2019 17:22
#8
Post
by Lowsun » 08 Nov 2019 20:54
Oh right! Thanks man, I really appreciate your help! "Dodge Dungeon" is now a finished script