如何使随机机会“起作用"?分批 [英] How to make a random chance "function" in Batch
问题描述
我正在做一个小型的小游戏,我希望有一个随机的机会来获得某些物品(例如,如果随机数大于10但小于15,那么您将获得某个物品).这是我已经尝试过导致崩溃的内容.
I'm making a small little game I want a random chance to get certain items (e.g. if the random number is greater than 10 but less than 15 then you will get a certain item). Here's what I've already tried which resulted in a crash.
set /a chance= %random% %%30+1
if %chance% gtr 10 && lss 30 (
set /a %nails%+1
echo You got nails! %chance%
)
这里的这只是一个测试,但是应该让您对我要做什么有所了解.这确实是我想到的唯一方法.如果可以帮助,请执行!:)
This piece right here was just a test, but should give you an idea of what I am going for. This is really the only way I can think of doing it. If you could help, please do! :)
推荐答案
我在该代码中看到了许多问题:
I see a number of problems in that code:
set /a chance= %random% %%30+1
if %chance% gtr 10 && lss 30 (
set /a %nails%+1
echo You got nails! %chance%
)
经历他们:
The
if
statement is not valid,&&
is the "execute next command if previous command worked" conjunction, not a general "and" operator. To do what you want would be:if %chance% gtr 10 if %chance% lss 30
.
See here for a way to doand
andor
incmd
language.
命令 set/a%nails%+ 1
实际上并不以任何方式更改 nails
,它只是计算一个表达并把它扔掉.您需要赋值来赋值,并且在这种情况下不需要变量标记:
set/a"nails + = 1"
.
The command set /a %nails%+1
does not actually change nails
in any way, it just evaluates an expression and throws it away. You need an assignment to assign a value, and you don't need the variable markers in this case:set /a "nails += 1"
.
如果您要使用 delayedexpansion
来打印出 nails
(应该如此),则需要同时使用!
并在变量名之后:
echo您得到了!钉子!%chance%
.
If you're using delayedexpansion
to print out nails
(and you should be), you need a !
both before and after the variable name:echo You got !nails! %chance%
.
顺便说一句,您可能会注意到我喜欢引用我的
set/a
表达式并将它们很好地隔开-我发现这有助于提高可读性.
As an aside, you'll probably notice I have a penchant for quoting my
set /a
expressions and spacing them nicely - I find this aids readability.
这将解决一些特定的问题,但是,老实说,您最好制作一个泛型函数,该函数可以对事件发生的可能性给出肯定/否定答案.这样,您可以在需要的任何地方重复使用它.
That will fix some specific problems but, to be honest, you're probably better off making a generic function that can give you a yes/no answer for some probability of an event happening. That way, you can reuse it anywhere you need it.
您可以在完整程序中使用如下所示的功能,例如 chance
,以根据百分比确定是否应该发生某些事情:
You can use a function like chance
, shown below in a complete program, to decide whether something should happen based on a percentage:
@echo off
goto :main
:chance
setlocal enableextensions enabledelayedexpansion
set retcode=1==0
set /a "value = %random% %% 100"
rem echo %value% rem uncomment for debugging
if %value% lss %2 set retcode=1==1
endlocal && set %1=%retcode%
goto :eof
:main
call :chance result 50
echo %result%
应同时使用变量名称和要使用的百分比级别来调用该结果.例如,如果您想基于5%的机会设置变量 hasdied
,则可以使用以下方式调用它:
It should be called with both a variable name to put the result into, and the percentage level you want to use. For example, if you wanted to set a variable hasdied
based on a 5% chance, you would call it with:
call :chance hasdied 5
if %hasdied% goto :handlebeingdead
该函数包含许多可能需要解释的功能:
The function contains a number of features which probably bear explanation:
-
setlocal
命令确保没有变量转义此功能的范围(但请参见下文),对于正确封装很有用.
The
setlocal
command ensures that no variables escape the scope of this function (but see below), useful for proper encapsulation.
value
变量被设置为介于 0
和 99
之间的某个随机值.它分布不完全,因为%random%
将为您提供最大为 32767
的值,因此会稍微偏向小于 68
的数字.所说的偏斜可能不足以引起您的关注.
The value
variable is set to some random value between 0
and 99
inclusive. It's not perfectly distributed since %random%
will give you a value up to 32767
so will be slightly skewed toward numbers less than 68
. Said skew is probably not enough to concern yourself with.
然后将该值与您提供的阈值(第二个参数)进行比较,以确定返回值true或false.
This value is then compared with the threshold you provided (the second argument) to decide the return value true or false.
返回值相当隐蔽,因为它为您提供了 expression ,您可以将其放入 if
语句中,而无需进行显式比较,例如:
如果%hasdied%== 1
通过直接返回这样的相等比较,则可以使用返回值,就好像它是布尔值一样.
The return value is rather sneaky in that it gives you an expression that you can put into an if
statement without having to do an explicit comparison like:if %hasdied%==1
By returning such an equality comparison directly, you can just use the return value as if it was boolean.
然后, endlocal
会清除此函数中所做的所有变量更改,包括返回代码的 .但是,这一行的替换发生在任何一个执行之前 的事实,这意味着该行的 set
部分将已经具有正确的 retcode值
在 endlocal
清理之前替换.这是一种使特定变量转义"的方法.以 setlocal/endlocal
为边界的范围.因此, retcode
值放置在您提供的名称作为第一个参数的参数中.
The endlocal
then cleans up any variable changes that have been made in this function, including the return code. However, the fact that the substitutions on this line take place before any of it is executed means that the set
part of it will already have the correct value of retcode
substituted before the endlocal
cleans it up. This is a way to have specific variables "escape" the scope bounded by setlocal/endlocal
. The retcode
value is therefor placed in the parameter whose name you provided as the first argument.
该命令的 set%1 =
部分是一种允许您指定哪些变量应在调用本身中接收值的方法,类似于 myvar = function()
.这样一来,您就不必为每个函数分配一个硬编码的变量名,然后在调用后将其分配给另一个变量.
The set %1=
part of that command is a way to allow you to specify what variable should receive the value in the call itself, akin to myvar = function()
. That stops you from having to allocate a hard-coded variable name to each function and then assign it to another variable after the call.
当然, goto:eof
只是一条 return
指令.
这篇关于如何使随机机会“起作用"?分批的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!