I assume you're using some sort of custom type for the cards. So lets call this t_card_kind
.
You could do some sort of array shift to "delete" the card from the players hand. But this doesn't make much sense.
What I would suggest is defining an enum like
namespace uno { enum play_status { DRAW_PILE,IN_HAND,DISCARD }; };
That way you can simply declare a new type-defined structure
typedef struct s {
t_card_kind card;
uno::play_status status;
} t_game_card;
... and lastly declare an array such as
t_game_card my_cards[108];
or a vector such as:
vector my_cards[108];
and then populate it.
To change a card's status simply access the member.
e.g.
my_cards[i].status = uno::IN_HAND;
This design will execute much quicker and is more elegant.
To solve your second question just implement a method like
unsigned int count_status(const t_game_card * my_card,
uno::play_status status_kind) {
const unsigned int DECK_SIZE = 108; //size of a standard uno deck
unsigned int matches;
for (unsigned int counter=0; counter < DECK_SIZE;counter++) {
if (t_game_card[counter].play_status==status_kind) {
matches++;
}
}
return matches;
}
...Or just switch to vectors and use the erase() method.
EDIT 1
Based on my above discussion with John there is debates over this single container design versus a multi-container design. Here is my opinion on the topic:
I believe this design of using a single vector of cards with state info attached is more robust and easier maintain than a multi-vector based design. Here is why.
In your resulting code you would have something like:
namespace uno { enum play_status { DRAW_PILE,IN_HAND,DISCARD }; };
typedef struct s { t_card_kind card; uno::play_status status; } t_game_card;
static vector<t_game_card> my_cards[108];
Where a multi-vector based approach would have:
static t_game_card draw_pile[108];
static t_game_card in_hand;
static t_game_card discards;
...still three items, though mine is a bit longer line length wise.
As previously stated, to change a state with my approach you would simply use something like:
my_cards[i]=uno::IN_HAND;
whereas with a vector-based method you would have to do something like:
in_hand.append(draw_pile[i]);
draw_pile.erase(draw_pile.begin()+i);
This is longer, more computationally intensive, uses more memory, and in my opinion less intuitive.
Now let us consider extensibility. Let's say you come up with a uno variant that includes a "BONUS" pile. With my approach this is simple -- just add a value to the enum:
namespace uno { enum play_status { DRAW_PILE,IN_HAND,DISCARD,BONUS }; };
with the vector approach, you'll need to create and maintain an entire extra vector:
static t_game_card draw_pile[108];
static t_game_card in_hand;
static t_game_card discards;
static t_game_card bonus;
We now have 4 (!) variables with the vector based approach versus a single, intuitive variable with my approach.
Maintaining multiple containers for separate states takes up more memory, is computationally more expensive, and is less intuitive versus using a single container (vector, array, etc.) to hold structures with state info attached.