Card shuffling script
After both for loops have finished, have all the cards been labelled before function c has
been started? card1=2D card2=2C Card3=2H............... Card52=AS
If that is how it works , how does it randomise them ?
The random number range is reduced by 1 after enter is pressed , if card52 hasn't been
been picked , how can it be picked if the range is now 51?
#echo off
title
rem %random%
setlocal enabledelayedexpansion
set a=0
set e=52
set f=0
for %%a in (2 3 4 5 6 7 8 9 10 J Q K A) do call :a "%%a"
goto c
:a arg1
set b= %~1
for %%b in (%~1D%b%C%b%H%b%S) do call :b "%%b"
exit /b 0
:b arg1
set /a a=a+1
set Card%a%=%~1
exit /b 0
:c
set /a c=%random%*%e%/32768+1
set d=!Card%c%!
set /a f=%f%+1
echo Card #%f%: %d%
echo.
pause
cls
set Card%c%=!Card%e%!
set /a e=%e%-1
if %e% neq 0 goto c
Pause
exit
Related
This question already has answers here:
Nested Variables in Substring selection
(1 answer)
windows batch command nested variable
(2 answers)
Closed 3 months ago.
Simply put, it's
set /a mm=%r:~2,3%
BUT, the 2 is codified as set /a d=2 and the 3 is codified as set /a l=3.
So, now how do I write the first expression using the codified variables?
i.e. set /a mm=%r:~%d%,%l%% doesn't work. What's the gimmick?
I've tried...
set /a mm="%r:~(%%d),%%l%" and all kinds of other codifications but the % usage throws me.
#echo off
::: Experimental Module
set /a s=0
title %date% # %time% playtime.bat by -JpE-
:start
if %s% geq 2 cls & set /a s=0
echo .
echo .
echo %date% # %time%
set /a a=11 & set /a b=4 & set /a c=115
echo .
set /a s+=1
echo a==%a%, b==%b%, c==%c%
call :funct1 a,b,c
goto start
::::::::::::::::::::::::::::::::::::::::::::
:funct1
set g=%~2
set h=%~3
call :funct2 z,x,%g%,%h%
call :funct4 %z%,%x%,%g%,%h%
exit /b %errorlevel%
:funct2 <ReturnVar1, ReturnVar2, Arg_g, Arg_h>
set /a g=%~3 & set /a h=%~4
set /a r=1
set /a d=1000
if %g% neq 0 if %g% gtr 0 set /a r=(%d%*%~4/%~3)
::: Return z & x as %~1 & %~2
call :funct3 z,x,r
::::::::::::::::::::::::::::
set "%~1=%z%"
set "%~2=%x%"
exit /b %errorlevel%
::: Calc :::
:funct3 <rr,mm,r>
set /a r=%~3
set bats=C:\Users\JpE\Documents\AAA Sync2Laptop\Batch Files\BCS-Suite
set strlen="%bats%\string_length.bat"
call %strlen% len,r
REM echo length of %r% is %len%
::: 1000 so 3 digits accuracy right of decimal point.
set /a lngt=3
set /a digi=(%len%-%lngt%)
echo * & echo . & echo len==%len% digi==%digi%
:::::::::::::::::::::::::
REM set /a mm=%r:~2,3%
call set /a mm=(%%r:~%digi%,%lngt%%%)
:::::::::::::::::::::::::
set /a rr=(%r%/1000)
::: Okay to here :::
echo sending back from funct3: rr==%rr%, mm==%mm%
set "%~1=%rr%"
set "%~2=%mm%"
exit /b %errorlevel%
::: Display :::
:funct4 <rr,mm,a,b,c>
echo .
echo A == %a%
echo B == %b%
echo C == %c%
echo .
echo C / B == %rr%.%mm%
echo .
pause
echo .
echo .
exit /b %errorlevel%
:return
echo Program Terminating
pause
There is a batch file that looks for Pen=n in the list.txt and changes its value (n) randomly from the given row of ten numbers (set "var[pen]=1 2 3 4 5 6 7 8 9 10"). But if there are more than ten numbers say twenty (set "var[pen]=1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20") or hundred, it is still picking a number from first ten ones ignoring the rest.
#echo off
setlocal EnableDelayedExpansion
set "file=D:\list.txt"
set "temp=D:\temp.txt"
set "var[pen]=1 2 3 4 5 6 7 8 9 10" &
for /L %%i in (1,10,1%time:~-2%) do set "rand=!random!"
(for /F "usebackq tokens=1,2 delims==" %%a in ("%file%") do (
if defined var[%%a] (
call :getRandomValue var="!var[%%a]!"
echo %%a=!var!
) else if "%%b" neq "" (
echo %%a=%%b
) else (
echo %%a
)
)) > "%temp%"
move /Y "%temp%" "%file%"
pause > nul && pause > nul
goto :EOF
:getRandomValue value="list"
set /A "rand=!random:~-1!+1"
for /F "tokens=%rand%" %%v in (%2) do set "%1=%%v"
Any help would be appreciated.
edit:
the list.txt contains a list of stuff like pen paper rubber etc. with the corresponding value next to it.
pen=5
pencil=43
paper=0
rubber=22
what the bat file does is just putting random number picking in up from the row of numbers provided. in the following case it would change the value of pen to a random number from 1 to 10. but if I add some extra numbers more than ten it will then just ignore them.
You forgot to specify the origin post of this problem. In such a post, there is not any specification about how the probabilities must be given, but all the 3 examples provided have 10 probable values, so I assumed that all probabilities have 10 values. The fix is add the number of probabilities each value can have:
#echo off
setlocal EnableDelayedExpansion
rem Define the probabilities for new values
set "value[apple]=0 0 0 0 0 0 0 1 1 1" & set "num[apple]=10" & rem 0 (70%) or 1 (30%)
set "value[peach]=0 0 0 0 0 1 2 3 4 5" & set "num[peach]=10" & rem from 0 (50%) to 5 (the rest 50%)
set "value[banana]=54 68 82 96" & set "num[banana]=4" & rem each 25%
rem Randomize
for /L %%i in (1,10,1%time:~-2%) do set "ran=!random!"
(for /F "tokens=1,2 delims==" %%a in (input.ini) do (
if defined value[%%a] (
call :getRandomValue value=%%a
echo %%a=!value!
) else if "%%b" neq "" (
echo %%a=%%b
) else (
echo %%a
)
)) > output.ini
move /Y output.ini input.ini
goto :EOF
:getRandomValue value=item
set /A "ran=%random%%%num[%2]+1"
for /F "tokens=%ran%" %%v in ("!value[%2]!") do set "%1=%%v"
exit /B
You also forget (again) to provide the real format of the input file, that include [headers]:
[Berries]
Strawberry=1
Blackberry=-13
Blueberry=100
Cherry=6
[Fruits]
apple=0
peach=4
banana=18
orange=-2.5
[Vegetables]
Potato=44
Tomato=2
Onion=0
Garlic=17
EDIT 2022/01/08: New method added as requested in comment
As I already said, you have not specified the rules to define the probable values. I proposed a method that works correctly based on your first example, but then you define values that does not conform with my proposed method (10 possible values, like in your first example). I modified the method and then you invented values that does not conform either: "Why 100 values?" "Because any number above 31 will make the method fail..."
I modified the method (again) so you can define the probabilities via value:percent pairs. Here it is:
#echo off
setlocal EnableDelayedExpansion
rem Define the probabilities for new values as value:percent pairs
set "value[apple]=23:17 68:83" & rem 23 at 17%, 68 at 83%
set "value[peach]=0:50 1:10 2:10 3:10 4:10 5:10" & rem from 0 (50%) to 5 (the rest 50%)
set "value[banana]=54:25 68:25 82:25 96:25" & rem each 25%
rem Randomize
for /L %%i in (1,10,1%time:~-2%) do set "ran=!random!"
(for /F "tokens=1,2 delims==" %%a in (input.ini) do (
if defined value[%%a] (
call :getRandomValue %%a
echo %%a=!value!
) else if "%%b" neq "" (
echo %%a=%%b
) else (
echo %%a
)
)) > output.ini
move /Y output.ini input.ini
goto :EOF
:getRandomValue item
set /A "ran=%random%%%100+1, val=0"
for %%a in (!value[%1]!) do for /F "tokens=1,2 delims=:" %%x in ("%%a") do (
if %ran% gtr !val! set "value=%%x"
set /A val+=%%y
)
exit /B
What you are aiming to do is to randomly index from a list, which requires you to first determine the number of items in the list.
one method of doing so:
#Echo off
Set "var[pen]=a b c d e f g h i"
Rem enable enviroment for !expanison!
Setlocal EnableDelayedExpansion
Rem Build 'array', splitting string on spaces and incrementing array size count
Set _i=1& Set "item[1]=%var[pen]: =" & Set /A "_i+=1" & Set "item[!_i!]=%"
Rem index randomly from known array size [one indexed]
For /f delims^= %%i in ('Set /A !random! %%!_i! + 1')Do Echo(Item:%%i = !Item[%%i]!
Pause
I am attempting to figure out a way to do returning if then statements in the for command, here's the code so far:
We have a file called: File.cfg with multiple numbers (no more than 6 numbers):
1
3
4
6
2
5
Setting those numbers as variables:
setlocal enabledelayed expansion
setlocal
set /a count=1
for /F "usebackq delims=" %%a in ( File.cfg ) do (
set line!count!=%%a
set /a count+=1
)
Then attempting to do a returning if then operations:
set /a count=0
echo 1 > list.txt
:Loop
set /a count+=1
echo %count% > list.txt
FOR /F "usebackq delims= " %%a in (list.txt) do (
echo !line%%a!
if %%a==7 goto :eof
if !line%%a!==1 goto 1
if !line%%a!==2 goto 2
if !line%%a!==3 goto 3
if !line%%a!==4 goto 4
if !line%%a!==5 goto 5
if !line%%a!==6 goto 6
)
Example of the goto #'s
:1
code
code
code
goto loop
Though in the end, the batch program ends prematurely, mainly at count 1.
Final output results:
( echo !line1!
if 1 == 7 goto :eof
if !line1! == 1 goto 1
if !line1! == 2 goto 2
if !line1! == 3 goto 3
if !line1! == 4 goto 4
if !line1! == 5 goto 5
if !line1! == 6 goto 6
)
1
Not sure why you have the complicated code unless you are trying to do a proof of concept on something. In my experience the easiest way to achieve your desired outcome is to do this.
#echo off
for /F "usebackq delims=" %%a in ("File.cfg") do CALL :%%a
REM END OF MAIN Functions below
GOTO :EOF
:1
ECHO IN 1
GOTO :EOF
:2
ECHO IN 2
GOTO :EOF
REM Shortened for brevity
The code above will output
IN 1
IN 3
IN 4
IN 6
IN 2
IN 5
If you really want to use array variables then again the easiest solution is the following code.
#echo off
setlocal enabledelayedexpansion
set "count=0"
for /F "usebackq delims=" %%a in ("File.cfg") do (
set /a "count+=1"
set "line!count!=%%a"
)
FOR /L %%G IN (1,1,%count%) DO CALL :!line%%G!
REM END OF MAIN Functions below
GOTO :EOF
:1
ECHO IN 1
GOTO :EOF
:2
ECHO IN 2
GOTO :EOF
REM Shortened for brevity
The aforementioned code will also output
IN 1
IN 3
IN 4
IN 6
IN 2
IN 5
So, I am working on a batch TD game, and whenever i test it and play through Round 1, It crashes instantly. I have no idea what could cause this. I'll send the code, Thanks in advance! (healing and conceding doesnt work right now)
#echo off
goto gamediff
:gamediff
cls
echo GAME COLOUR
echo.
echo [1] Blue (Easy)
echo [2] Yellow (Normal)
echo [3] Red (Hard)
set /p col=
if %col% == 1 set /a cashamm= 500 & set /a damamm= 30 & goto gameload
if %col% == 2 set /a cashamm= 250 & set /a damamm= 50 & goto gameload
if %col% == 3 set /a cashamm= 250 & set /a damamm= 60 & goto gameload
goto gamediff
:gameload
set /a turn= 1
set /a basic= 0
set /a heavy= 0
set /a snip= 0
set /a total= 0
set /a cash= %cashamm%
set /a dam= %damamm%
set /a attack= 0
set /a heal= 3
set /a health= 500
ping 127.0.0.1 -n 2 > nul
if %col% == 1 color b0
if %col% == 2 color f0
if %col% == 3 color c0
goto game
:game
cls
set /a nonpro= %dam%
echo Round %turn%
echo Cash: %cash%
echo Opponent Damage: %dam%
echo Your Protection: %attack%
echo Helth: %health%
echo.
echo STATS
echo Basic Troops: %basic%
echo Heavy Troops: %heavy%
echo Sniping Troops: %snip%
echo TOTAL: %total%
echo.
echo.
echo [0] Concede
echo [1] Play Round
echo [2] Recruitment
echo [3] Heal (Heals left: %heal%)
set /p gamin=
if %gamin% == 0 goto lose
if %gamin% == 1 goto play
if %gamin% == 2 goto shop
if %gamin% == 3 goto healtime
goto game
:play
cls
echo YOU PROTECT!
ping 127.0.0.1 -n 2 > nul
echo %attack% PROTECTED
ping 127.0.0.1 -n 3 > nul
echo.
echo THEY ATTACK!
ping 127.0.0.1 -n 2 > nul
set /a nonpro-= %attack%
if %nonpro% LSS 1 set /a nonpro= 0
set /a health-= %nonpro%
echo -%nonpro% HEALTH!
pause
if %health% LSS 1 goto lose
if %round% GTR 50 goto win
set /a round+= 1
set /a dam+= %random% %% 20
set /a cash+= %random% %% 100
goto game
:shop
cls
echo Recruitment
echo.
echo [0] Leave
echo [1] Basic Troop (-50 Cash, +15 Protection)
echo [2] Heavy Troop (-100 Cash, +40 Protection)
echo [3] Sniping Troop (-70 Cash,+25 Protection)
set /p shope=
if %shope% == 0 goto game
if %shope% == 1 goto buy1
if %shope% == 2 goto buy2
if %shope% == 3 goto buy3
goto shop
:buy1
if cash LSS 50 goto game
set /a cash-= 50
set /a attack+= 15
goto game
:buy2
if cash LSS 100 goto game
set /a cash-= 100
set /a attack+= 40
goto game
:buy3
if cash LSS 70 goto game
set /a cash-= 70
set /a attack+= 25
goto game
Thanks to anyone who can help me!
If you need more information, please ask for it in the comments.
You can contact me through whatever this site has if you run into any more problems. I can also help you with any questions you have, quickly.
lose and win are non-existent labels. Use quotations when using if, and also with set unless you're declaring a variable as another. The /a switch is not necessary for set whenever arithmetic is not being performed.
Other proper things to do while writing in batch:
--In a goto statement ensure the label is preceded with a colon :.
--When prompting user input in the form of selection with under 9 options, use the choice command. It's more suitable.
--Your variable names should make sense.
--Batch is slow, inefficient, unreliable, elementary, featureless, and basic. Opt for a better coding language that's simple but much, much better, like VB.NET or Python. Batch is barely even a coding language.
The following code has most of the problems I mentioned fixed, except for the choice one because, in some cases, set could be a better option.
#echo off
goto gamediff
:gamediff
cls
echo GAME COLOUR
echo.
echo [1] Blue (Easy)
echo [2] Yellow (Normal)
echo [3] Red (Hard)
set /p "col=>"
if %col% == 1 set /a cashamm = 500 & set /a damamm = 30 & goto gameload
if %col% == 2 set /a cashamm = 250 & set /a damamm = 50 & goto gameload
if %col% == 3 set /a cashamm = 250 & set /a damamm = 60 & goto gameload
goto :gamediff
:gameload
set /a turn = 1
set /a basic = 0
set /a heavy = 0
set /a snip = 0
set /a total = 0
set /a cash = %cashamm%
set /a dam = %damamm%
set /a attack = 0
set /a heal = 3
set /a health = 500
timeout /t 2 /nobreak >NUL
if %col% == 1 color b0
if %col% == 2 color f0
if %col% == 3 color c0
goto :game
:game
cls
set /a nonpro = %dam%
echo Round %turn%
echo Cash: %cash%
echo Opponent Damage: %dam%
echo Your Protection: %attack%
echo Health: %health%
echo.
echo STATS
echo Basic Troops: %basic%
echo Heavy Troops: %heavy%
echo Sniping Troops: %snip%
echo TOTAL: %total%
echo.
echo.
echo [0] Concede
echo [1] Play Round
echo [2] Recruitment
echo [3] Heal (Heals left: %heal%)
set/p "gamin=>"
if %gamin% == 0 goto lose
if %gamin% == 1 goto play
if %gamin% == 2 goto shop
if %gamin% == 3 goto healtime
goto :game
:play
cls
echo YOU PROTECT!
timeout /t 2 /nobreak >NUL
echo %attack% PROTECTED
timeout /t 3 /nobreak >NUL
echo.
echo THEY ATTACK!
timeout /t 3 /nobreak >NUL
set /a nonpro -= %attack%
if "%nonpro%" LSS "1" set /a nonpro = 0
set /a health -= %nonpro%
echo -%nonpro% HEALTH!
if "%health%" LSS "1" goto :lose
if "%round%" GTR "50" goto :win
set /a round += 1
set /a dam += %random% %% 20
set /a cash += %random% %% 100
goto :game
:shop
cls
echo Recruitment
echo.
echo [0] Leave
echo [1] Basic Troop (-50 Cash, +15 Protection)
echo [2] Heavy Troop (-100 Cash, +40 Protection)
echo [3] Sniping Troop (-70 Cash,+25 Protection)
set /p "shope=>"
if "%shope%" == "0" goto :game
if "%shope%" == "1" goto :buy1
if "%shope%" == "2" goto :buy2
if "%shope%" == "3" goto :buy3
goto :shop
:buy1
if "%cash%" LSS "50" goto :game
set /a cash -= 50
set /a attack += 15
goto :game
:buy2
if "%cash%" LSS "100" goto :game
set /a cash -= 100
set /a attack += 40
goto :game
:buy3
if "%cash%" LSS "70" goto :game
set /a cash -= 70
set /a attack += 25
goto :game
:lose
REM When the player loses, run this code
goto :game
:win
REM When the player wins, run this code
goto :game
Also, your shop doesn't work. Also also I tested your code I modified and it does work
My job is to write a small script in cmd which compares two variables(number) a and b.
If a is smaller than b then it counts from a to b with 1 steps
if a is bigger than b then it counts from a to b backwards.
Here is the code:
if a LSS b (for /L %%g in (a, 1, b) do echo %%g) else (for /L %%g in (a, -1, b) do echo %%g)
if i set a to 1 and b to 10 it only writes out 2 zeros.
set /a a=1
set /a b=10
Where is the problem?
Your variables need to be wrapped in % marks to access them
set a=1
set b=10
if %a% LSS %b% (
for /L %%g in (%a%, 1, %b%) do echo %%g
) else (
for /L %%g in (%a%, -1, %b%) do echo %%g
)