Solved Really Stuck On Game Lobby Excercise

Hexui Undetected CSGO Cheats Sinkicheat PUBG Cheat

TheGreatUnknown

Jr.Coder
Full Member
Nobleman
Dec 20, 2012
58
417
1
My excercise is:
Improve the Lobby class from the Game Lobby program by writing a
friend function of the Player class that allows a Player object to be sent
to cout. Next, update the function that allows a Lobby object to be sent
to cout so that it uses your new function for sending a Player object to
cout.

C++:
//Game Lobby
//Simulates a game lobby where players wait

#include <iostream>
#include <string>
using namespace std;


class Player
{
         friend ostream& operator<<(ostream& os, const Player& aPlayer); // to send player object to cout
public:
	Player(const string& name = "");
	string GetName() const;
	Player* GetNext() const;
	void SetNext(Player* next);

private:
	string m_Name;
	Player* m_pNext; // Pointer to next player in list
};


Player::Player(const string& name): // constructor
	m_Name(name), 
	m_pNext(0)
{}
string Player::GetName() const
{
	return m_Name;
}

Player* Player::GetNext() const
{
	return m_pNext;
}

void Player::SetNext(Player * next)
{
	m_pNext = next;
}

class Lobby
{
	friend ostream& operator<<(ostream& os, const Lobby& aLobby); // remember ostream& os then a comma!
public:
	Lobby();
	~Lobby();
	void AddPlayer();
	void RemovePlayer();
	void Clear();
private:
	Player* m_pHead;
};

Lobby::Lobby():
m_pHead(0)
{}

Lobby::~Lobby()
{
	Clear();
}



void Lobby::AddPlayer()
{
	// creates a new player node
	cout << "Please enter the name of your player: ";
	string name;
	cin >> name;
	Player* pNewPlayer = new Player(name);

	// if list is empty, make head of list this new player
	if(m_pHead == 0)
	{
		m_pHead = pNewPlayer;
	}
	// otherwise find the end of the list and add the player there
	else
	{
		Player* pIter = m_pHead;
		while(pIter->GetNext() != 0)
		{
			pIter = pIter->GetNext();
		}
		pIter->SetNext(pNewPlayer);
	}

}

	void Lobby::RemovePlayer()
	{
		if(m_pHead == 0)
		{
			cout << "The game lobby is empty, No one to remove!\n";
		}

		else
		{
			Player* pTemp = m_pHead;
			m_pHead = m_pHead->GetNext();
			delete pTemp;
		}
	}

	void Lobby::Clear()
	{
		while(m_pHead != 0)
		{
			RemovePlayer();
		}
	}

	ostream& operator<<(ostream& os, const Lobby& aLobby) // remember ostream& os then a comma!
	{
		Player* pIter = aLobby.m_pHead;
		os << "\nHere's whos in the game lobby:\n";
			if (pIter == 0)
			{
				os << "The game lobby is empty.\n";
			}

			else
			{
				while(pIter != 0)
				{
					os <<pIter->GetName() << endl;
					pIter = pIter->GetNext();
				}
			}

			return os;
	}

	int main()
	{
	Lobby myLobby;
	int choice;

	do 
	{
		cout << myLobby;
		cout << "\nGAME LOBBY\n";
		cout << "0 - Exit the program.\n";
		cout << "1 - Add a player to the lobby.\n";
		cout << "2 - Remove a player from the lobby.\n";
		cout << "3 - Clear the lobby.\n";
		cout << endl << "Enter choice: ";
		cin >> choice;

		switch (choice)
		{
		case 0: cout << "Good-bye.\n"; break;
		case 1: myLobby.AddPlayer(); break;
		case 2: myLobby.RemovePlayer(); break;
		case 3: myLobby.Clear(); break;
		default: cout << "That was not a valid choice.\n";
		}
	}
	
	while (choice != 0);

	return 0;
}
So far I've gotten to:
C++:
class Player
{
	friend ostream& operator<<(ostream& os, const Player& aPlayer);
public:
	Player(const string& name = "");
	string GetName() const;
	Player* GetNext() const;
	void SetNext(Player* next);

private:
	string m_Name;
	Player* m_pNext; // Pointer to next player in list
};
But have no idea how to update it to allow a lobby object to be sent to cout and the weird thing is the RemovePlayer(); function loops infinitely even if I download the source code from the authors book myself. Could anyone help me out?
 
Last edited:

Solaire

Respected Hacker
Dank Tier VIP
Dec 15, 2013
1,051
16,353
62
friend ostream& operator<<(ostream& os, const Player& aPlayer);
Are you wanting the player, or lobby to be sent to cout? In the function prototype specify which, then in the function, you'd do something like:
C++:
OverloaderStuff(ostream&os, const Player& c)
{
    os << Player.Name;
    return os;
}
That would send the player's name to the screen.

