This morning I thought of an algorithm that does just that, it returns True or False with a certain percent chance of success.
I've started the theory(in my head...) like so:
- we need a chance resolution(in this case 5%)
- we need to have an array of boolean with the number of elements equal to 100 divided by resolution(5)
- initialize the array of chances to false
- calculate how many 5% chances are there(if you give 20% chance, then we have to set to True 4 elements in ChanceArray
- for each 5% chance set to True a element in ChanceArray that is NOT already set to true, starting at a random index in the array
- pick a random element from the array and return it's state(True or False) as the result of the chance
Here it is, my implementation:
(add "Math" to uses clause)
function CheckSuccess(const PercentChance: Integer): Boolean; var // 5% resolution // can give chances like 10%, 50% or 15%, 55%, 35%, etc. ChanceArray: array[0..19] of Boolean; ChanceCount: Integer; ChanceIndex: Integer; Index: Integer; procedure AddChance; begin ChanceIndex := RandomRange(Low(ChanceArray), High(ChanceArray)); while ChanceArray[ChanceIndex] do begin Inc(ChanceIndex); if ChanceIndex > High(ChanceArray) then ChanceIndex := Low(ChanceArray); end; // while ChanceArray[ChanceIndex] do begin ChanceArray[ChanceIndex] := True; end; // procedure AddChance; begin // you should probably call this once per application startup Randomize; // initialize chance array to false for Index := Low(ChanceArray) to High(ChanceArray) do ChanceArray[Index] := False; // how many 5% chances we got? if PercentChance > 100 then ChanceCount := 20 else ChanceCount := (PercentChance div 5); // 5% resolution for Index := 1 to ChanceCount do AddChance; ChanceIndex := RandomRange(Low(ChanceArray), High(ChanceArray)); Result := ChanceArray[ChanceIndex]; end;Usage:
(we give the player a 25% chance of success – you can increase or decrease chance but replacing 25 with another value)
P.S. Please drop me a comment with how would you implement a similar algorithm.