The first mistake is already on the line:
set place=%random% %% 5
This line assigns a string to environment variable place
which consists of
- a random decimal number in range 0 to 32767,
- a space character,
- a percent sign,
- a space character and
- the number 5.
As a result the first if
command line is after processing before execution for example:
if x20934 % 5x==1 goto cave
The Windows command processor exits batch file processing with the error message:
% was unexpected at this time.
That is a pretty clear error message on debugging the batch file. The first argument of command IF is x20934
and so the Windows command processor expects next either the string comparison operator ==
or with command extensions enabled as by default one of the operators EQU
, NEQ
, LSS
, LEQ
, GTR
, GEQ
which are mainly for comparing two 32-bit signed integer values, but can be used also for string comparisons.
Please read the answer on Symbol equivalent to NEQ, LSS, GTR, etc. in Windows batch files for full details how Windows command processor does a string or integer comparison.
So it is first necessary to correct the command line which should evaluate an arithmetic expression and assign the result as string to environment variable place
.
set /A place=%RANDOM% %% 5 + 1
Then it would be possible to use IF conditions with either operator ==
or EQU
to evaluate the result.
The usage of string comparison operator ==
would be faster in this case on which it is 100% sure that place
is a string with first character being 1
, 2
, 3
, 4
or 5
(with decimal code value 49 to 53) and second character is the terminating null (with decimal code value 0). So the function strcmp used by cmd.exe
returns the integer result already after first or second character (byte) compare.
set /A place=%RANDOM% %% 5 + 1
if %place% == 1 goto cave
if %place% == 2 goto plains
if %place% == 3 goto swamp
if %place% == 4 goto volcano
if %place% == 5 goto fail
It would be also possible to use EQU
as operator. But in this case both strings are first converted with function strtol to 32-bit signed integer values which are next compared using an integer comparison. That requires much more CPU cycles to accomplish the comparison.
set /A place=%RANDOM% %% 5 + 1
if %place% EQU 1 goto cave
if %place% EQU 2 goto plains
if %place% EQU 3 goto swamp
if %place% EQU 4 goto volcano
if %place% EQU 5 goto fail
The user running the batch file will not see a difference. The processors in PCs are nowadays so fast that the much more CPU cycles needed for the execution of the two strtol
in comparison to execution of single strcmp
is just a few microseconds.
The batch file execution efficiency can be increased even more by avoiding the five IF conditions completely because of the Windows command processor has to do in worst case five times:
- Open the batch file.
- Set file read position to byte offset of end of last read.
- Read the bytes from batch file up to next line-feed.
- Preprocess the command line to find out if more lines need to be read.
- Remember current byte position in batch file.
- Close the batch file.
- Process the command line completely and execute it.
The IF conditions can be avoided by using appropriate labels and use just command GOTO with a label depending on environment variable place
:
@echo off
set /A place=%RANDOM% %% 5
goto Place%place%
:Place0 - cave
echo You went for a crusade and ended up in a cave.& echo(& pause
rem More commands for cave.
exit /B
:Place1 - plains
echo You went for a crusade and found a plains biome.& echo(& pause
rem More commands for plains.
exit /B
:Place2 - swamp
echo You went for a crusade and ventured into a swamp.& echo(& pause
rem More commands for swamp.
exit /B
:Place3 - volcano
echo You went for a crusade and somehow ended up on a volcano.& echo(& pause
rem More commands for volcano.
exit /B
:Place4 - fail
echo Your boat sank and you survived. You lost 5 coins.& echo(& pause
The Windows command processor interprets just the string after :
up to first delimiter character as label. So it is possible to use the labels as shown above to know which Placex
label is for which place because of the string after the space is ignored by Windows command processor.
The arithmetic expression results in a value in range 0-4
assigned as string to environment variable place
which is concatenated with the string Place
on next command line to the label name to be processed by GOTO to continue batch file processing on the line below that label.
To understand the commands used and how they work, open a command prompt window, execute there the following commands, and read the displayed help pages for each command, entirely and carefully.
echo /?
exit /?
goto /?
pause /?
rem /?
set /?
See also single line with multiple commands for an explanation of operator &
.