You don't have to delete anything.
Shuffle your deck array (using a Fisher-Yates shuffle or similar algorithm). Deal each card from the "top" of the deck:
int top = 0;
card1 = deck[top++];
card2 = deck[top++];
card3 = deck[top++];
...
etc. The top variable is the index of the next available card in the deck.
The general outline of your code will be something like
#define DECKSIZE 52
#define HANDSIZE 5
int main( void )
{
int deck[DECKSIZE] = { ... }; // initial deck;
size_t top = 0; // points to next available card
shuffle( deck, DECKSIZE );
int hero[HANDSIZE] = {0}; // 0 means no card has been drawn for
int villan[HANDSIZE] = {0}; // that element.
if ( deal( hero, HANDSIZE, deck, DECKSIZE, &top ) &&
deal( villan, HANDSIZE, deck, DECKSIZE, &top ) )
{
/**
* do stuff with hero and villan hands
*/
}
else
{
/**
* Not enough cards available in deck for two hands.
*/
}
};
Your deal function would look something like
int deal( int *hand, size_t handsize, int *deck, size_t decksize, size_t *top )
{
size_t i;
for ( i = 0; i < handsize && *top < decksize; i++ )
hand[i] = deck[(*top)++];
return i == handsize;
}
This function will return 0 if we run out of cards in deck before we've dealt the hand, in which case you'll need to do...something. Good luck!
If you want to deal a partial hand (such as to replace 3 cards), you'd do something like
if ( deal( &hero[2], 3, deck, DECKSIZE, &top) )
...
This call will overwrite hero[2] through hero[4] with three new cards drawn from deck. With each call to deal, top will be advanced to point to the next available card in the deck.
You can write a discard function that returns cards to the deck. It means keeping a separate bottom variable and updating that:
int discard( int card, int *deck, size_t decksize, size_t *top, size_t *bottom )
{
int result = *bottom < *top && *bottom < decksize;
if ( result )
deck[(*bottom)++] = card;
return result;
}
Obviously, bottom should be strictly less than the deck size and strictly less than top on a discard; otherwise, we haven't managed our deck or hands properly. With a little work, you could make your array "circular", such that top and bottom "wrap around" as necessary. If you exhaust the deck, you can reshuffle (minus the cards in hand, which will be the deck entries between bottom and top) and reset top and bottom as necessary.
Play with this on paper for a little while, and it should become obvious.
EDIT
Addressing questions here:
At which point do you assign deck[5] to a card, for instance
That happens in the deal function, in the for loop. The first time we call deal, we tell it to deal to the hero hand:
deal( hero, HANDSIZE, deck, DECKSIZE, &top )
At this point, top is 0. Assuming we're dealing 5 cards at a time, the first call to deal effectively does this:
Loop iteration 0: hero[0] = deck[0]
Loop iteration 1: hero[1] = deck[1]
Loop iteration 2: hero[2] = deck[2]
Loop iteration 3: hero[3] = deck[3]
Loop iteration 4: hero[4] = deck[4]
When the function returns, the top variable has been updated to 5. The next time we call deal, we tell it to deal to the villain hand:
deal( villain, HANDSIZE, deck, DECKSIZE, &top )
Again, assuming we're dealing 5 cards at a time, the loop effectively does this:
Loop iteration 0: villain[0] = deck[5];
Loop iteration 1: villain[1] = deck[6];
Loop iteration 2: villain[2] = deck[7];
Loop iteration 3: villain[3] = deck[8];
Loop iteration 4: villain[4] = deck[9];
After the second call to deal, top has been updated to 10.
Each time you call deal with the top variable, it will start dealing from deck at the position specified by top, and each time through the loop it will add 1 to top. The loop will exit if one of two conditions is true:
i == handsize - we've dealt all the cards necessary for this hand
*top == decksize - we've reached the end of the array, nor more cards may be dealt.
So, suppose you've dealt a number of hands, and there are only 3 cards left in the deck - if you try to deal 5 more cards, the loop will exit before you've dealt all 5 cards, and we'll return a 0 to indicate that no more cards are left in the deck.
at which point is the desk shuffled randomly?
You would call a shuffle function to do that before the first call to deal:
int deck[DECKSIZE] = { ... };
...
shuffle( deck, DECKSIZE );
...
if ( deal( hero, HANDSIZE, deck, DECKSIZE, &top ) &&
deal( villain, HANDSIZE, deck, DECKSIZE, &top ) )
{
...
}
A simplistic (and not terribly good) implementation of the shuffle function would be:
void shuffle( int *deck, size_t decksize )
{
for ( size_t i = 0; i < decksize; i++ )
{
int r = rand() % (decksize - i)
int tmp = deck[i+r];
deck[i+r] = deck[i];
deck[i] = tmp;
}
}
Basically, what this does is swap each deck[i] with a randomly chosen element from deck[i] through deck[decksize-1] (meaning the element may remain in place). Assume we have 5 cards. The first time through the loop, i points to the first card. We pick an offset from i at random and call it r:
i --> 1
2
3
4 <-- r
5
We then swap the contents of deck[i] and deck[i+r], and then advance i:
4
i --> 2
3
1
5
We pick another r at random from the remaining elements:
4
i --> 2
3
1
5 <-- r
and do another swap and advance i:
4
5
i --> 3
1
2
Lather, rinse, repeat - by the end of the loop, the array is more-or-less randomly shuffled.
0or-1?) and check for that.srand()— why call it only once?