So I've been trying to make the following code:
set /a num1=10
set /a num2=%random% %%60 +%num1%
echo %num2%
(This is simplified)
For this code I need the +%num1% to be a variable because I need to be able to change the lowest number.
For some reason, instead of giving me a random number it gives a totally unrelated number, that isn't random either, but the same every time. My first thought was it was perhaps adding the second variable instead of making a randomizer. That is not the case though, and I'm not sure how to fix this issue.
I have also tried the following code:
set /a num1=10
set /a num2=(%random%*60/32768)+%num1%
echo %num2%
The issue with this code is it never seems to work as randomizer for me even without the variable.
Any help is appreciated.
Here's some examples to assist you:
Set "num1=10"
Set /A "num2 = (%RANDOM% %% 60) + num1"
Echo(%num2%
Set "num1=10"
Set /A "num2 = (%RANDOM% * 60 / 32768) + num1"
Echo(%num2%
Please note, that we have only been provided with a very small portion of your batch file, so if this code is part of a parenthesized block, you may need to enable delayed expansion and use !RANDOM! and possibly !num2! instead of %RANDOM% and %num2% respectively.
In the first form you are have to account for modulus bias, as described further in this question Why do people say there is modulo bias when using a random number generator?
(Note: the accepted answer there has a flaw which I pointed out and provide a solution to in my answer to that question.)
In both the first and the second form they present an incorrect range of values the way it is written. More info can be found here How to use random in BATCH script?
Long story Short:
In both forms, if you want your range to start at 10 and go to 60 you will need to adjust it to be using a modulus of 50, in the first form you must account for modulus bias in your calculations causing some numbers to appear more often.
The first form can be fixed using this method:
SET "Min=10"
SET "Max=60"
SET /A "Discard= 32768 - ( ( ( 32768 %% (Min-Max) ) + 1 ) %% (Min-Max) )"
:Rand
SET /A "num2=%random%"
IF %num2% GTR %Discard% GOTO :Rand
SET /A "num2= num2 %% (Min-Max) + Min"
echo=%num2%
The second form can be fixed using this method:
SET "Min=10"
SET "Max=60"
SET /A "num2= %random% * ( Max - Min + 1 ) / 32768 + Min "
echo=%num2%
Example of Full script:
#(SETLOCAL
ECHO OFF
)
CALL :Main
( ENDLOCAL
EXIT /B
pause
)
:Main
SET "Min=10"
SET "Max=60"
SET /A "Discard= 32768 - ( ( ( 32768 %% (Min-Max) ) + 1 ) %% (Min-Max) )"
ECHO=Form1:
CALL :Form1
ECHO=Form2:
CALL :Form2
pause
GOTO :EOF
:Form1
SET "num2=%random%"
IF %num2% GTR %Discard% GOTO :Form1
SET /A "num2= num2 %% ( Min - Max ) + Min"
echo=%num2%
GOTO :EOF
:Form2
SET /A "num2= %random% * ( Max - Min + 1 ) / 32768 + Min "
echo=%num2%
GOTO :EOF
Results:
C:\WINDOWS\system32>C:\Admin\SE\testrandom.cmd
Form1:
10
Form2:
31
Press any key to continue . . .
C:\WINDOWS\system32>
Related
Hello guys I am very bad at notepad, I want to make a random code generator.
That Generates codes like this 3K2EU-ZGS5L-P3DNL-YM9JC
I want it to work with a notepad .bat file so I can let it run on my PC
This can be done using %random% values to assign numbers and letters as demonstrated
below. If you need letters and numbers in specific places within the 20 digits,
adjust the Condition used to call getLetters or Getnumber to call according to current
%dig%==number
#ECHO OFF
SETLOCAL enableDelayedExpansion
:open
Set dig=0
:main
Set /a dig=%dig% + 1
CALL :digit%dig%
Call LetorNum
IF %dig%==20 goto result
GOTO main
:LetorNum
Set /a pick=%random% * 2 / 32768 + 1
IF %pick%==1 call :getLetter
IF %pick%==2 call :getNumber
GOTO :EOF
:getLetter
Set /a Letter=%random% * 26 / 32768 + 1
IF %letter%==1 Set disp!dig!=a
REM repeat for each letter value between a and z
IF %letter%==26 Set disp!dig!=z
GOTO :EOF
:getNumber
Set /a number=%random% * 10 / 32768 + 1
IF %number%==1 Set disp!dig!=0
REM repeat for every number value between zero and 9
IF %number%==9 Set disp!dig!=9
GOTO :EOF
:result
ECHO %disp1%%disp2%%disp3%%disp4%%disp5%-%disp6%%disp7%%disp8%%disp9%%disp10%-
%disp11%%disp12%%disp13%%disp14%%disp15%-%disp16%%disp17%%disp18%%disp19%%disp20%
pause >nul
GOTO open
Have I done something wrong or why this isn't working? I am quite new with batch. It says "The syntax of the command is incorrect."
if %nm1% lss %nm2% (
echo voitit:%voitat%
set /p "tupla=Voitonmaksu.1 tuplaus.2 (1/2)."
)
if %nm1%==%nm2% (
set /a voitat=%voitat% / 2
echo voitit:%voitat%
set /a voitot=%voitot% + %voitat%
pause
goto peli
)
if %nm2% lss %nm1%(
echo voitit:0
pause
goto peli
)
if %tupla%==1 (
set /a voitot=%voitot% + %voitat%
pause
goto peli
)
if %tupla%==2 goto tuplaus
set /a voitat=%voitat% / 2
set /a voitot=%voitot% + %voitat%
These commands won't work as expected because of delayedexpansion (many many SO articles on this - use the search facility in the top bar)
BUT since you are using set/a - the syntax allows the variables to be expressed "nude" - without the % delimiters, when the delayedexpansion quirk becomes irrelevant (but you should read up on it anyway - to obviate the inevitable follow-up question.)
if %nm2% lss %nm1%(
There must be a space between %nm1% and (
If either argument is non-numeric (probably not, given their names) then the arguments must be "quoted" (applies to any if where the arguments may contain spaces)
Following is the code in which I want to create 10 files if the counter reach 10 but the comparison is not working am I missing something or am I doing something wrong? It creates only one file and prints as following in that one file
10 == 0 set
#echo off
set limit=10
set count=0
:start
set count = %count% + 1
echo %limit% == %count% set > YouAreAnIdiot%random%.txt
if %count%==%limit%
exit 0
else
goto start
two errors in one line: set count = %count% + 1:
a) the space between count and = is part of your variable name. (It would be %count %)
b) to calculate with set, you need the /a parameter:
set /a count=%count% + 1
Surprisingly, set /a doesn't care for the additional space, but get used to the syntax without spaces around the = - this keeps life simple.
set /a doesn't need the percent signs with variables, so set /a count=count+1 also works.
There is a short form to do that:
set /a count+=1
Also your if statement will not work. The complete construct has to be on one (logical) line:
if %count%==%limit% (
exit 0
) else (
goto start
)
(note the spaces around the parantheses - they are critical)
I'm making a game where there are stocks, and I want them to be able to go negative, I know how to limit the positive random numbers, but how do I get the %random% to make a negative value? And, is making the %random% generate negative numbers even possible?
Just subtract the random number from 0.
set /a negative_random=0-%random%
To produce a random number in the range minrand to maxrand use
SET /a selection=%RANDOM% %% (%maxrand% - %minrand% + 1) + %minrand%
Here's a sampler : change the values assigned to minrand and maxrand to test:
#ECHO OFF
SETLOCAL
SET /a minrand=-3
SET /a maxrand=3
FOR /l %%a IN (1,1,20) DO CALL :genshow
GOTO :eof
:genshow
SET /a selection=%RANDOM% %% (%maxrand% - %minrand% + 1) + %minrand%
ECHO %selection%
GOTO :EOF
It depends on the range you want. If [-16384, 16383] is enough for you, use this
set /a num=%random%-16384
Otherwise if you need random values in the range [a, b] then use this
set /a num=%random% %%(b-a+1) + a
For example to get values from -10 to 20, use this
set /a num=%random% %%31 - 10
In my code*, I have a simple random number generator and a few ifs to check what number the generator produces. However, even when run in another instance of CMD, in another Batch file, and another instance of this Batch file, it still produces the same number: 4. Every time. I am not using this code in a loop, although it can be looped back to its section. I do, however, have another line of code to generate another number within a different set of parameters that works just fine.
*My code:
:genClass
set /a class=(5 * !random!) / 32768 + 1
if !class!==1 (
set class=Knight
goto genKnightArmor
)
if !class!==2 (
set class=Warrior
goto genWarriorArmor
)
if !class!==3 (
set class=Archer
goto genArcherArmor
)
if !class!==4 (
set class=Thief
goto genThiefArmor
)
if !class!==5 (
set class=Mage
goto genMageArmor
)
:genKnightArmor
set /a armor=(2 * !random!) / 32768 + 1
if !armor!==1 set armor=Light Armor
if !armor!==2 set armor=Heavy Armor
echo !name!
echo !gender!
echo !class!
echo !armor!
pause
exit
:genWarriorArmor
set /a armor=(2 * !random!) / 32768 + 1
if !armor!==1 set armor=Light Armor
if !armor!==2 set armor=Heavy Armor
echo !name!
echo !gender!
echo !class!
echo !armor!
pause
exit
:genArcherArmor
set /a armor=(2 * !random!) / 32768 + 1
if !armor!==1 set armor=Light Armor
if !armor!==2 set armor=Heavy Armor
echo !name!
echo !gender!
echo !class!
echo !armor!
pause
exit
:genThiefArmor
set /a armor=(2 * !random!) / 32768 + 1
if !armor!==1 set armor=Light Armor
if !armor!==2 set armor=Heavy Armor
echo !name!
echo !gender!
echo !class!
echo !armor!
pause
exit
:genMageArmor
set /a armor=(3 * !random!) / 32768 + 1
if !armor!==1 set armor=Light Armor
if !armor!==2 set armor=Heavy Armor
if !armor!==3 set armor=Robes and Hood
echo !name!
echo !gender!
echo !class!
echo !armor!
pause
exit
EDIT: With Monacraft's solution, it now generates a number of 2 and also generates the armor type without error. However, the code to generate the class is still messed up and, as stated before, continues to generate the number 2.
EDIT: I have edited the code once again to change the arithmetic and string variable names. This did not clear anything up, although the class generator is now continuously generating the number 3. I've noticed that, when edited, the generator produces a new number, although, after the first generation, it yields the same number.
EDIT: Fixed mistakes in my code. Such as matching the variables and changing the number 4 in the random generator to 5.
Ok, the main problem with your random number generator is the use of ! instead of %. Unless your using a for loop, you won't need these.
Instead of this:
set /a num=(4 * !random!) / 32768 + 1
Simply use this:
set /a num=(4 * %random%) / 32768 + 1
I tested this in cmd, and it worked fine.
To use ! you need to EnableDelayedExpansion and then use this is a for loop.
Hope this helped with your problem,
Mona.
set /a num=(4 * %random%) / 32768 + 1
if !class!==1 (
Maybe i'm wrong, but, set num and if class does not seem correct
The problem is your expression
set /a num=(4 * !random!) / 32768 + 1
Batch mathematics is integer-only, so this will fail.
Try
set /a num=(%random% %% 4) + 1
Better yet, try in your main code
call :roll armor 3
and add at the end of the code
REM Roll 1..%2
:ROLL
set /a %1=(%random% %% %2) + 1
GOTO :EOF
Note carefully where the colons are - they are critical.
call :roll somevar n
will assign a random number 1..n to the variable somevar
Here's another way to do the selection:
#echo off
:genClass
set name=Slartibartfast
set gender=Alien
set /a num1=%random% %% 5 + 1
set /a num2=%random% %% 2 + 1
if %num1%==1 (
set class=Knight
if %num2%==1 set armor=Light Armor
if %num2%==2 set armor=Heavy Armor
)
set /a num2=%random% %% 2 + 1
if %num1%==2 (
set class=Warrior
if %num2%==1 set armor=Light Armor
if %num2%==2 set armor=Heavy Armor
)
set /a num2=%random% %% 2 + 1
if %num1%==3 (
set class=Archer
if %num2%==1 set armor=Light Armor
if %num2%==2 set armor=Heavy Armor
)
set /a num2=%random% %% 2 + 1
if %num1%==4 (
set class=Thief
if %num2%==1 set armor=Light Armor
if %num2%==2 set armor=Heavy Armor
)
set /a num2=%random% %% 3 + 1
if %num1%==5 (
set class=Mage
if %num2%==1 set armor=Light Armor
if %num2%==2 set armor=Heavy Armor
if %num2%==3 set armor=Robes and Hood
)
echo %name%
echo %gender%
echo %class%
echo %armor%
echo.
pause
goto :genclass