Batch Script Won't Display Variable - windows

I have a Batch Script which when I run wont display a string variable.
#ECHO OFF
color 0c
set /a Copyed = 1
set /a File = %random%
set /a Origin = %~z1
set /a End = 0
set /a OSize = %~z1
if %~z1 LEQ 999 (
set /a Size = %~z1
set Z="Bytes"
)
if %OSize% GEQ 1000 (
set /a OSize /= 1000
set /a OEnd += 1
)
if %OSize% GEQ 1000 (
set /a OSize /= 1000
set /a OEnd += 1
)
if %OSize% GEQ 1000 (
set /a OSize /= 1000
set /a OEnd += 1
)
if %OSize% GEQ 1000 (
set /a OSize /= 1000
set /a OEnd += 1
)
if OEnd == 1 (set OZ="KB")
if OEnd == 2 (set OZ="MB")
if OEnd == 3 (set OZ="GB")
if OEnd == 4 (set OZ="TB")
echo ::::::::::::::::::::::: > %File%
echo :::::::::::::::::::::::
echo Original File "%1" Has A Size Of %OSize% %OZ% >> %File%
echo Original File "%1" Has A Size Of %OSize% %OZ%
pause
When I run this script using another file I get :
:::::::::::::::::::::::
Original File ""P:\Virus Testing\Fill.txt"" Has A Size Of 536
Press any key to continue . . .
In the file it creates I get this :
:::::::::::::::::::::::
Original File ""P:\Virus Testing\Fill.txt"" Has A Size Of 536
As you can see neither of them display the varible %OZ%. How do I fix this? Thanks In Advance

Try
if %OEnd% == 1 (set OZ="KB")
if %OEnd% == 2 (set OZ="MB")
if %OEnd% == 3 (set OZ="GB")
if %OEnd% == 4 (set OZ="TB")

A few bugs in your script:
You need to initialize OEnd, not End
set /a OEnd = 0
You need a descriptor for OZ for bytes, something like
if %OEnd% == 0 (set OZ=Bytes)
And, each of the other checks needs to check the value of OEnd, not name itself:
if %OEnd% == 1 (set OZ=KB)
if %OEnd% == 2 (set OZ=MB)
if %OEnd% == 3 (set OZ=GB)
if %OEnd% == 4 (set OZ=TB)

Related

Game Crashes After Playing The First Round, How Can I Get It To Function Correctly?

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

Batch Script fails in IF statement

My batch script is failing in the second if state of :nbig. (I have found this out using #echo after each statement). However, the SET statement within the if succeed if run normally, as does the if statement with an #echo inside. This is very peculiar and I can't see what I have done wrong.
My code is here:
:: Set the day and night values
set /A nighttemp = 2700
set /A daytemp = 6500
:: Set Transition Duration
set /A transitionduration = 60
:: Set times in minutes from midnight
set /A tnight = 1380
set /A tday = 480
For /f "tokens=1-4 delims=/:." %%a in ("%TIME%") do (
SET /A HH24=%%a
SET /A MI=%%b
SET /A SS=%%c
SET /A FF=%%d
)
SET /A mins = %HH24%*60 + %MI%
SET /A tdaywindow = %tday% + 60
SET /A tnightwindow = %tnight% + 60
if %tnight% GEQ %tday% ( GOTO NBIG)
if %tnight% LSS %tday% ( GOTO DBIG)
pause
:NBIG
if %mins% LSS %tday% ( SET /A temp = %nighttemp% )
if %mins% LSS %tdaywindow% ( SET /A temp = (%daytemp% - %nighttemp%)*((%mins% - %tday%)/60) + %nighttemp% )
if %mins% LSS %tnight%( SET /A temp = %daytemp% )
if %mins% LSS %tnightwindow%( SET /A temp = (%nighttemp% - %daytemp%)*((%mins% - %tnight%)/60) + %daytemp% )
GOTO ENDING
:DBIG
if %mins% LSS %tnight%( SET /A temp = %daytemp% )
if %mins% LSS %tnightwindow% ( SET /A temp = (%nighttemp% - %daytemp%)*((%mins% - %tnight%)/60) + %daytemp%)
if %mins% LSS %tday% ( SET /A temp = %nighttemp% )
if %mins% LSS %tdaywindow% ( SET /A temp = (%daytemp% - %nighttemp%)*((%mins% - %tday%)/60) + %nighttemp% )
GOTO ENDING
:ENDING
#echo %temp%
pause
::%~dp0\redshift.exe -O %temp%
A correctly running program should #echo the value of temp, however it errors.
(Aside: This is to run the redshift program with custom times...)
The batch parser must parse the open and close parentheses before SET /A command, so a closing paren within SET /A is being applied to the opening paren before SET /A.
You would either need to escape the closing parens within the computation
if %mins% LSS %tdaywindow% ( SET /A temp = (%daytemp% - %nighttemp%^)*((%mins% - %tday%^)/60^) + %nighttemp% )
or better yet, enclose the entire assignment within quotes:
if %mins% LSS %tdaywindow% ( SET /A "temp = (%daytemp% - %nighttemp%)*((%mins% - %tday%)/60) + %nighttemp%" )
But perhaps the simplest solution is to ditch the outer parens entirely - they are not needed with the way you have structured your code.
if %mins% LSS %tdaywindow% SET /A "temp = (%daytemp% - %nighttemp%)*((%mins% - %tday%)/60) + %nighttemp%"
Even though they are not needed with this last form, I still like to enclose my SET assignment within quotes.
Unrelated to your error, you can further simplify your code by using the SET /A feature that automatically expands numeric variables without needing % or ! (only available to SET /A)
if %mins% LSS %tdaywindow% SET /A "temp = (daytemp - nighttemp)*((mins - tday)/60) + nighttemp"

Wait for file program failed due to %Counter% LSS %Limit%

SETLOCAL ENABLEDELAYEDEXPANSION
SET /A Counter = 0
SET /A Limit = 5
:File_Check
IF EXIST D:\Automation\OTOT_OBAL\Automation\myfilter.jar (
GOTO Trigger_Found
)
ELSE IF %Counter% LSS %Limit% (
timeout /t 5 /nobreak >null
SET /A Counter = Counter + 1
GOTO File_Check
)
GOTO (VERYEND)
ENDLOCAL
:Trigger_Found
echo ON
echo TRIGGER FOUND
Exit
:VERYEND
echo !Counter!
echo program has reached maximum wait time we are going to exit.
Exit
The else is redundant, but if used must be on the same physical line as the preceding )
The target of the final goto is the label (veryend) not the label veryend.
In the absence of current code:
IF EXIST D:\Automation\OTOT_OBAL\Automation\myfilter.jar (
GOTO Trigger_Found
) ELSE IF %Counter% LSS %Limit% (
timeout /t 5 /nobreak >null
SET /A Counter = Counter + 1
GOTO File_Check
)
GOTO VERYEND
should work
IF EXIST D:\Automation\OTOT_OBAL\Automation\myfilter.jar GOTO Trigger_Found
IF %Counter% LSS %Limit% (
timeout /t 5 /nobreak >null
SET /A Counter = Counter + 1
GOTO File_Check
)
GOTO VERYEND
would probably be better.

