调用IF语句|批量

时间:2016-01-10 01:19:09

标签: batch-file

错误代码:

If was unexpected at this time

代码设置每个玩家的统计数据然后它调用函数来根据统计数据和其他变量确定损失数量

我想要做的是调用一个带有两个IF语句的函数 示例:

@echo off
set /a level=5
set /a opponentLevel=5
set /a movePower=50
set moveType=physical
goto player

:damageCalculator
if %moveType%==physical (
    pause
    set /a damage=(((( 2 * %level% / 5 + 2) * %attackStat% * %movePower% / %opponentDefenceStat%) / 50) + 2)
    set /a opponentHealth-=%damage%
) else if %moveType%==special (
    set /a damage=(((( 2 * %level% / 5 + 2) * %spAttackStat% * %movePower% / %opponentSpDefenceStat%) / 50) + 2)
    set /a opponentHealth-=%damage%
)
goto :eof

:player
set type=fire
set/a health=19
set/a attackStat=10
set/a defenceStat=10
set/a spAttackStat=11
set/a spDefenceStat=10
set/a speedStat=12

:opponent
set /a opponentHealth=18
set /a opponentAttackStat=10
set /a opponentDefenceStat=9
set /a opponentSpAttackStat=8
set /a opponentSpDefenceStat=9
set /a opponentSpeedStat=13

:attack
pause
cls
call :damageCalculator
echo It did %damage% Damage!!
pause>nul

这只是批次无法做到的事情之一吗?

1 个答案:

答案 0 :(得分:3)

按编辑问题更新

您的脚本有一些小问题。首先,我要指出,rem @echo off在尝试追踪问题原因时通常会有所帮助。在这种情况下这样做表明导致错误的行是您的第一行set /a

您的if语句失败的原因是因为数学中的括号被视为代码块的结尾。一旦遇到...5 + 2)的右括号,批处理解释器会将其视为if语句的结尾,因此当行中有更多内容时会感到困惑。您需要引用set /a语句来防止这种情况发生。

set /a "damage=(((( 2 * level / 5 + 2) * attackStat * movePower / opponentDefenceStat) / 50) + 2)"

看看我在那里set /a "variable=value"怎么做了?你也可以用插入符号来逃避右括号 - 例如^),但我认为引用"var=value"更容易阅读。引号将内容保留在命令的上下文中。他们基本上说,“这是一个单一的标记。它是set命令的一个独特部分,而不是整个代码块。”作为奖励,您还可以看到在%命令中检索变量值不需要set /a符号。干净,是吗?

你还有另外一个问题。由于您在检索时在同一个括号代码块中设置了%damage%变量,因此%damage%将过早地进行评估。您可以setlocal enabledelayedexpansion并将其检索为!damage!,这肯定会奏效。但是有一个更简单的解决方案。把它放在if语句之外。无论移动类型是物理的还是特殊的,你都在做set /a opponentHealth-=damage,无论如何,对吧?

:damageCalculator
if "%moveType%"=="physical" (
    set /a "damage=(((( 2 * level / 5 + 2) * attackStat * movePower / opponentDefenceStat) / 50) + 2)"
) else if "%moveType%"=="special" (
    set /a "damage=(((( 2 * level / 5 + 2) * spAttackStat * movePower / opponentSpDefenceStat) / 50) + 2)"
)
set /a opponentHealth-=damage
goto :eof

但是,您仍然应该在setlocal下方添加@echo off,以防止在您的环境中使用在此脚本范围之外没有任何意义的变量。

这是另一个提示。您可以在一行set /a行中合并多个语句。

在:

set /a level=5
set /a opponentLevel=5
set /a movePower=50
set "moveType=physical"

后:

set /a level=5, opponentLevel=5, movePower=50
set "moveType=physical"

原始答案

将您的第二个if更改为else if或在其前面添加回车符(在前面的括号之后)。另外,将您的goto :EOF移到右括号后的下一行。

对此的解释是cmd解释器将括号代码块视为单个命令。所以在本质上,

if [true condition] (
    action
) second command

正在评估为

if [true condition] (action) second command

导致错误,因为第一个命令(if)和第二个命令之间没有换行符或其他分隔符。以下是有效复合命令的示例:

@echo off & setlocal

复合命令需要:

  • 无条件AND(& - 右侧始终在左侧后执行)
    • 示例:endlocal & goto :EOF
  • 逻辑AND(&& - 右侧仅在前一个命令退出零时执行)
    • 示例:find /i "text" "textfile.txt" >NUL && echo Text was found
  • pipe(| - 使得右侧的命令对左侧命令生成的输出执行某些操作
    • 示例:dir /s /b | more
  • 逻辑OR(|| - 仅当前一个命令退出非零时才执行右侧
    • 示例:tasklist | find /i "iexplore.exe" >NUL || echo Internet Explorer not running

...或if语句else

if condition 1 (
    action 1
) else if condition 2 (
    action 2
) else (
    action 3
)

或者,如果您想检查两个条件是否成立:

if %var% leq 10 if %var% geq 5 (
    echo Variable is between 5 and 10.
)

当然,您不必使用复合语句。函数不能有多个if语句不能复合。

:fn <str>
if "%~1"=="fish" (echo Bloop.)
if "%~1"=="cats" (echo Meow.)
if "%~1"=="dogs" (echo Grrrr.)
goto :EOF

......完全有效。