Double variables in batch?(Or a way around them?) - batch-file

I'm making a card game, so I'm trying to set a specific amount of times a number can be used, so I'm basically looking for either a way to do "double variables" or a way around them:
#echo off
color 0a
set 1=13
set 2=13
set 3=13
set 4=13
:loop
if %counter%==0
goto :skip
set /a card=%random%*4/32767+1
set %card%=%%card%%-1
goto :loop
:skip
....

I think this is the logic you are going for. Your assumption was correct. You do need double variable expansion. This can be achieved two ways. With Delayed Expansion or using the CALL command. I chose the latter. For the example I set the counter to 13 and kept echoing the contents of each of the variables after each loop.
#echo off
set _1=13
set _2=13
set _3=13
set _4=13
set "counter=13"
:loop
IF "%counter%"=="0" goto skip
set /a card=%random% %% 4 +1
call set /a _%card%=%%_%card%%% - 1
echo _1=%_1%
echo _2=%_2%
echo _3=%_3%
echo _4=%_4%
set /a counter-=1
goto :loop
:skip
pause
EDIT: Now that I look at that again, you actually don't need to use the CALL at all or delayed expansion because the SET command will take care of it for you.
#echo off
set _1=13
set _2=13
set _3=13
set _4=13
set "counter=13"
:loop
IF "%counter%"=="0" goto skip
set /a card=%random% %% 4 +1
set /a _%card%-=1
echo _1=%_1%
echo _2=%_2%
echo _3=%_3%
echo _4=%_4%
set /a counter-=1
goto :loop
:skip

Related

Is there a way to run these 2 batch scripts simultaneously? on the same file, combined

