The answer below is a rather long and boring explanation for those who want to know the details. If you just want a balanced program (where you have 3, 4, 5, ... options all of them with the same chance of happening) and do not want the details, check the second post below.I've been exploring the use of 'if rand(%)' to make
the actions of mobs less predictable. For example this
prog on a watch wizard:
Is there any reason this might be a bad idea? If I hadCode: Select all
>fight_prog 100~ if rand(10) cast 'stone skin' else if rand(50) cast 'magic missile' $n else if rand(10) cast 'shield' else if rand(10) cast 'armor' else if rand(10) cast 'bulls strength' else if rand(10) cast 'fire shield' else cast 'shocking grasp' $n endif endif endif endif endif endif ~
the patience, I could make mobs do some neat stuff
with code like this.
All classes come with a standard fight_prog I think. But if you really want your mob to be efficient and if you don't want it to just do some standard actions / cast some standard spells, I think it's a very good idea to add a fight_prog with some random actions.
A note about imbricated rand tests, that is, rand tests in other rand tests... you have to remember that each "rand" test is like a choice with 2 options: the "if" part and the "else" part. I saw in your program above that you have rand(..) tests with numbers summing up to 100%. This program above won't make the mob cast "magic missile" with 50% chance, or "fire shield" with 10% chance though... it's a bit more tricky.
I'll use the (smaller) program below to explain
Code: Select all
if rand(40)
cast 'magic missile'
else
if rand(50)
cast 'lightning bolt'
else
cast 'shocking grasp'
endif
endif
Code: Select all
/-- 40% -- magic missile
|
------|
| /-- 50% -- lightning bolt
| |
\-- 60% -- first else part ----|
|
\-- 50% -- shocking grasp
- there is 40% chance that the mob casts 'magic missile'
- and 60% chance that the mob does something else.
In these 60%, there are 2 options:
- 50% chance to cast lightning bolt
- 50% chance to cast shocking grasp
Code: Select all
/---------------------|----------------------------\
| 40 % | 60 % |
\---------------------|----------------------------/
magic missile /--------------|-------------\
| 50 % | 50 % |
\--------------|-------------/
lightning bolt shocking grasp
- 40% chance for magic missile
- 30% chance for lightning bolt (50% of 60%)
- 30% chance for shocking grasp (the last 50% of 60%)
In your longer program above, you would have
- 10% for stone skin (90% left for the else part)
- 45% (50% of 90%) for magic missile (45% left for the second else part)
- 4.5% (10% of 45%) for shield (40.5% left for the third else part)
- 4.05% (10% of 40.5%) for armor (36.45% left for the fourth else part)
- 3.645% (10% of 36.45%) for bulls strength (32.803% left for the fifth else part)
- 3.2803% (10% of 32.803%) for fire shield (29.5247% left for last else part)
- 29.5247% for shocking grasp
All that sums up to "the numbers in rand() tests can be tricky".
For example, if you want a rand_prog with 4 options that all have the same chance of happening, you can't use
Code: Select all
if rand(25)
option 1
else
if rand(25)
option 2
else
if rand(25)
option 3
else
option 4
endif
endif
endif
- 25% for option 1 (75% left)
- 18.75% (25% of 75%) for option 2 (56.25% left)
- 14.0625% (25% of 56.25%) for option 3 (42.1875% left)
- 42.1875% for option 4
So, option 4 is very likely to be be chosen in this case. What you want is 25% for each of those options.
- So, rand(25) for option 1, and there's 75% left
- You want 25%, that is, 1/3rd of what is left, so you'll use rand(33) for option 2, then there's 50% left
- You want 25%, that is, 1/2 of what is left, so you'll use rand(50) for option 3
Code: Select all
if rand(25)
option 1
else
if rand(33)
option 2
else
if rand(50)
option 3
else
option 4
endif
endif
endif