• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Random Chances, Integer

Status
Not open for further replies.
Level 4
Joined
Apr 15, 2016
Messages
61
  • The Merchant Bag
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to The Merchant Bag
    • Actions
      • Set MerchantBagChance[1] = (Random integer number between 61 and 100)
      • Set MerchantBagChance[2] = (Random integer number between 31 and 60)
      • Set MerchantBagChance[3] = (Random integer number between 11 and 30)
      • Set MerchantBagChance[4] = (Random integer number between 1 and 10)
      • Set MerchantBagItem[MerchantBagChance[1]] = Flash Bomb
      • Set MerchantBagItem[MerchantBagChance[2]] = Tracker
      • Set MerchantBagItem[MerchantBagChance[3]] = Shock Trap
      • Set MerchantBagItem[MerchantBagChance[4]] = Chaos Bomb
      • Hero - Create MerchantBagItem[MerchantBagChance(Random integer number between 1 and 100)] and give it to (Casting unit)
Did I do right ? Random chance for coming random itens ? Like: 10% to come the Chaos Bomb, 20% for the Trap,etc,etc. ?
 
Level 37
Joined
Jul 22, 2015
Messages
3,485
You only choose one integer between the parameters, where it should be that an item represents all of them.

Imagine these numbers are chosen:
  • MerchantBagChance[1] = 70
  • MerchantBagChance[2] = 35
  • MerchantBagChance[3] = 21
  • MerchantBagChance[4] = 1
    ----------------------------------
  • MerchantBagItem[70] = Flash Bomb
  • MerchantBagItem[35] = Tracker
  • MerchantBagItem[21] = Shock Trap
  • MerchantBagItem[1] = Chaos Bomb

  • Hero - Create MerchantBagItem[MerchantBagChance(Random integer number between 1 and 100)] and give it to (Casting unit)
^Imagine the random integer chosen is 50. MerchantBagItem[50] doesn't exist because only 70, 35, 21, and 1 were chosen at the start of the ability.


EDIT: If you wanted it so that the caster only got one of the items per cast, I would do something like this:

  • Map Init
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set MerchantBagItem[1] = Flash Bomb
      • Set MinChance[1] = 1
      • Set MaxChance[1] = 10
      • -------- --------
      • Set MerchantBagItem[2] = Tracker
      • Set MinChance[2] = 11
      • Set MaxChance[2] = 30
      • -------- --------
      • Set MerchantBagItem[3] = Shock Trap
      • Set MinChance[3] = 31
      • Set MaxChance[3] = 60
      • -------- --------
      • Set MerchantBagItem[4] = Chaos Bomb
      • Set MinChance[4] = 61
      • Set MaxChance[4] = 100
      • -------- --------
      • Set MaxItems = 4
  • The Merchant Bag
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to The Merchant Bag
    • Actions
      • Set Caster = (Triggering unit)
      • Set RandomInt = (Random integer number between 1 and 100)
      • -------- --------
      • For each (Integer LoopInt) from 1 to MaxItems, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • RandomInt Greater than or equal to MinChance[LoopInt]
              • RandomInt Less than or equal to MaxChance[LoopInt]
            • Then - Actions
              • Hero - Create MerchantBagItem[LoopInt] and give it to Caster
              • Custom script: exitwhen true
            • Else - Actions

I'm not the best when it comes to sorting algorithms, so I wouldn't be shocked if there were a more efficient way of doing it. Also, I put the items and their chances in a map init trigger because I found no sense in caching the data on every cast.
 
Last edited:
Level 11
Joined
Jul 25, 2014
Messages
490
  • Your wanted trigger
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • ((Triggering unit) is A structure) Equal to True
    • Actions
      • Set RandomInteger = (Random integer number between 1 and 100)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • RandomInteger Greater than 0
          • RandomInteger Less than or equal to 50
        • Then - Actions
          • -------- Give item 1 to your unit --------
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • RandomInteger Greater than 50
          • RandomInteger Less than or equal to 70
        • Then - Actions
          • -------- Give item 2 to your unit --------
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • RandomInteger Greater than 70
          • RandomInteger Less than or equal to 90
        • Then - Actions
          • -------- Give item 3 to your unit --------
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • RandomInteger Greater than 90
          • RandomInteger Less than or equal to 100
        • Then - Actions
          • -------- Give item 4 to your unit --------
        • Else - Actions
That's how I would be going for it. But yeah, KILLCIDE's way is probably way more efficient since it doesnt require you to use multiple if blocks.
 

Chaosy

Tutorial Reviewer
Level 40
Joined
Jun 9, 2011
Messages
13,183
It's less code but it's actually more inefficient if anything since it uses a few variables behind the scenes that you don't use.
With other words the number of function calls should be the same.