As for the RemovePlayer(); function, I'm not sure. I skimmed over this part of the book because the writer gets just a tad bit vague in some areas. I recommend checking out This Site. It's where I got a lot of really good information on classes.
 

TheGreatUnknown

Jr.Coder
Full Member
Nobleman
Dec 20, 2012
58
417
1
Cheers I got that feeling to, his remove player function doesn't work. Nice one mate. Any other books to reccomend once I've finished this one or should I just go through the web looking at code?
 

Solaire

Respected Hacker
Dank Tier VIP
Dec 15, 2013
1,051
16,353
62
I read the book up until the basic classes, put it down and read the sites take on classes, then picked the book back up and re-read a lot of the stuff in it to solidify what I had learned. As for other books, I'm not sure. It's the only C++ book I've actually read. C++ Primer 5th Edition looks promising, but I stopped at the beginning classes stuff because they didn't actually include the code for the class :p. (My learning right now seems to revolve around classes lol)

I'm not really sure why it wouldn't work. The code looks good to me, check your deconstructors if they are functioning properly. Does the Clear() function work for you?
 

TheGreatUnknown

Jr.Coder
Full Member
Nobleman
Dec 20, 2012
58
417
1
It does yeah, good advice there is a lot more useful info on the web once you know the basics. Classes arn't the most important thing but learning C++ it is something good to get comfortable with ^^
 

Solaire

Respected Hacker
Dank Tier VIP
Dec 15, 2013
1,051
16,353
62
It does yeah, good advice there is a lot more useful info on the web once you know the basics. Classes arn't the most important thing but learning C++ it is something good to get comfortable with ^^
True, but you definitely want to know how to use them. They are really nice in the fact that you don't have to copy the same code 20 times just because there are slight differences between the objects you are creating. I think the term I'm looking for here is 'Abstraction'. Know how to use the functions, but don't worry about what happens behind the scenes. The way the book described it was great, it went something like "Abstraction is like a car. You don't know where all of the pieces and bolts go. You just know how to push on the gas pedal and turn the steering wheel". It also cleans up the entry point, because you don't have stray code unless it's needed.
 

Solaire

Respected Hacker
Dank Tier VIP
Dec 15, 2013
1,051
16,353
62
Huh. I really don't see anything wrong with it. Try using breakpoints in your compiler, and step through that part of code to see where it goes wrong.
 

TheGreatUnknown

Jr.Coder
Full Member
Nobleman
Dec 20, 2012
58
417
1
I tried debugging using breakpoints even copied the source code from the authors site. Will read up on using breakpoints and debugging again but this surely has me stumpt. I'm on chapter 10 at the moment, after that I'll have to reread and get it all stuck in my head.
 

HalfWayToHell333

Jr.Coder
Silenced
Full Member
Nobleman
Jun 23, 2014
80
783
3
Isn´t there a "break" missing?!
C++:
	switch (choice)
		{
		case 0: cout << "Good-bye.\n"; break;
		case 1: myLobby.AddPlayer(); break;
		case 2: myLobby.RemovePlayer(); break;
		case 3: myLobby.Clear(); break;
		default : cout << "That was not a valid choice.\n";
                break; // <- missed
		}
and dont use uninitialised vars.
int choice = 0;
Hope that helps.
 

Liduen

Hacker
Dank Tier VIP
May 19, 2013
702
8,478
33
Isn´t there a "break" missing?!
C++:
	switch (choice)
		{
		case 0: cout << "Good-bye.\n"; break;
		case 1: myLobby.AddPlayer(); break;
		case 2: myLobby.RemovePlayer(); break;
		case 3: myLobby.Clear(); break;
		default : cout << "That was not a valid choice.\n";
                break; // <- missed
		}
and dont use uninitialised vars.
int choice = 0;
Hope that helps.
I'm sorry to disappoint you, but the break there changes absolutely nothing :)
 

HalfWayToHell333

Jr.Coder
Silenced
Full Member
Nobleman
Jun 23, 2014
80
783
3
Your are right.

I checked the whole source and here is a possible solution , no more infinite Loop in my case.

C++:
//Game Lobby
//Simulates a game lobby where players wait

#include <iostream>
#include <string>
using namespace std;


class Player
{
	friend ostream& operator<<(ostream& os, const Player& aPlayer); // to send player object to cout
public:
	Player(const string& name);
	string GetName() const;
	Player* GetNext() const;
	void SetNext(Player* next);

private:
	string m_Name;
	Player* m_pNext; // Pointer to next player in list
};