manipulate string with a batch

I've got a string named "code" and an int named "lenght" which is the lenght of "code"
also int "todo" which has a value of 0,1 or 2.
0 should delete a character at position "lenght".
1 should change the caracter at position "lenght" to a random character.
2 should add a random charachter at position "lenght".
how do i archive this goal?
SET code="%*f0"
set length=0
:loop0
if defined # (
set #=%#:~1%
set /A length += 1
goto loop0
)
SET /A location=%RANDOM% * %lenght% / 32768 + 1
SET /A todo=%RANDOM% * 2 / 32768 + 1
IF %todo% == 0(
)
IF %todo% == 1(
)
IF %todo% == 2(
)
If correctly understood you, then:
#echo off
setlocal enabledelayedexpansion
set "str=%~f0"
set "len=0"
set "buf=%str%"
:loop
if defined buf (set buf=%buf:~1%& set /a "len+=1" & goto:loop)
echo Delete char at %%len%% position^:
set /a "len-=1"
echo !str:~0,%len%!
echo.
echo Change char at %%len%% position for random^:
rem set chars string
set "map=abcdefghijklmnopqrstuvwxyz"
rem convert it to array
set "i=0"
for /l %%i in (0, 1, 25) do (
for /l %%j in (1, 1, 1) do (
set "arr.!i!=!map:~%%i,%%j!" & set /a "i+=1"
)
)
rem random set 0..25
set /a "rnd=0+25*%random%/32768"
echo !str:~0,%len%!!arr.%rnd%!
endlocal
exit /b

What is wrong with this recursive Windows CMD script? It won't do Ackermann properly

I'm trying to get to calculate the Ackermann function. A description of what I'm trying to achieve is at http://rosettacode.org/wiki/Ackermann_function.
Using the test script, Test 0 4 gives me 5 which is correct. However Test 1 4 gives 5 not 6, and Test 2 4 gives 5 instead of 11.
Where am I going wrong?
::echo off
set depth=0
:ack
if %1==0 goto m0
if %2==0 goto n0
:else
set /a n=%2-1
set /a depth+=1
call :ack %1 %n%
set t=%errorlevel%
set /a depth-=1
set /a m=%1-1
set /a depth+=1
call :ack %m% %t%
set t=%errorlevel%
set /a depth-=1
if %depth%==0 ( exit %t% ) else ( exit /b %t% )
:m0
set/a n=%2+1
if %depth%==0 ( exit %n% ) else ( exit /b %n% )
:n0
set /a m=%1-1
set /a depth+=1
call :ack %m% %2
set t=%errorlevel%
set /a depth-=1
if %depth%==0 ( exit %t% ) else ( exit /b %t% )
I use this script to test it
#echo off
cmd/c ackermann.cmd %1 %2
echo Ackermann of %1 %2 is %errorlevel%
A sample output, for Test 1 1, gives:
>test 1 1
>set depth=0
>if 1 == 0 goto m0
>if 1 == 0 goto n0
>set /a n=1-1
>set /a depth+=1
>call :ack 1 0
>if 1 == 0 goto m0
>if 0 == 0 goto n0
>set /a m=1-1
>set /a depth+=1
>call :ack 0 0
>if 0 == 0 goto m0
>set/a n=0+1
>if 2 == 0 (exit 1 ) else (exit /b 1 )
>set t=1
>set /a depth-=1
>if 1 == 0 (exit 1 ) else (exit /b 1 )
>set t=1
>set /a depth-=1
>set /a m=1-1
>set /a depth+=1
>call :ack 0 1
>if 0 == 0 goto m0
>set/a n=1+1
>if 1 == 0 (exit 2 ) else (exit /b 2 )
>set t=2
>set /a depth-=1
>if 0 == 0 (exit 2 ) else (exit /b 2 )
Ackermann of 1 1 is 2
Change line 27 above from
call :ack %m% %2
to
call :ack %m% 1
What is the scope of your variables m and n?
You set values within one call to :ack, and then recursively call again, setting values. Do you overwrite them? In Stack-based languages such as C and Java, local variables are fine, each level of recursion gets new variables. What happens in cmd?

Resources