kingkingyyk3
Visitor (Welcome to the Jungle, Baby!)
- Reaction score
- 216
JASS:
library GetChance
/*
Get Chance v1.0.4
by kingking
GetRandomInt/Real in warcraft 3 are commonly used to get the chance to trigger something, like effects.
However, they are not precise.
They will return close values sometimes.
This has caused the chance is not so precise.
This library is aimed to solve that.
Usage :
Chance.define(real probabilityToProc, integer weightage) -> Chance
vars.getChance() -> boolean
vars.reset() = Reset the allocated chance.
set vars.probability = <probability>
set vars.weightage = <weightage>
It is a good idea for attaching this to units because allocated chances to return true are different.
For best precision, probabilityToProc * weightage should be whole number.
Weightage is the number for checking each loop.
If you put 10 for it, then each 10 times of .getChance will reset the chance.
*/
struct Chance
private integer countdown
private integer weight
private integer procCount
private real probably
private integer left
static method define takes real probabilityToProc, integer weightage returns thistype
local thistype this = thistype.allocate()
debug if weightage <= 0 then
debug call BJDebugMsg("GetChance error! Invalid Weight found!")
debug return 0
debug endif
set .probably = probabilityToProc
set .procCount = R2I(probabilityToProc * weightage)
set .weight = weightage
return this
endmethod
method reset takes nothing returns nothing
set .countdown = .weight
set .left = .procCount
endmethod
method operator probability= takes real r returns nothing
debug if r < 0. and r > 1. then
debug call BJDebugMsg("GetChance error! Invalid Probability found!")
debug return
debug endif
set .probably = r
set .procCount = R2I(r * .weight)
endmethod
method operator weightage= takes integer i returns nothing
debug if i <= 0 then
debug call BJDebugMsg("GetChance error! Invalid Weight found!")
debug return
debug endif
set .procCount = R2I(.probably * i)
set .weight = i
endmethod
method getChance takes nothing returns boolean
if .countdown == 0 then
call .reset()
endif
if .probably == 1. then
return true
elseif .probably == 0. then
return false
endif
set .countdown = .countdown - 1
if .left > .countdown then
return true
endif
if .left > 0 and GetRandomReal(0.,1.) <= .probably then
set .left = .left - 1
return true
endif
return false
endmethod
endstruct
endlibrary
UPDATES :
v1.0.0 : Initial Release.
v1.0.1 : Allow users to change probability and weightage freely.
v1.0.2 : Switched algorithm to array stack.
v1.0.3 : Switched algorithm to linked list.
v1.0.4 : Switched algorithm. Does not require preloading chance now and lot's faster(271% faster than v1.0.0).
v1.0.5 : Polished current algorithm by a small chance detecting, thus the distribution is better.