I am trying to create a tennis tournament simulator. There are 128 players in the tournament, and 32 seeds. I have a vector filled with 'Player' objects named 'Players'. Each 'Player' object has three member variables, Strength, Ranking, and ATPPoints. When the vector 'Players' is first declared, the default constructor for each 'Player' object is used, which initialises each of the 'Player' objects to zero. I then generate a Strength value in the range of 0-10 for each of these 'Player' objects, and sort them descendingly according to their strength.
I now want to create the draw for a tournament. I declare a vector 'Draw' with 128 'slots'. Each slot initially contains a blank 'Player' object, with its member variables set to 0. I first place the top 32 players throughout the draw such that they do not meet until later rounds as they would be in real life. For the remaining players, I position them in the draw by generating a random number between 0 and 127. Some of the slots 0-127 are occupied by seeded Players. These seeded Players have non zero Strength and Rank values, so to avoid overwriting these slots, I check the Strength value of the 'Player' object in the slot in question. A return value of 0 would indicate an empty slot.
At the beginning of the function, I output the Strength and Rank values of the 'Player' objects already in the draw. This outputs correctly.
for (Player& p : Draw)
{// outputz the draw in it's current state, with the already placed seeds as expected.
cout << p.GetRanking() << " " << p.GetStrength() << endl;
}
For reasons I don't understand though, later in the function when I read the values as below, 0 is returned regardless of which slot is selected.
double CurrentSlotStrength = Draw.at(Slot).GetStrength();
double CurrentSlotRank = Draw.at(Slot).GetRanking();
I have included the rest of my code below. The function is question is 'SelectRandomSlot'. Please could someone explain why I am seeing different values.
int SelectRandomSlot(vector<Player> &Draw)
{
for (Player& p : Draw)
{// outputz the draw in it's current state, with the already placed seeds as expected.
cout << p.GetRanking() << " " << p.GetStrength() << endl;
}
//minstd_rand is a simple multiplicative congruential pseudo-random number generator
//minstd_rand Gen;
mt19937 Gen; // Now using mersenne_twister_engine
int LowerLimit = 0;
int UpperLimit = Draw.size()-1;
uniform_int_distribution<> Dist(LowerLimit, UpperLimit);
bool Found = false;
int Slot = 0;
while(!Found)
{
Slot = Dist(Gen);// generates a number pseudo randomly between 0 and 127.
double CurrentSlotStrength = Draw.at(Slot).GetStrength();
double CurrentSlotRank = Draw.at(Slot).GetRanking();
// Draw is initialized with blank instantiations of Player, with the member variables
// of Strength, Rank, and ATPPoints set to 0.0 (double), 0(int) and 0(int) respectively.
// Since the seeds have already been placed, the Strength and Ranking values of these
// should not equal 0. 0 indicates an empty Player.
if(CurrentSlotStrength==0.0)
{
Found = true;
}
}
return(Slot);
}
void CreateTournament(vector<Player> &Players, vector<Player> &Draw)
{
//-- Place the appropriate number of seeds in the draw.
int DrawPosition;
int NoOfParticipants = Draw.size();
int NoOfSeeds = NoOfParticipants/4;
for(int i=0; i<NoOfSeeds; i++)
{
DrawPosition = SeedPlayer(Players.at(i).GetRanking(),NoOfParticipants);
Draw.at(DrawPosition) = Players.at(i); // Assumes Players have been sorted descendingly according to rank...
// ...This happens initially, but must be repeated after each tournament.
}
int Remaining = NoOfParticipants-NoOfSeeds;
for(int j=NoOfSeeds; j<NoOfSeeds+Remaining; j++)
{
DrawPosition = SelectRandomSlot(Draw);
Draw.at(DrawPosition) = Players.at(j);
}
}
int main()
{
vector<Player> Players(1000);
// Player strengths are generated from a normal distribution with a mean of 5 and standard deviation of 2, with values outside the range of 0-10 discarded.
GeneratePlayerStrengths(Players);
// end() will return a iterator(pointer) to one past the last element in the array we pass it.
// Remember the sort function sorts up to but not including what we pass in as the second parameter.
sort(Players.begin(), Players.end(), SortMethod); // sort descending order
int i=1;
for (Player& a : Players)
{
// initialise the rank of the players according to their strength
a.SetRanking(i++);
}
vector<Player> Draw(128);
CreateTournament(Players, Draw);
//TODO: Create list of tournaments with their participants and wildcards. Then loop through to create all of these tournaments.
cin.ignore(); // keep the command window open for debugging purposes.
return 0;
}
class Player
{
public:
Player()
{// initialize to 0.0 to indicate 'empty'
Strength = 0.0;Ranking = 0.0;ATPPoints = 0.0;}
Player(double val){Strength = val;Ranking = 0.0;ATPPoints = 0.0;}
virtual ~Player() {}
double GetStrength() const{return Strength;}
void SetStrength(double val){Strength = val;}
int GetRanking() const{return Ranking;}
void SetRanking(int val){Ranking = val;}
int GetATPPoints() const {return ATPPoints;}
void SetATPPoints(int val){ATPPoints = val;}
protected:
private:
double Strength; //!< Member variable "Strength"
int Ranking; //!< Member variable "Ranking"
int ATPPoints; //!< Member variable "ATPPoints"
};