如何使随机机会“起作用"?分批 [英] How to make a random chance "function" in Batch

查看:43
本文介绍了如何使随机机会“起作用"?分批的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在做一个小型的小游戏,我希望有一个随机的机会来获得某些物品(例如,如果随机数大于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%
)

经历他们:

  • if 语句无效,& 是如果先前的命令有效,则执行下一个命令".连词,而不是一般的与"操作员.要执行的操作是:
    如果%chance%gtr 10,如果%chance%lss 30 .
    请参见

  • 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 do and and or in cmd 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