I was doing some random simulation stuff here at work and doing some smoothing similar to what is done with the 90% rule. If I recall how you are doing it, I think there is a major bug there.
My understanding is you are doing the battle and then looking at the result. If the result is in the lower (0-9) or upper (91-100) range you are re-rolling the entire battle but you aren't tracking the original winner. So that a re-roll could switch the winner. Allowing that switch of winners is where I discovered the bug is.
For example lets take an 88% battle for the attacker. He wins 88% of the time and the defender wins 12%. I wrote a simple coding example of:
- Code: Select all
int attacker = 0; // Total attacker wins
int defender = 0; // Total defender wins
int total=10000; // Total simulation
int attWin = 88; // Attacker win %
srand((int)time(NULL));
for (int i=0; i<total; i++)
{
int result = (rand()%100)+1; // Battle result: 1-100
if (result <= attWin )
{
attacker++;
}
else
{
defender++;
}
}
cout << "attacker " << attacker << endl;
cout << "defender " << defender << endl;
cout << "percentage " << (float)attacker/total*100 << endl;
Running this code gives a winning % of 88% for the attacker as expected.
Now I added the smoothing code. I just re-roll anything <10 or >90.
- Code: Select all
int attacker = 0; // Total attacker wins
int defender = 0; // Total defender wins
int total=10000; // Total simulation
int attWin = 88; // Attacker win %
srand((int)time(NULL));
for (int i=0; i<total; i++)
{
bool valid = false;
while (!valid)
{
int result = (rand()%100)+1; // Battle result: 1-100
if (result > 10 && result <= 90) // Check battle is in the middle 80%
{
if (result <= attWin )
{
attacker++;
}
else
{
defender++;
}
valid = true;
}
}
}
cout << "attacker " << attacker << endl;
cout << "defender " << defender << endl;
cout << "percentage " << (float)attacker/total*100 << endl;
Now the attacker win % jumps to 97.5% instead of being at 88% where it should be.
The reason is because if you just re-roll and allow the winner to be switched then the true valid outcomes are 78/80 for the attacker and 2/80 for the defender and 78/80 = 97.5%.
Since re-rolling is the easiest for you code wise, you'll need to track the winner and re-roll until you get a valid result AND the original winner.
KGB