Hello, I am to search through the gamers vector to find if the names match, say which index it is at and then insert but they are both different types and both private so i am having quite an issue. I am not to use custom loops(for,if,ect) and have to compare both but I am having a really hard time.
1 2 3 4 5 6 7 8 9 10 11
class Tournament
{
private:
vector<Games>Gamers;
int FindGamers(const std::string& name);
:
int FindGamers(const std::string& name)
{
don't know how to search through different types but know i have to
insert to put it back into vector.
}
Since FindGamers() is a method of Tournament, it has access to Tournament::Gamers. In other words, you don't have to worry about Gamers being private.
Please provide the definition of class Games. Also, explain what it means for a (string) name to match an instance of Games.
I am to search through the gamers vector to find if the names match, say which index it is at and then insert
I think you're saying that FindGamers returns the index of vector "Gamers" that matches the parameter "name". If "name" doesn't match any existing value in "Gamers" then it should insert a new value and return the index of that new value. Do I understand correctly?
@dhayden that is exactly it!
and @keskiverto. I cannot change the function provided, i can of course put in code into the function, but not change it in any way, that is what the instructions were, which is why I was having a problem which is also why i created a thread which i double checked with the professor. So adding Tournament::FindGamers(const std::string& name) will not work... which is why I've been having a problem because I cannot seem to be able to compare the Gamers with the name
I have to sift through the Gamers, find the similar names, if similar, show the index, if not, make a new gamer and insert it in gamer vector
In your latest code shouldn't FindOrInsertPlayer() be a member function of the Glicko class? I see this function defined in the class definition (line 39).
Now we are talking. The essentials (now that we can see what is and what is not):
1 2 3 4 5 6 7 8 9 10 11 12 13 14
class Player
{
public:
Player( const std::string& name = "", double r = INITIAL_RATING,
double rd = INITIAL_DIFFERENTIAL, double v = INITIAL_VOLATILITY );
std::string Name() const;
};
class Glicko
{
std::vector<Player> m_Players;
int FindOrInsertPlayer( const std::string& name );
};
From that we do see that you can create a Player from a string. For example:
1 2
std::string john = "Doe";
Player bob( john ); // public and legal
Furthermore, we can read the name of the Player.
1 2
Player mary_sue;
if ( mary_sue.Name() == john ) std::cout << "Hello Dolly!\n";
However, we cannot compare Player to string directly:
1 2
if ( mary_sue == john ) // error: no operator== for <Player> and <std::string>
std::cout << "Hello Dolly!\n";
// TODO Without writing a custom loop
What an asinine requirement. I appreciate your prof's desire to force you to use parts of the standard library, but in this case it just gets in the way.
Since FindOrInsertPlayer() is private, I think Professor Makework wants you to call it from LoadPlayers().
To avoid a custom loop, I used std::find_if(). find_if() requires that third argument that takes a single parameter: an iterator that points to an item. Since we want to compare that item's name to a string, I created a class called EqualName to store the string and handle the function call operator:
class EqualName
{
public:
EqualName(const std::string &s) : name(s) {}
std::string name;
booloperator()(const Player &p) {
return p.Name() == name;
}
};
int Glicko::FindOrInsertPlayer(const std::string& name)
{
// TODO Without writing a custom loop, Search the m_Players
// vector to find the desired name If the player is
// found, return the index for the element in the vector
// If the player is not found, create a new player,
// insert it at the end of the vector and return the
// index for the newly inserted item
EqualName pred(name);
std::vector<Player>::iterator iter;
iter = find_if(m_Players.begin(), m_Players.end(), pred);
if (iter == m_Players.end()) {
m_Players.emplace_back(name);
iter = m_Players.end()-1;
}
return iter - m_Players.begin();
}
To show why this is dumb, here's a simpler implementation. No auxilliary predicate class needed, no iterator arithmetic, just a dirt-simple for loop.
1 2 3 4 5 6 7 8 9 10 11
int Glicko::FindOrInsertPlayer(const std::string& name)
{
unsigned i;
for (i=0; i< m_Players.size(); ++i) {
if (m_Players[i].Name() == name) break;
}
if (i == m_Players.size()) {
m_Players.emplace_back(name);
}
return i;
}
you guys are awesome! thank you so much. Yeah it would be quite easier to write a bunch of loops. i'm gonna give it a go, but that makes a lot more sense. thank you guys again