0

This is simplification of my classes (a "gang-management" game logic):

class Player
{
private:
    string nickname, password;
    Gang my_gang; //this player's gang class instance
public:
    //generic functions...
}
//PlayerContainer is a database of all possible players, each player has a specific gang assigned
class PlayerContainer
{
private:
    list<Player> player_list;
public:
    void add_player();
    void remove_player();
    // and many more .....
    void login();
    void sign_up();
}

Now I wanted to test the login/sign up functionality in the console. In main, the program first asks a user for a login, or for a registration (new gang creation).

Following is the login() function definition (only the parts that I thought would be necessary):

//if login() returns false, the rest of the program won't continue. 
//If true is returned, the program forwards to the menu-part.

bool PlayerContainer::login()
{
    string nick, pass;

    cout << endl << "Enter your nickname: ";
    cin >> nick;
    cout << "Enter your password: ";
    cin >> pass;

    list<Player>::iterator it;

    for (it = player_list.begin(); it != player_list.end(); ++it)
    {
        if (it->get_nickname() == nick && it->get_password() == pass)
        {
            return true;
        }
        else
        {
            //breaks the loop and lets the function return false;
        }
    }

    return false;
}

Now the sign_up() function:

void PlayerContainer::sign_up()
{
    string nick, pass, gang_name;

    cout << endl << "Enter your nickname: ";
    cin >> nick;
    cout << "Enter your password: ";
    cin >> pass;

    list<Player>::iterator it;

    /*Check whether there are no known players*/
    for (it = player_list.begin(); it != player_list.end(); ++it)
    {
        if (it->get_nickname() == nick)
        {
            cout << endl << "ERROR: Player [" << it->get_nickname() << "] already exists!";
            return;
        }
    }

    cout << "\tCreate your gang" << endl << "Enter name of your gang: ";
    cin >> gang_name;

    Gang* g = new Gang(gang_name);

    Player* tmpp = new Player(nick, pass, *g);
    player_list.push_back(*tmpp); //store the temp player in the player list

    cout << endl << "Gang created successfully";
}

EXPECTATIONS:

  • after signing up, the user "account" data should be stored in list<Player> player_list.

PROBLEM:

  • when trying signing up after logging in, the login function won't evaluate true (won't let me in).

From what I tried by observing the code behaviour, it seems it's never really saved in player_list. It must have "slipped through". I'm blaming this part of code:

Player* tmpp = new Player(nick, pass, *g);
player_list.push_back(*tmpp); //store the temp player in the player list

I'd be very thankful for any insights!

Swordfish
  • 12,971
  • 3
  • 21
  • 43
DemoVision
  • 71
  • 6
  • 1
    Why are you using `new`, and not simply `player_list.push_back(Player(nick, pass, Gang(gang_name)));`? Also, there is no need for `Gang` to be dynamically allocated. – PaulMcKenzie Jul 28 '20 at 01:51

1 Answers1

1
    list<Player>::iterator it;

    for (it = player_list.begin(); it != player_list.end(); ++it)
    {
        if (it->get_nickname() == nick && it->get_password() == pass)
        {
            return true;
        }
        else
        {
            //breaks the loop and lets the function return false;
        }
    }

The else-Block will break the search on the first mismatch. After you fixed your search functionality consider overloading operator==() and using std::find().


Btw: std::list<> is almost always inappropriate. Use std::deque<> or std::vector<>. In which scenario do I use a particular STL container?


Btw2:

   list<Player>::iterator it;

   for (it = player_list.begin(); it != player_list.end(); ++it)

~~>

for (auto it{ player_list.begin() }; it != player_list.end(); ++it) // ...

~~>

for (auto const &player : player_list) // ...

Btw3: I don't know what your game will be like but I'd assume a gang would have multiple members and not every player wants to found it's own gang but rather join an existing one. Maybe you want to reconsider your data model.

Swordfish
  • 12,971
  • 3
  • 21
  • 43
  • Thanks very much! It worked 110%. Also, thank you for pointing out what I should improve. I'm still pretty new to c++ and I'm always up to find out new proper ways of using it. Thanks for your insight! EDIT:Btw3: The players would be gang leaders and would fight against other players' gangs with their own. :-) But I know it still may have whole bunch of other flaws – DemoVision Jul 28 '20 at 02:23
  • 1
    @DemoVision Please also follow PaulMcKenzie's advice: `new` is hardly ever used in modern C++ (when you aren't writing libraries but user code). If you have to use dynamically created objects use a container or a smart pointer. – Swordfish Jul 28 '20 at 02:29