Reputation: 11
In any card game, you lose your card from your hand when you play it, but with my limited knowledge in vectors I can't do it. Tried to pushback then popback to get rid of the string from the vector but doesn't work.
//Create vector to store deck names in & player's hands
vector<string> Cards;
vector<string> P1Hand;
//Generate the deck of cards
for (int i = 0; i < SuitNum;i++) //iterate through suits
{
for (auto j : CardValue)
{
card = j.first + suits[i]; //declare card
DeckValue[card] = CardValue[j.first];//add card to deck map and assign value
Cards.push_back(card); // add card to vector
CardNum++;// raise card number for every card added to deck
}
}
//display cards for player 1
while (CardNum > 13)
{
int RCard = rand()%CardNum;//generate a random number based on number of cards left in deck
string DrawCard = Cards.at(RCard); // access a random card
P1Hand.push_back(DrawCard); //add card to hand
Cards.erase(Cards.begin() + RCard); // remove cards from vector so they cant be called twice
CardNum--; //lower available cards
cout<<"["<<DrawCard<<"]"; //print card and its value
}
cout<<endl;
cout<<"Select Card to Play: ",cin>>PlayedCardP1;
What I tried:
P1Hand.push_back(PlayedCardP1); //delete last card to next deck
P1Hand.pop_back();
Basically, PlayedCardP1 should be removed from P1Hand
Upvotes: 1
Views: 567
Reputation: 11271
If you want to remove an item from a std::vector
us an use std::vector::erase
, like already used in the code. That function requires an iterator. Luckely, std::find
, used for finding an element, gives you an iterator. Hence
P1Hand.erase(std::find(std::cbegin(P1Hand), std::cend(P1Hand), PlayedCardP1));
NB this invalidates iterators and references at or after the point of the erase, including the end()
iterator. So take care it in an iterator loop. See the linked reference page.
Side note: std::vector
is an array elements in memory. If you remove an element in the middle, all items after it will be shifted forward. That can become inefficient if done very often. An std::list
is more efficient for that, but comes at the cost of more memory interactions when iterating and more storage for link pointers. You can test which one's better for you.
You could also look at std::unordered_set
, which only can contain each value once. But it has other issues. Always test which container works better.
p.s. for std::find
you need to #include <algorithm>
Upvotes: 1