Kšištof Bortkevič
Kšištof Bortkevič

Reputation: 23

IF statement using delayed expansion?

I have a piece of code that looks something like this(Delayed Expansion is enabled):

    for /l %%y in (1,1,%variable%) do (
     set /a rand=!random! * 100 / 32768 + 1
     echo !rand!
     if !rand! GEQ %chance% (
      set /a var=%var%+%varx%
     )
    )

the echo !rand! part displays the number, but if !rand! GEQ %chance% just sees !rand! as a string, not as its value. So even if !rand! is bigger than %chance% it still skips the command.

The weird part is no matter how many times !rand! is greater than %chance% at the end of the loop var increases by %varx% only once. What should be done here so that the IF statement sees !rand!'s value?

Upvotes: 2

Views: 882

Answers (1)

dbenham
dbenham

Reputation: 130819

As Stephan says in his comment - you know enough to use delayed expansion within a loop when expanding random and rand. Why aren't you using it with var? The value of %var% is constant within your loop. You need !var! to see the dynamic value that exists at each iteration.

for /l %%y in (1,1,%variable%) do (
  set /a rand=!random! * 100 / 32768 + 1
  echo !rand!
  if !rand! GEQ %chance% (
    set /a var=!var!+%varx%
  )
)

But there is another solution. SET /A knows how to expand variables on its own, without % or !. Note that !random! is still needed because random is not a true environment variable.

for /l %%y in (1,1,%variable%) do (
  set /a rand=!random! * 100 / 32768 + 1
  echo !rand!
  if !rand! GEQ %chance% (
    set /a var=var+varx
  )
)

Or you could use the += operator

for /l %%y in (1,1,%variable%) do (
  set /a rand=!random! * 100 / 32768 + 1
  echo !rand!
  if !rand! GEQ %chance% (
    set /a var+=varx
  )
)

If you want optimal performance, you could do all computations within one SET /A, without any need for IF. But this is pretty extreme, and not very readable:

for /l %%y in (1,1,%variable%) do (
  2>nul set /a "rand=!random!*100/32768+1, 1/(rand/chance), var+=varx"
  echo !rand!
)

var is only incremented If rand is greater than or equal to chance. If rand is less than chance, then you get a division by 0 error (hidden by the redirection of stderr), and SET /A does not proceed any further.

Upvotes: 4

Related Questions