[SOLVED] SET /a -- Random Number?
Moderator: DosItHelp
[SOLVED] SET /a -- Random Number?
I really hope that this doesn't already exist and that I don't just suck at searching....
Anyways, I'm writing a small quiz game in Batch, and am wondering how to create and limit a random number generator. I have reason to believe this is possible using "set /a," however I am not positive on this, nor how to make it work.
What I want:
A Random Number Generator, limited to numbers in between 'x' and 'y', where 'x' and 'y' are defined before hand, and the ability of the batch file to then direct to a different section of the file, by section title of the number defined.
Something like:
RAND#= Z
GOTO Z
:T
Stuff relating to T
:Z
Stuff relating to Z
Thanks ahead of time,
Geoffrey
Anyways, I'm writing a small quiz game in Batch, and am wondering how to create and limit a random number generator. I have reason to believe this is possible using "set /a," however I am not positive on this, nor how to make it work.
What I want:
A Random Number Generator, limited to numbers in between 'x' and 'y', where 'x' and 'y' are defined before hand, and the ability of the batch file to then direct to a different section of the file, by section title of the number defined.
Something like:
RAND#= Z
GOTO Z
:T
Stuff relating to T
:Z
Stuff relating to Z
Thanks ahead of time,
Geoffrey
Last edited by g2geo94 on 16 May 2011 09:38, edited 1 time in total.
Re: SET /a -- Random Number?
'
[edit] probably too difficult, see dbenhams post below please !
[edit] probably too difficult, see dbenhams post below please !
Code: Select all
::for /f "usebackq tokens=1-3 delims=¦" %%b in ( '"MinimumSTR"¦"MaximumSTR"¦"StoreVAR"' ) do %Get.RandomNumber.TokenSTR% %()%
::
for %%? in ( Get.RandomNumber.TokenSTR ) do set "%%~?=set /a Minimum = %%~b ^&set /a Maximum = %%~c ^&set /a interval = ^^^!Maximum^^^! - ^^^!Minimum^^^! ^&call set /a %%~d = %%Random%% ^&set /a %%~d = ^^^!%%~d^^^! * ^^^!interval^^^! / 32767 + ^^^!Minimum^^^! ^&( echo. ^&echo. ^&set /p "?= %%~d : '^^^!%%~d^^^!' [OK]" ^<nul ) "
Re: SET /a -- Random Number?
This is going to more than likely seem very noobish, but could you break that down a bit?
Re: SET /a -- Random Number?
'
I am not good in english, what u mean by 'seem very noobish' ? sorry.
I am not good in english, what u mean by 'seem very noobish' ? sorry.
Code: Select all
@echo off &SetLocal EnableExtensions EnableDelayedExpansion
::I want a randomnumber, & i want to jump based on this number right ?
::create executable variable @Get.RandomNumber.TokenSTR
for %%? in ( Get.RandomNumber.TokenSTR ) do set "%%~?=set /a Minimum = %%~b ^&set /a Maximum = %%~c ^&set /a interval = ^^^!Maximum^^^! - ^^^!Minimum^^^! ^&call set /a %%~d = %%Random%% ^&set /a %%~d = ^^^!%%~d^^^! * ^^^!interval^^^! / 32767 + ^^^!Minimum^^^! ^&( echo. ^&echo. ^&set /p "?= %%~d : '^^^!%%~d^^^!' [OK]" ^<nul ) "
::This is how you use it
::for /f "usebackq tokens=1-3 delims=¦" %%b in ( '"MinimumSTR"¦"MaximumSTR"¦"StoreVAR"' ) do %Get.RandomNumber.TokenSTR% %()%
::Lets use it...
echo.
echo.
for /f "usebackq tokens=1-3 delims=¦" %%b in ( '"1"¦"4"¦"RandomNumber"' ) do %Get.RandomNumber.TokenSTR% %()% >nul
call :LABEL%RandomNumber%
for /f "usebackq tokens=1-3 delims=¦" %%b in ( '"1"¦"4"¦"RandomNumber"' ) do %Get.RandomNumber.TokenSTR% %()% >nul
call :LABEL%RandomNumber%
for /f "usebackq tokens=1-3 delims=¦" %%b in ( '"1"¦"4"¦"RandomNumber"' ) do %Get.RandomNumber.TokenSTR% %()% >nul
call :LABEL%RandomNumber%
goto :Exit ()
:LABEL1
echo.LABEL1
goto :EOF ()
:LABEL2
echo.LABEL2
goto :EOF ()
:LABEL3
echo.LABEL3
goto :EOF ()
:LABEL4
echo.LABEL4
goto :EOF ()
:Exit
pause
exit 0
Re: SET /a -- Random Number?
Random numbers are actually very easy with batch. %RANDOM% is a dynamic pseudo variable that returns a pseudo random number between 0 and 32767. The only thing remaining is to use the modulo operator (%, or %% in a batch file) to limit the values between 0 and Count, and add the minimum required value to set the range.
See if this can get you started:
See if this can get you started:
Code: Select all
@echo off
echo:
echo Testing :random without RtnVar
echo:
for /l %%n in (1,1,10) do call :random 1 10
echo:
echo:-------------------------
echo:
echo Testing :random with RtnVar in order to implement random GOTO
echo:
call :random 1, 5 label
goto :%label%
:1
echo option :1
exit /b
:2
echo option :2
exit /b
:3
echo option :3
exit /b
:4
echo option :4
exit /b
:5
echo option :5
exit /b
:random Min Max [RtnVar]
::
:: Compute a pseudo random integral value between numeric values Min and Max
::
:: Return the value in variable RtnVar
:: or display the value if RtnVar not specified
::
:: Min and Max may be specified using any expression supported
:: by SET /A
::
setlocal
set /a rtn=%random% %% ((%~2)-(%~1)+1) + (%~1)
(endlocal
if "%~3" neq "" (set %~3=%rtn%) else echo:%rtn%
)
exit /b
Re: SET /a -- Random Number?
Thank you, dbenham. This should work perfectly.
@Ed, "sound very noobish" is basically saying "I'm gonna sound very stupid and naive in this subject of matter"
@Ed, "sound very noobish" is basically saying "I'm gonna sound very stupid and naive in this subject of matter"
Re: [SOLVED] SET /a -- Random Number?
I did not know about the modulo which is quite handy,
Thank U dbenham
One last thing;
using call in combination with goto gives u:
-nice looking code
-easy to debug
-slow execution times, good for small (100kb)-- scripts
avoiding call in combination with goto gives u:
-bad looking code
-hard to debug
-fast executing time, good for large (100kb)++ scripts
Thank U dbenham
Code: Select all
::for /f "usebackq tokens=1-3 delims=¦" %%b in ( '"MinimumSTR"¦"MaximumSTR"¦"StoreVAR"' ) do %Get.RandomNumber.TokenSTR% %()%
::
for %%? in ( Get.RandomNumber.TokenSTR ) do set "%%~?=set /a Minimum = %%~b &set /a Maximum = %%~c &call set /a %%~d = %%Random%% %%%% ^( %%Maximum%% - %%Minimum%% + 1 ^) + %%Minimum%% &( echo. &echo. &call set /p "?= %%~d : %%%%~d%% [OK]" <nul ) "
One last thing;
using call in combination with goto gives u:
-nice looking code
-easy to debug
-slow execution times, good for small (100kb)-- scripts
avoiding call in combination with goto gives u:
-bad looking code
-hard to debug
-fast executing time, good for large (100kb)++ scripts
Re: [SOLVED] SET /a -- Random Number?
Hi Ed Dyreen
It took me a while to parse your code, but I finally figured out what was going on. You are basically creating and calling a "macro" that takes three arguments. I hadn't seen that batch technique before. (It's a shame DOSKEY macros can't be used in batch!)
It's kind of cool, but it seems like your code is much more complicated than it needs to be.
I came up with the following which I think is simpler to code and easier to follow:
Dave Benham
It took me a while to parse your code, but I finally figured out what was going on. You are basically creating and calling a "macro" that takes three arguments. I hadn't seen that batch technique before. (It's a shame DOSKEY macros can't be used in batch!)
It's kind of cool, but it seems like your code is much more complicated than it needs to be.
I came up with the following which I think is simpler to code and easier to follow:
Code: Select all
echo off
SetLocal
::create "macro" that takes three arguments
set "macroRandom=call set /a %%~c= %%Random%% %%%% ((%%~b)-(%%~a)+1) + (%%~a)"
::a few equivalent examples of calling the "macro"
for /f "tokens=1-3" %%a in ("10 20 result1") do %macroRandom%
for /f "tokens=1-3 delims=," %%a in ("10,20,result2") do %macroRandom%
for /f "tokens=1-3 delims=," %%a in ("5 + 5,20,result3") do %macroRandom%
for /f "usebackq tokens=1-3 delims=:" %%a in ('5 + 5:20:result4') do %macroRandom%
for /f "usebackq tokens=1-3 delims=," %%a in ('5 + 5^,20^,result5') do %macroRandom%
set /a min=10, max=20
for /f "tokens=1-3" %%a in ("min max result6") do %macroRandom%
::hide more of the details in a two part macro
set "randomPart1=for /f "tokens=1-3" %%a in"
set "randomPart2=do call set /a %%~c= %%Random%% %%%% ((%%~b)-(%%~a)+1) + (%%~a)"
::call the two part macro
%randomPart1% ("10 20 result7") %randomPart2%
::display results of "calls"
set result
Dave Benham
Re: [SOLVED] SET /a -- Random Number?
'
It pleases me that someone I look up to likes my macro technique
I have never seen it before either &I wonder if I am the only that used it until now. Probably not
The reason for this technique is frustration. Frustration because my script is build upon sort of a sjablon consisting of several files that are used like we use #include in a high level language.
Frustrated with the time consuming calls &goto commands I discovered/devellopped a much faster 'macro' technique.
The difference between this macro and a function is that a function would have to be called EVERY time it is used.
A variable/macro gets loaded into memory only once &doesn't need anything to be jumped to or read from to be used.
That's why it is about a factor 1000 faster than any similar function.
You are doing basically the same thing as I &yes my macro is more complicated than needs to be. But really at those speeds the delay is hardly measurable. The reason it is more complicated is because I have more than one macro to load &am always looking for standardization (similar function should look alike if possible).
The thing you have left out at the end ( echo hello world ) is actually quite handy, it displays the results which can be easily suppressed if you send the output to nul.
But hey, every person has his own programming style &that in fact is a good thing!
For the moment I am converting many simple functions to macros since it is only for about a month I use this technique &there is a lot that still needs to be done.
In the end (whenever that is) my sjablon consists of only one function that uses a loop
set "@MACRO=set "RULE=while this is true" &call :LoopUntil"
for something in ( something ) do @MACRO
end of program
::Functions >>
:LoopUntil ( /rule: "ByVAR" )
%eval% (
::true loop
goto :LOOPUntil "()"
)
:: false
goto :eof
::Functions<<
:EOF ()
In the past I was worried about readability, in the present speed has become my biggest enemy.
These days every second counts; a faster batch gives a more professional look &users would not understand when simple things take time.
It pleases me that someone I look up to likes my macro technique
I have never seen it before either &I wonder if I am the only that used it until now. Probably not
The reason for this technique is frustration. Frustration because my script is build upon sort of a sjablon consisting of several files that are used like we use #include in a high level language.
Frustrated with the time consuming calls &goto commands I discovered/devellopped a much faster 'macro' technique.
The difference between this macro and a function is that a function would have to be called EVERY time it is used.
A variable/macro gets loaded into memory only once &doesn't need anything to be jumped to or read from to be used.
That's why it is about a factor 1000 faster than any similar function.
You are doing basically the same thing as I &yes my macro is more complicated than needs to be. But really at those speeds the delay is hardly measurable. The reason it is more complicated is because I have more than one macro to load &am always looking for standardization (similar function should look alike if possible).
The thing you have left out at the end ( echo hello world ) is actually quite handy, it displays the results which can be easily suppressed if you send the output to nul.
Code: Select all
%Exec.MACRO% >nul
For the moment I am converting many simple functions to macros since it is only for about a month I use this technique &there is a lot that still needs to be done.
In the end (whenever that is) my sjablon consists of only one function that uses a loop
set "@MACRO=set "RULE=while this is true" &call :LoopUntil"
for something in ( something ) do @MACRO
end of program
::Functions >>
:LoopUntil ( /rule: "ByVAR" )
%eval% (
::true loop
goto :LOOPUntil "()"
)
:: false
goto :eof
::Functions<<
:EOF ()
In the past I was worried about readability, in the present speed has become my biggest enemy.
These days every second counts; a faster batch gives a more professional look &users would not understand when simple things take time.
Re: SET /a -- Random Number?
Ed Dyreen wrote:Code: Select all
::for /f "usebackq tokens=1-3 delims=¦" %%b in ( '"MinimumSTR"¦"MaximumSTR"¦"StoreVAR"' ) do %Get.RandomNumber.TokenSTR% %()%
::
for %%? in ( Get.RandomNumber.TokenSTR ) do set "%%~?=set /a Minimum = %%~b ^&set /a Maximum = %%~c ^&set /a interval = ^^^!Maximum^^^! - ^^^!Minimum^^^! ^&call set /a %%~d = %%Random%% ^&set /a %%~d = ^^^!%%~d^^^! * ^^^!interval^^^! / 32767 + ^^^!Minimum^^^! ^&( echo. ^&echo. ^&set /p "?= %%~d : '^^^!%%~d^^^!' [OK]" ^<nul ) "
...You are trying to make yourself look smart but that's actually crap.
Code: Select all
@echo off
:check
set rnd=%random%
if %rnd% GTR 100 goto check
if %rnd% LSS 0 goto check
echo %rnd%
pause
That's it! That's all you freaking have to do! 100 is the max, 0 is the min. Just change those.
I know this is an old thread, but I hate how people try to insult new programmers in this way. It's a jerk move.
Re: [SOLVED] SET /a -- Random Number?
Not cool Nit - I seem to recall an expression - "The pot is calling the kettle black".
I discourage anyone from using Nitt's naive solution, unless you want your computer executing perhaps thousands of unnecessary loops. Each pass has only a 0.3% chance of getting a number between 0 and 100. On average it takes 365 checks to achieve a number less than 100 (based on a 100 call sample). In one case a single call required 1872 checks. Of course the situation is even worse if your max is less than 100.
The modulo solution in my 1st post on this thread is simple and fast.
Dave Benham
I discourage anyone from using Nitt's naive solution, unless you want your computer executing perhaps thousands of unnecessary loops. Each pass has only a 0.3% chance of getting a number between 0 and 100. On average it takes 365 checks to achieve a number less than 100 (based on a 100 call sample). In one case a single call required 1872 checks. Of course the situation is even worse if your max is less than 100.
The modulo solution in my 1st post on this thread is simple and fast.
Dave Benham
Re: [SOLVED] SET /a -- Random Number?
dbenham wrote:Not cool Nit - I seem to recall an expression - "The pot is calling the kettle black".
I discourage anyone from using Nitt's naive solution, unless you want your computer executing perhaps thousands of unnecessary loops. Each pass has only a 0.3% chance of getting a number between 0 and 100. On average it takes 365 checks to achieve a number less than 100 (based on a 100 call sample). In one case a single call required 1872 checks. Of course the situation is even worse if your max is less than 100.
The modulo solution in my 1st post on this thread is simple and fast.
Dave Benham
Modulo is not truly random. And thanks for insulting me when you really don't know what you're even getting at.
My point was that you people are trolling when you post codes like the one I quoted. I know modulo, but Batch has an easier way around it.
And how is < 0.1 seconds a long time to wait? Saying the code is bad because it is slow is naive. This is Batch, we aren't working with large projects in C++ or anything.
You know he wouldn't understand your code, either. That's trolling. When people are new, you work at their level. You people are such jerks.
-
- Posts: 25
- Joined: 24 Feb 2009 14:52
- Location: UK
- Contact:
Re: [SOLVED] SET /a -- Random Number?
Well said nitt however, let's look at the proper way to generate random numbers between (and including) 'min' and 'max'.
The following code will generate a random number between 5..10 inclusively:
The following code will generate a random number between 5..10 inclusively:
Code: Select all
set min=5
set max=10
set /a range=max-min +1
set /a rnd=%random% %%%range% +%min%
echo %rnd%
Re: SET /a -- Random Number?
trying to find a delete option.. i've put this post elsewhere. and copied replies to it too elsewhere, to clean up this thread since it contains Ed's valuable discovery of macros!
i'd like to delete this post of mine and those other posts of mine in this thread which just contain the words del.
i'd like to delete this post of mine and those other posts of mine in this thread which just contain the words del.
Last edited by taripo on 13 Dec 2011 15:44, edited 4 times in total.
Re: SET /a -- Random Number?
'
You can use whatever delimiter you like though...
I have no clue, I don't have that problemtaripo wrote:If I put that in a batch file, and TYPE blah.bat it shows ª
Code: Select all
C:\PROFSYS\ADMIN>prompt $
@echo off
for /f "tokens=1-26 delims=¦" %a in ( "this¦works" ) do echo.a=%~a_ &echo.b=%~b_
a=this_
b=works_