I have these 2 scripts .bat working fine individually, but I want to combine them into one, so they can run their commands at the same time, instead of consecutively.
Let me explain my idea:
I'm testing a program made by a German, which consists of showing bmp images on your cmd console (also using gifs frames on a loop to show animated images as well). the plugin made for this to work is called Insertbmp.exe:
#echo off
title BMP console
cd bin\sprimg
pause
cls
color 0f
mode 81,41
cls
set name=openedk
:loop1
openedk\insertbmp /p:"%name%%loop%.bmp" /x:0 /y:0 /z:0
set /a loop=%loop%+1
if not exist openedk\%name%%loop%.bmp goto endofloop1
timeoutms 100
goto loop1
:endofloop1
set /a lo=%lo%+1
set loop=0
if %lo% lss 4 goto loop1
set lo=0
pause
color f0
mode 62,32
cls
set name=alien
:loop2
alien\insertbmp /p:"%name%%loop%.bmp" /x:0 /y:0 /z:0
set /a loop=%loop%+1
if not exist alien\%name%%loop%.bmp goto endofloop2
timeoutms 100
goto loop2
:endofloop2
set /a lo=%lo%+1
set loop=0
if %lo% lss 4 goto loop2
set lo=0
pause
color 0f
mode 62,22
cls
set name=sleep
:loop3
sleep\insertbmp /p:"%name%%loop%.bmp" /x:0 /y:18 /z:0
set /a loop=%loop%+1
if not exist sleep\%name%%loop%.bmp goto endofloop3
timeoutms 100
goto loop3
:endofloop3
set /a lo=%lo%+1
set loop=0
if %lo% lss 3 goto loop3
set lo=0
pause
color 0f
mode 33,2
cls
echo End of TEST file
pause
exit
the other one is also a batch script made to type lines by itself, it's called ghost typer:
#echo off
:: Ghost typer
setlocal enableextensions enabledelayedexpansion
set lines=7
set "line1=This was a triumph"
set "line2=I'm making a note here: huge success"
set "line3=It's hard to overstate my satisfaction"
set "line4=Aperture science"
set "line5=We do what we must because we can"
set "line6=For the good of all of us"
set "line7=Except the ones who are dead"
for /f %%a in ('"prompt $H&for %%b in (1) do rem"') do set "BS=%%a"
for /L %%a in (1,1,%lines%) do set num=0&set "line=!line%%a!"&call :type
pause>nul
goto :EOF
:type
set "letter=!line:~%num%,1!"
set "delay=%random%%random%%random%%random%%random%%random%%random%"
set "delay=%delay:~-6%"
if not "%letter%"=="" set /p "=a%bs%%letter%" <nul
:: adjust the 3 in the line below: higher is faster typing speed
for /L %%b in (1,2,%delay%) do rem
if "%letter%"=="" echo.&goto :EOF
set /a num+=1
goto :type
Basically, what I have in mind is: run those commands simultaneously on the same line so it doesn't consecutively run them, giving me a cmd console typing whatever I want by it self, while showing me my animated images one by one which I already have on my folder.
on my current situation, it only runs the loop command before it runs the typer codes.
any suggestions?
(I'm rookie on coding anything, sorry)

Using Mode Command to Resize Command prompt Clears Entire Screen

So I try Writing the codes to generate random characters and I want to make the screen always at the same size but when I tried using mode command it clears all text or you can call it entire screen
Here is the code:
:startprg
mode con: cols=120 lines=24
setlocal EnableDelayedExpansion
set char=abcdeijklmnstuvwxyzABCDETUVYZ23456789^^%%_`^^%%_`^^%%_`^^%%_`^^%%_`☺☻♥♦♣♠◘•○☺☻♥♦♣♠◘♂♀q7•-6○Z♂n¡* /*-+##$*()_=-=+
set count=0
set hla=0
:Number
set hla=120
set /a length=-1 + !hla!
:Loop
set /a count+=1
set /a rand=%Random%%%61
set buffer=!buffer!!char:~%rand%,1!
if !count! leq !length! goto Loop
title ^!buffer!
echo ^!buffer!
set /a length+=1
endlocal
goto startprg
Please help me I'm on Windows 10 and I don't know how to fix this problem
Currently each time you goto :startprg you reset the mode. Simply move the label to after mode con: in order to initiate it only once. So it should be:
#echo off
mode con: cols=120 lines=24
:startprg
setlocal EnableDelayedExpansion
So the full code would be as:
#echo off
mode con: cols=120 lines=24
:startprg
setlocal EnableDelayedExpansion
set char=abcdeijklmnstuvwxyzABCDETUVYZ23456789^^%%_`^^%%_`^^%%_`^^%%_`^^%%_`☺☻♥♦♣♠◘•○☺☻♥♦♣♠◘♂♀q7•-6○Z♂n¡* /*-+##$*()_=-=+
set count=0
set hla=0
:Number
set hla=120
set /a length=-1 + !hla!
:Loop
set /a count+=1
set /a rand=%Random%%%61
set buffer=!buffer!!char:~%rand%,1!
if !count! leq !length! goto Loop
title ^!buffer!
echo ^!buffer!
set /a length+=1
endlocal
goto startprg

How does this batch password generation work?

I am creating a password generator in batch, and had to use some help from the internet to finish it, but I am having difficulty interpreting the section of the code I had to borrow. Would someone please explain it?
:generate
#Echo Off
color 0a
set /P usernumberlength="What length do you want your password to be? "
pause
cls
Setlocal EnableDelayedExpansion
Set RNDLength=%usernumberlength%
/// from here
Set Alphanumeric=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
Set Str=%Alphanumeric%987654321
:loop
IF NOT "%Str:~18%"=="" SET Str=%Str:~9%& SET /A Length+=9& GOTO :loop
SET tmp=%Str:~9,1%
SET /A Length=Length+tmp
Set count=0
SET RndAlphaNum=
:loop2
Set /a count+=1
SET RND=%Random%
Set /A RND=RND%%%Length%
SET RndAlphaNum=!RndAlphaNum!!Alphanumeric:~%RND%,1!
If !count! lss %RNDLength% goto loop2
/// to here
Echo Password is: is !RndAlphaNum!
Echo Now choose what you want to do.
Echo 1) Go back to the beginning
Echo 2) Exit
set input=
set /p input= Choice:
if %input%==1 goto generate
if %input&==2 exit
pause
This working example (from the code you provided) contains the all-you-need section.
#echo Off
color 0a
setlocal enabledelayedexpansion
:generate
set /p usernumberlength="What length do you want your password to be? "
rem ----- begin section all you need -----
Set Alphanumeric=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
rem "Length" is the string length of %alphanumeric%
Set Length=62
set count=0
rem "RndAlphaNum" is the output
SET RndAlphaNum=
:loop
Set /a count+=1
Set /A RND=%Random% %% %Length%
SET RndAlphaNum=!RndAlphaNum!!Alphanumeric:~%RND%,1!
if !count! lss %usernumberlength% goto loop
rem ----- end section all you need -----
echo Password is: !RndAlphaNum!
goto generate

Batch Roguelike Game

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.
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%
#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.

batch file variable problems

I am having problems with variables transferring throughout my batch file.
This is a rough example of what I have:
#echo off
setlocal enabledelayedexpansion
:one
set variableone=outputone
set variabletwo=outputtwo
set variablethree=outputthree
goto two
:two
set /a variable%variableone%four=numberone
set /a variable%variabletwo%five=numbertwo
set /a variable%variablethree%six=numberthree
goto three
:three
set /a variable%variableone%four+=(2*(!variable%variabletwo%five!-!!variable%variablethree%six!)
echo !variable%variableone%four!
exit
It is a lot longer than that and this is just a simplified version of what it actually is, however, the variables in the label ":three" won't transfer down so the variable ends up blank which leaves the equation blank as well. Is there a way to fix this?
It's tremendously difficult to see what you are doing.
In the below code, I've replaced the variable names NUMBER* with values.
I've also added the missing close-parenthesis and I'm wondering about the two successinve !
#ECHO OFF
setlocal enabledelayedexpansion
:one
set variableone=outputone
set variabletwo=outputtwo
set variablethree=outputthree
goto two
:two
set /a variable%variableone%four=numberone
set /a variable%variabletwo%five=numbertwo
set /a variable%variablethree%six=numberthree
set /a variable%variableone%four=14
set /a variable%variabletwo%five=25
set /a variable%variablethree%six=36
goto three
:three
set /a variable%variableone%four+=(2*(!variable%variabletwo%five!-!!variable%variablethree%six!))
echo !variable%variableone%four!
set var
Now for me, what is being echoed is -8 which is equal to 14+(2*(25-36))
So - works for me!

Resources