Player::Player(const string& name = "") : // constructor
m_Name(name),
m_pNext(nullptr)
{}
string Player::GetName() const
{
	return m_Name;
}

Player* Player::GetNext() const
{
	return m_pNext;
}

void Player::SetNext(Player * next)
{
	m_pNext = next;
}

class Lobby
{
	friend ostream& operator<<(ostream& os, const Lobby& aLobby); // remember ostream& os then a comma!
public:
	Lobby();
	~Lobby();
	void AddPlayer();
	void RemovePlayer();
	void Clear();
private:
	Player* m_pHead;
};

Lobby::Lobby() :
m_pHead(0)
{}

Lobby::~Lobby()
{
	Clear();
}



void Lobby::AddPlayer(){//modded
	// creates a new player node
	cout << "Please enter the name of your player: ";
	string name;
	cin >> name;
	Player* pNewPlayer = new Player(name);

	cin.clear();
	cin.ignore();

	// if list is empty, make head of list this new player
	if (m_pHead == 0)
	{
		m_pHead = pNewPlayer;
	}

	// otherwise find the end of the list and add the player there
	else
	{
		Player* pIter = m_pHead;

		while (pIter->GetNext() != nullptr)
		{
			pIter = pIter->GetNext();
		}
		pIter->SetNext(pNewPlayer);
	}

}

void Lobby::RemovePlayer(){//modded
	if (m_pHead == nullptr)
	{
		cout << "The game lobby is empty, No one to remove!\n";
	}

	else
	{
		Player* pTemp = m_pHead;
		m_pHead = m_pHead->GetNext();
		delete pTemp;
	}
}

void Lobby::Clear()
{
	while (m_pHead != 0)
	{
		RemovePlayer();
	}
}

ostream& operator<<(ostream& os, const Lobby& aLobby){//modded
	Player* pIter = aLobby.m_pHead;
	os << "\nHere's whos in the game lobby:\n";
	if (pIter == nullptr)
	{
		os << "The game lobby is empty.\n";
	}

	else
	{
		while (pIter != nullptr)
		{
			if (pIter->GetName() != ""){//no name ?!
				os << pIter->GetName() << "\n";
			}

			if (pIter->GetNext() != nullptr){//no next Player ?!
				pIter = pIter->GetNext();
			}
			else break;
		}
	}

	return os;
}

int main()
{
	Lobby myLobby;
	int choice = -1;
	do
	{
		cout << myLobby;
		cout << "\nGAME LOBBY\n";
		cout << "0 - Exit the program.\n";
		cout << "1 - Add a player to the lobby.\n";
		cout << "2 - Remove a player from the lobby.\n";
		cout << "3 - Clear the lobby.\n";
		cout << "Enter choice: ";
		cin >> choice;
		if (cin.good()){//is input valid ?
			switch (choice){
			case 0: choice = -1;
				    cout << "Good-bye.\n";
				break;
			case 1: myLobby.AddPlayer();
				break;
			case 2: myLobby.RemovePlayer();
				break;
			case 3: myLobby.Clear();
				break;
			default: cout << "That was not a valid choice.\n";
				cin.clear();
				cin.ignore();
				break;
			}
		}
		else {// nope it was bullshit
			cout << "!Bullshit Input!" << endl;
			cin.clear();
			cin.ignore();

		}

	} while (choice > -1);

	return 0;
}

Maybe it is usefull.
 
Last edited:

TheGreatUnknown

Jr.Coder
Full Member
Nobleman
Dec 20, 2012
58
417
1
Sorry I meant ye the clear works but not the RemovePlayer, nice one btw I'll give it a test!
EDIT: Sadly it still thinks there is no one in the lobby to remove. Keep in mind this is even in the authors source code this error happens. So lord knows why it's happening, it seems each time a lobby user and you use option 2 to remove someone it removes a random user. Then trying to remove anyone will go into an infinite loop.
 
Last edited:

HalfWayToHell333

Jr.Coder
Silenced
Full Member
Nobleman
Jun 23, 2014
80
783
3
Sorry but i cant reproduce your Error.
I used the Code you posted modified it and now added some "console debugging" , a node counter and a Dtor cout to the Player Class.
In VS2013 there seems to be no error.
All works as it should so far for a sinlge linked List.
BTW why dont use a std::deque or a std::list or std::vector instead of Raw Pointers ?

C++:
//Game Lobby
//Simulates a game lobby where players wait

#include <iostream>
#include <string>
using namespace std;


