#include <cstdlib>
#include <iostream>
#include <cmath>
#include <time.h>
using namespace std;
static const float CONTROL_WR = 0.8f;
static const float AGGRO_WR = 0.65f;
static const unsigned STARS = 5 * 5 + 5 * 4 + 5 * 3; //From rank 20: 5 ranks with 3 stars, 5 ranks with 4, 5 with 5
static const unsigned REPEATS = 10000; //Higher is slower and more accurate estimate of expected number of games needed
//Flip a coin that lands on "heads" with probability p
bool trial(float p)
{
float r = (float)((float)rand() / (float)RAND_MAX);
return r < p;
}
class RunningStat //See: http://w...content-available-to-author-only...k.com/blog/standard_deviation/
{
public:
RunningStat() : m_n(0) {}
void Clear()
{
m_n = 0;
}
void Push(float x)
{
m_n++;
// See Knuth TAOCP vol 2, 3rd edition, page 232
if (m_n == 1)
{
m_oldM = m_newM = x;
m_oldS = 0.0;
}
else
{
m_newM = m_oldM + (x - m_oldM)/m_n;
m_newS = m_oldS + (x - m_oldM)*(x - m_newM);
// set up for next iteration
m_oldM = m_newM;
m_oldS = m_newS;
}
}
int NumDataValues() const
{
return m_n;
}
float Mean() const
{
return (m_n > 0) ? m_newM : 0.0;
}
float Variance() const
{
return ( (m_n > 1) ? m_newS/(m_n - 1) : 0.0 );
}
float StandardDeviation() const
{
return sqrt( Variance() );
}
private:
int m_n;
float m_oldM, m_newM, m_oldS, m_newS;
};
int main(int argc, char* argv[])
{
//Initialize a random seed.
//Can consider using something better than the standard built-in rand(). Google: Mersenne Twister
srand(time(NULL));
RunningStat stat;
float wr = AGGRO_WR;
for (unsigned iteration = 0; iteration < REPEATS; ++iteration)
{
unsigned cur_stars = 0; //This is unsigned and zero-based because we're simulating from rank 20. If you want to start at 10 or something, change to signed and take into account negatives
unsigned streak = 0; //Streak length
unsigned games = 0; //How many games played
while (cur_stars < STARS)
{
++games;
if (trial(wr)) //if we won the game
{
++cur_stars;
++streak;
}
else
{
if (cur_stars > 0)
{
--cur_stars;
}
streak = 0;
}
if (streak > 2)
{
++cur_stars;
}
}
stat.Push((float)games);
}
cout << "After " << REPEATS << " attempts, it took an average of " << stat.Mean() << " games at a win-rate of " << wr << " with a standard deviation of " << stat.StandardDeviation() << endl;
//std::cout << std::endl << "Hurray! It took " << games << " games at a win-rate of " << wr << " to reach Rank 5" << std::endl;
return 0;
}