Jump to content
  • Advertisement
Sign in to follow this  
starruler

Container questions

This topic is 3714 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm working on Uno with the goal of eventually adding an AI (Uno is a very simply game) and possibly networking (way down the road). Anyways, I'm trying to decided on the correct container for cards in the Player class. A vector is nice because I can use [] to access elements which is great for getting input from the user. However, I need the cards to be ordered, which means that a set or something else would be great because that would all happen without my intervention and it would stay sorted over additions and removals. For reference I ask players to play cards like this 1 2 3 4 5G 7R 4B 7B And then I have them input the number above the card they want to play (it's text based for right now). Thanks!

Share this post


Link to post
Share on other sites
Advertisement
Vector and ordered container are not mutually exclusive. You can keep a vector sorted, and so have it ordered. Make a utility function for inserting an element into a sorted vector, and find the insertion point using, say, std::lower_bound, and maybe a similar function for removing elements for symmetry between insertion and removal.

That way you have simple ways to insert and remove, the vector is ordered, and you have random access to its content.

For reference, check this. Binary search related functions are in 3.3.

Share this post


Link to post
Share on other sites
Another question I have is whether it's bad form to store a pointer in a vector. For my hand variable it would be something like std::vector<Card*> hand. This is nice because I can simply pass around pointers and don't have to construct Cards all the time. Plus, if you don't use pointers, you can't use polymorphism. It just makes it much more difficult when a set sorts by pointer rather than what the pointer points to.

Share this post


Link to post
Share on other sites
What kind of cards do you use that are so heavy and expensive to create and/or copy that you consider using pointer to cards instead? And what kind of cards do you use that requires inheritance?

Share this post


Link to post
Share on other sites
It was a general question, my cards are very lightweight and won't use inheritance. But say I was writing a game that had a base moveableobject type and I had a list of those. I would be required to use a pointer in that case, right? Is that bad form?

Share this post


Link to post
Share on other sites
In a mostly unrelated question I have a std::list of players that I need to iterate over both forwards and backwards. In Uno you can play a reverse card that reverses the order of play. I was thinking about using an iterator to keep track of the position and then when it was reversed switch to the alternate type of iterator. However as I'm implementing it, it's getting rather nasty. Does anyone have a good alternative?

Share this post


Link to post
Share on other sites
Quote:
Original post by starruler
In a mostly unrelated question I have a std::list of players that I need to iterate over both forwards and backwards. In Uno you can play a reverse card that reverses the order of play. I was thinking about using an iterator to keep track of the position and then when it was reversed switch to the alternate type of iterator. However as I'm implementing it, it's getting rather nasty. Does anyone have a good alternative?


List iterators are bidirectional, because std::list is a doubly-linked list. Therefore, you can use the operator-- of the iterator as well as operator++. Set a flag to remember which direction you're going in, and pick accordingly.

You might try something like:


template <typename Container, typename BidirectionalIterator>
void advance_cyclic(const Container& c, BidirectionalIterator& iter, int delta) {
if (delta > 0) {
if (++iter == c.end()) { iter = c.begin(); } advance_cyclic(delta - 1);
} else if (delta < 0) {
if (iter == c.begin()) { iter = c.end(); } --iter; advance_cyclic(delta + 1);
}
}



But you might find it more practical to manipulate the list instead, such that the desired player is always at the front:


template <typename Container>
void rotate_n(const Container& c, int delta) {
Container::iterator iter = (delta < 0) ? c.end() : c.begin();
std::advance(iter, delta);
std::rotate(c.begin(), iter, c.end());
}


Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!