Linked List in the same Linked List - c++

I am new at C++, and I'm dealing with the Linked List. However, I'm confused that, while I'm writing a Linked List class. I'm trying to write a code for soccer league. I'm trying to hold each team in a linked list and since each team has players I would like to store them also in a linked list. So the linked list class should have a member to point a linked list which is the same property with the class I'm writing. Can it be possible?

Yes. A node of the teams list would contain a list of players. If you can't use std::list:
struct Player
{
Player* nextPlayer;
};
struct Team
{
Team* nextTeam;
Player* firstPlayer;
};
I'm pretty sure though that a list is not the optimal structure to model this.

I would prefer the following structure as you may not want to use players and teams always in a list:
struct PlayerNode
{
Player* item;
PlayerNode* nextNode;
};
struct TeamNode
{
Team* item;
TeamNode* nextNode;
};
struct Team {
// ...
PlayerNode* firstPlayer;
};
This allows you to use a team or a player as a standalone object (not connected to other teams/players).
But within a team you can also access its players, which I guess is desirable.

If you are using C++ then use STL instead. I am explaining one example with vector
Suppose this is the heirarchy
You have 2 League League1, League2
each have 2 teams Team1, Team2
each team has 10 players P1, P2
All the players of one team can be stored in a vector named temp_team
All temp_team can be pushed to vector named temp_league
All temp_league vector can be pushed to vector named footBall, League, watever.

Related

Linked list of different classes, how to access specific class functions with pointer?