Also, I think you both are doing about this the wrong way.

Instead of checking if it's larger than x and less than y (example: 10, 23)

Then why not check if it's less than 13 instead? The % chance does not change but it's way more logical and easier to understand. And a bit more efficient if you care about that.
 
Level 37
Joined
Jul 22, 2015
Messages
3,485
It's less code but it's actually more inefficient if anything since it uses a few variables behind the scenes that you don't use.
With other words the number of function calls should be the same.
In theory, they do have the same amount of function calls, but the loop will end and stop comparing integers when it has found where it belongs thanks to the exitwhen true operator. Without it, they would be exactly the same, but just less code as you said.
  • With exitwhen true
    • Random integer is 9
    • 1st loop iteration (1-10) -> found it!
    • Loop ends
  • Without
    • Random intger is 9
    • 1st loop iteration (1-10) -> found it!
    • 2nd loop iteration (11-30) -> not true
    • 3rd loop iteration (31-60) -> not true
    • 4th loop iteration (61-100) -> not true

Also, I think you both are doing about this the wrong way.

Instead of checking if it's larger than x and less than y (example: 10, 23)

Then why not check if it's less than 13 instead? The % chance does not change but it's way more logical and easier to understand. And a bit more efficient if you care about that.
I'm not so sure about that. If you only compared if it was less than one of the numbers, there can be multiple loop that return true. Example:
  • Random Integer is 12
    • 1st loop iteration -> not less than 10; do not create item
    • 2nd loop iteration -> less than 30; create item
    • 3rd loop iteration -> less than 60; create item
    • 4th loop iteration -> less than 100; create item

I also could be misunderstanding you.
 

Chaosy

Tutorial Reviewer
Level 40
Joined
Jun 9, 2011
Messages
13,183
He could nest the if blocks to solve that though.

_________

Due the exitwhen that'll never happen.

Also, if the integer is 12:
1,10 = 9
11,30 = 19
31,61 = 30
61,100 = 39

if 12 < 9 = false
if 12 < 19 = true
exitwhen
if 12 < 30 = true (if exitwhen does not exist)
if 12 < 39 = true (if exitwhen does not exist)

edit: made a math mistake. Fixed.
 
Level 4
Joined
Apr 15, 2016
Messages
61
Get random item when the ability is cast. Merchant Bag means the bag, bag with itens. Only one item per cast.

10% for item x
20% for item y
30% for item z
40% for item a
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,198
An item pool should have no problem doing that. Needs JASS though...

JASS:
local itempool pool = CreateItemPool()
call ItemPoolAddItemType(pool, 'I000', 0.1)
call ItemPoolAddItemType(pool, 'I001', 0.2)
call ItemPoolAddItemType(pool, 'I002', 0.3)
call ItemPoolAddItemType(pool, 'I003', 0.4)
call PlaceRandomItem(pool, 0, 0)
call DestroyItemPool(pool)
set pool = null

Other approach is a list of weight + item type pairs. Count the total weight, possibly adding some constant to it to represent no item spawn. Then roll a random number between 0 and total weight. Iterate through the list comparing the rolled number if it is less than the spawn eight. If it is less than the spawn weight then spawn the item and break the loop, otherwise subtract spawn weight from the rolled number and advance to the next element. It works by fragmenting the rolled number into ranges for each list entry and since the probability distribution is even throughout the rolled number it will have the correct drop chances. This has a complexity of O(n).

A more scale-able approach would use a binary search tree for the rolled number fragmentation part. This would allow the result to be computed with a better complexity of O(log2(n)). This has other overheads so for small lists it will likely be slower.
 
Level 4
Joined
Apr 15, 2016
Messages
61
The problem is that Jass doesn't work in my map (not even using the custom editor). My map won't never start if a GRAIN of jass step on it.

Or maybe that was because the map was more than 8 mb ?

Anyway, is there a GUI for this system ?

Why does Killcide method do not work or is inefficient ?
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,198
The problem is that Jass doesn't work in my map (not even using the custom editor). My map won't never start if a GRAIN of jass step on it.
That only happens if you have a syntax error.

Anyway, is there a GUI for this system ?
Unfortunately not because WC3 GUI is abysmal.

Why does Killcide method do not work or is inefficient ?
His approach is more difficult to maintain as you need to keep track of 2 weight variables and potentially modify all entries for consistency when altering 1 item. The suggestion I gave is mechanically the same except only 1 weight variable needs to be modified and entries do not depend on other entries for correct operation.
 
Status
Not open for further replies.
Top