class Player
{
	friend ostream& operator<<(ostream& os, const Player& aPlayer); // to send player object to cout
public:
	Player(const string& name);
	~Player(){ cout << "\n" <<"Player erased : " << m_Name << endl; }
	string GetName() const;
	Player* GetNext() const;
	void SetNext(Player* next);

private:
	string m_Name;
	Player* m_pNext; // Pointer to next player in list
};


Player::Player(const string& name = "") : // constructor
m_Name(name),
m_pNext(nullptr)
{}
string Player::GetName() const
{
	return m_Name;
}

Player* Player::GetNext() const
{
	return m_pNext;
}

void Player::SetNext(Player * next)
{
	m_pNext = next;
}

class Lobby
{
	friend ostream& operator<<(ostream& os, const Lobby& aLobby); // remember ostream& os then a comma!
public:
	Lobby();
	~Lobby();
	void AddPlayer();
	void RemovePlayer();
	void Clear();
private:
	Player* m_pHead;
	int nodeCount;//added
};

Lobby::Lobby() : m_pHead(nullptr) , nodeCount(0)
{}

Lobby::~Lobby()
{
	Clear();
}



void Lobby::AddPlayer(){//modded
	// creates a new player node
	cout << "Please enter the name of your player: ";
	string name = "";
	cin >> name;
	Player* pNewPlayer = new Player(name);

	cin.clear();
	cin.ignore();

	// if list is empty, make head of list this new player
	if (m_pHead == nullptr)
	{
		m_pHead = pNewPlayer;
		nodeCount++;
	}

	// otherwise find the end of the list and add the player there

	else
	{
		Player* pIter = m_pHead;

		while (pIter->GetNext() != nullptr){
			pIter = pIter->GetNext();
		}
		
		pIter->SetNext(pNewPlayer);
		nodeCount++;
		
	}

}

void Lobby::RemovePlayer(){//modded
	if (m_pHead == nullptr || nodeCount == 0){
		cout << "The game lobby is empty, No one to remove!\n";
	}

	else 
	{
		Player* pTemp = m_pHead;
		m_pHead = m_pHead->GetNext();
		delete pTemp;
		nodeCount--;
	}
	
}

void Lobby::Clear()
{
	while (m_pHead != nullptr)
	{
		RemovePlayer();
	}
}

ostream& operator<<(ostream& os, const Lobby& aLobby){//modded
	
	Player* pIter = aLobby.m_pHead;

	os << "\nHere's whos in the game lobby:\n";
	
	if (pIter == nullptr)
	{
		os << "The game lobby is empty.\n";
	}

	else
	{
		while (pIter != nullptr)
		{
				os << pIter->GetName() << "\n";
				pIter = pIter->GetNext();
		}
	}

	os <<"current Nodes : "<< aLobby.nodeCount << "\n";

	return os;
}

int main()
{
	Lobby myLobby;
	int choice = -1;
	do
	{
		cout << myLobby;
		cout << "\nGAME LOBBY\n";
		cout << "0 - Exit the program.\n";
		cout << "1 - Add a player to the lobby.\n";
		cout << "2 - Remove a player from the lobby.\n";
		cout << "3 - Clear the lobby.\n";
		cout << "Enter choice: ";
		cin >> choice;
		if (cin.good()){//is input valid ?
			switch (choice){
			case 0: choice = -1;
				    cout << "Good-bye.\n";
				break;
			case 1: myLobby.AddPlayer();
				break;
			case 2: myLobby.RemovePlayer();
				break;
			case 3: myLobby.Clear();
				break;
			default: cout << "That was not a valid choice.\n";
				cin.clear();
				cin.ignore();
				break;
			}
		}
		else {// nope it was bullshit
			cout << "!Bullshit Input!" << endl;
			cin.clear();
			cin.ignore();

		}

	} while (choice > -1);

	return 0;
}
 

TheGreatUnknown

Jr.Coder
Full Member
Nobleman
Dec 20, 2012
58
417
1
Mainly because it's in the book so should work, and I'm not that advanced yet. I'm understanding many concepts it's practical I am getting to ^^
 
Attention! Before you post:

Read the How to Ask Questions Guide
99% of questions are answered in the Beginner's Guide, do it before asking a question.

No Hack Requests. Post in the correct section.  Search the forum first. Read the rules.

How to make a good post:

  • Fill out the form correctly
  • Tell us the game name & coding language
  • Post everything we need to know to help you
  • Ask specific questions, be descriptive
  • Post errors, line numbers & screenshots
  • Post code snippets using code tags
  • If it's a large project, zip it up and attach it

If you do not comply, your post may be deleted.  We want to help, please make a good post and we will do our best to help you.

Community Mods