Ok so I have a linked list of Personnel. However, I can add to the list a Personnel, an Employee, a Faculty, or a Student, because the other 3 are child classes.
Teacher directions: "Add a sub menu item and related functions (insert book) to allow a new book to be added into the book tree of an existing student node. The new book must be inserted into the correct place to maintain the binary search tree feature. The information of student name, book title, and url must be entered. To simply the program, you can assume that all the nodes in the linked list are Student nodes."
^^ ** I want to point out that I see where she says to simplify assume all the linked lists are student nodes, but all of the code for Personnel/Employee/Faculty and the linked list is supplied in the assignment. So, the only way to "use" that I can think of is go through all the code any change any reference from Personnel to Student, but that seems like a fairly stupid assignment at that point...
So my problem: I need to go through the linked list until I find the right entry using only name field. But then I need to edit the BookTree class that is tied to that entry, which only the child class Student has. I can't loop through the linked list with a Student pointer (although, the list is empty of anything other than students) because of type mismatch w/ Personnel, but if I find it by using a Personnel pointer I, of course, won't have access to Student specific functions to edit what I need to.
I have tried Student *ptr = &PersonnelPtr to just assign it the address after I located the correct one, no dice.
The code:
int add_book()
{
char studentName[50]; // blah
PersonnelNode *temp, *prev;
Student *student;
temp = head;
prev = temp;
while (temp != NULL)
{
student = temp->getNode(); // this line gives "value of type Personnel* cannot be assigned to an entity of type Student*
if (_stricmp(studentName, student->getName()) != 0)
{
prev = temp; // loop through
temp = temp->getNext();
index++;
}
else
{
// Do Stuff
// More importantly in the do stuff part I need access to Student-specific data/functions that Personnel pointer won't see
You should use a pointer to Personnel to control the other entities (children). Right now you're doing the other way around, and the compiler tells you that the right hand side (a Personnel*) cannot be converted to a Student*. That's because down-casting is not possible implicitly. In general, a Derived is a Base, so you can convert implicitly from Derived* to Base* (upcasting), but not the other way.
See e.g. this tutorial for some more information about up/down casting.
EDIT If you know your Personel* pointer points to a Student, then you can use dynamic_cast<Student*>(your_pointer) to access the Student features of your object. However, casts are in general a sign of imperfect design, and you should try to avoid them. In particular, how would you know what are the dynamic types of your objects in the list (assuming you get the list already filled by some other function)? You can use RTTI (testing typeid results then dynamic_cast-ing), but it is more than painful and not really recommended. It is much better to implement a common virtual interface and let the compiler deal with choosing the right virtual function at runtime.

C++ Text-based Game - "Map" Implementation

I'm trying to create a text-based adventure game. I'm thinking I want the map to be represented by different nodes where each node corresponds to a distinct location and has node pointer variables (left, forward, and right) that should point to another node in the respective direction. I tried to implement it as a linked list, but with this data structure, I could only have each node point to one other node. I want each node to point to three other nodes. Which data structure could I use to implement this or is this even possible?
A linked datastructure would do a good job of doing what you want:
example:
class location
{
std::string loc_name;
std::vector<std::pair<std::string,location*>> connections;
std::string description;
public:
bool add_link(location* loc, std::string dicription_to, std::string dicription_from);
//other parameters + functions to manage class
}
This would allow you to create locations such as:
location* loc = new location("graveyard");
loc->description = "A spooky graveyard on a hill, a cool mist floats amongst the gravestones and monuments";
loc->add_link(crypt /*previously defined*/,
"An imposing mausoleum with an open door, steps inside lead down into darkness",
"Moonlight filters down from the top of some steps, a way out?");
loc.add_link(spooky_house /*previously defined*/,
"The North gate of the graveyard",
"The entrance to the house's spooky graveyard");
I'd reccommend creating a map file you could read in though. Possibly using a template like this:
locations file:
/*locations, format = "name; description"*/
Spooky House; house_description
Crypt; crypt_description
Graveyard; A spooky graveyard on a hill, a cool mist floats amongst the gravestones and monuments
links file:
/*links, format = "index # (from); index # (to); description (from->to); description (to->from)"*/
3;2;An imposing mausoleum with an open door, steps inside lead down into darkness; Moonlight filters down from the top of some steps, a way out?
3;1;The North gate of the graveyard;The entrance to the house's spooky graveyard;
Loading the map would be as simple as reading in all the locations and pushing them into a vector for storage, then adding the links in to connect them.
You could implement a custom linked datastructure with linked positions on the map like this:
struct Map_Node{
Map_Node *left;
Map_Node *right;
Map_Node *forward;
/* other needed field*/
};
Then, you need to do the memory management on your own. For example by using smart pointers.
std::shared_ptr<Map_Node> entry{ new MapNode };
std::shared_ptr<Map_Node> hallway{ new MapNode };
entry->forward = &*hallway;
//and so on
An easier but less efficient for getting the next file would be a std::map. If each position
has its unique ID, e.g. a string, you could store the IDs of the neighboring fields and move freely on the map by using the ID.
struct Map_Node{
std::string name;
std::string left;
std::string right;
std::string forward;
/* other needed field*/
};
std::map<std::string, Map_Node> map;
Map_Node entry;
entry.name = "entry";
map[entry.name] = entry;
Map_Node hallway;
hallway.name = "hallway";
map[hallway.name] = hallway;
//links between:
map["entry"].forward = "hallway";

storing struct info in a vector (text rpg game)

I'm currently writing a text-based RPG for the Game Programming Institute course. I currently have a store in which the character can purchase armor, but now I need to add items to that. I have created a items class, but am having difficulty understanding how I can relate the store class, items class and player class together using a vector array.
I think what I should be doing is create a Item vector in the player class that holds information about the struct Items. Then when the player enters the store, the purchased items are entered into that vector.
I have included, what I feel are, relevant bits of my code. If anyone could give me some pointers or tips just to clear up my brain fog on understanding how to share information across these 3 classes that would be greatly appreciated.
Thanks!
Item.h
struct Item{
int itemType;
int goldValue;
};
In player.h class I have added the private data:
std::vector<Item> mItem;
In player.cpp I'm attemping to display the items with the function
void Player::purchaseItem(Item& mItems, int itemType, int itemValue)
Here is store.h
class Store{
public:
void enterStore(Player& player);
private:
Armor mStoreArmor;
int mCost;
};
A vector is designed to be a faster dynamically-allocated array.
I would think you'd want to use a hash or just a static array, with either keys or just indices, storing the quantity of each type of item.
you would obviously store possessions in a player class, and have the store class have a list of certain items (possibly with keys for what is in stock - this is why a hash would be a good idea).
When the player sees the store items and chooses one, the quantity in the player class's hash would be incremented.

How to remove duplicates from a doubly linked list by full name

I have a doubly linked list in which it stores player objects. The player object contains first name, last name, level and experience. Im trying to create a function that will remove a duplicate player object. For instance, if I enter Luis suarez and then he is entered again, I want the function to ask the user to enter the duplicates name and delete one of the luis suarez players (preferably the one last in the list). I've tried many things and none of them work nor delete anything. Can anyone help me with this?
Here is my try at RemoveDuplicate:
// -------------------------------------------------------------------------------------------------------
// Name: RemoveDuplicates.
// Description: Searchs through the list and finds duplicates and removes one.
// -------------------------------------------------------------------------------------------------------
void RemoveDuplicates(DoublyLinkedListIterator<Datatype> m_itr, string searchByFirstName)
{
Stats player;
string playerDuplicate = player.getFirstName();
for (m_itr.Start(); m_itr.Valid(); m_itr.Forth())
{
if (m_itr.Item().getFirstName() == searchByFirstName)
{
playerDuplicate = m_itr.Item().getFirstName();
}
}
delete(playerDuplicate);
}
My stats class has 4 member variables with getters.
private:
string firstName;
string secondName;
int level;
int experience;
In my linked list I have 3 classes.
DoublyLinkedListIterator;
DoublyLinkedList;
DoublyLinkedListNode;
Any help is greatly appreciated.
EDIT: Follow-up: Removing duplicates from a DoublyLinkedList
Looks like you have to delete the actual node in the linked list (using the iterator). Now you are just using delete on the local string variable playerDuplicate.
Full solution in the follow-up.

C++ Fantasy Football Draft Program - Adding Players to Teams

I am working on making a C++ program that will simulate a fantasy football draft.. I have used a linked list to create a list of team names, for each person participating in the draft. Now, I would like to know which way I should go about adding the players a team drafts to their respective team. I have the football players in a read in file and can figure out how to let them choose which, but cannot figure out how to store them on their respective team.
Any help appreciated
Thanks in advance
Well, you ought to have a Team class; the Team class ought to have a container to hold player names (another linked list, let's say). The list you have now should hold Teams rather than Strings.
Eventually the list of player names will probably be upgraded to a list of Player objects -- yet another class you'll want to define.
I know this is vague, but does it help?
It seems like you just need to understand the basic C++ containers a bit better.
One way might be to simply remove the player from a list or array of all players in the league, and add it to the fantasy player's list or array of players.
class Player; // ...
class FantasyPlayer
{
public:
std::vector< Player > picks; // array of my picks
};
std::vector< Player > all_players; // all available picks
std::vector< FantastyPlayer > fantasy_players; // all pickers
int iPicked = ...; // index of picked player in all_players
int iPicker = ...; // index of fantasy player currently picking
// add picked player to this fantasy player's pick list
fantasy_players[iPicker].picks.push_back(all_players[iPicked]);
// remove picked player from available players list
all_players.erase(iPicked);
Another, maybe easier, way to handle it might be to reference the "pickers" directly from the players themselves.
class FantasyPlayer; // ...
class Player
{
public:
Player() : owner(0) { /* empty */ }
FantastyPlayer* owner; // pointer to fantasy player who picked me
};
std::vector< Player > all_players; // all available picks
std::vector< FantastyPlayer > fantasy_players; // all pickers
int iPicked = ...; // index of picked player in all_players
int iPicker = ...; // index of fantasy player currently picking
// create link between a player and its picker
all_players[iPicked].owner = &(fantasy_players[iPicker]);
This code is all intentionally brief and incomplete, but maybe it'll get you started in the right direction. Good luck!