Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.
The last line is a bit confusing, can you explain it more cards[randNumberRoll] = cards[kDeck-i-1];
Compare
Code:
	for(i=0 ; i< kDeck ; i++) // Mixes the deck to mixDeck array
	{
		do {
			randNumberRoll = rand() % (kDeck-i);
		} while (cards[randNumberRoll] =='-');

		mixDeck[i] = cards[randNumberRoll];
		cards[randNumberRoll] = cards[kDeck-i-1];
                cards[kDeck-i-1] = '-';		
	}
with
Code:
	for(i=0 ; i< 52 ; i++) // Mixes the deck to mixDeck array
	{		
		do {
			randNumberRoll = rand() %52;
		} while (cards[randNumberRoll] =='-');
		
		mixDeck[i] = cards[randNumberRoll];
		cards[randNumberRoll] = '-';
	}
 
Well I see you've since posted your completed game so I'll post this anyway.


Code:
/* =====================================================================================================================
 * File - main.c
 * ---------------------------------------------------------------------------------------------------------------------
 * <https://forums.macrumors.com/threads/1072156/>
 *
 * Assumes C99
 * Formatted for 120 characters screen width
 * Uses 'tab' characters set as 4 space per 'tab'
 *
 * WARNING: Thrown togeether in about 45 minutes, including testing, and likely contains a few bugs!
 */

/* =====================================================================================================================
 * ---------------------------------------------------------------------------------------------------------------------
 * MARK: HEADERS
 */

//#define NDEBUG

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>


/* =====================================================================================================================
 * ---------------------------------------------------------------------------------------------------------------------
 * MARK: -
 * MARK: DEFINES
 */

#define kSUITES                  4
#define kCARDS_PER_SUITE        13
#define kCARDS_PER_DECK         ((kSUITES) * (kCARDS_PER_SUITE))


/* =====================================================================================================================
 * ---------------------------------------------------------------------------------------------------------------------
 * MARK: -
 * MARK: TYPESDEFS
 */

typedef unsigned char           card_t;
typedef card_t*                 card_ptr;


struct collection_t
{
    card_t          _v[kCARDS_PER_DECK];
    card_ptr        _end;
};

typedef struct collection_t     collection_t;
typedef collection_t*           collection_ptr;


/* =====================================================================================================================
 * ---------------------------------------------------------------------------------------------------------------------
 * MARK: -
 * MARK: GLOBALS
 */

const char*     szSuiteNames[kSUITES] =
{
    "Clubs", "Diamonds", "Hearts", "Spades"
};

const char*     szValueNames[kCARDS_PER_SUITE] =
{
    "Ace", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Jack", "Queen", "King"
};


/* =====================================================================================================================
 * ---------------------------------------------------------------------------------------------------------------------
 * MARK: -
 * MARK: CARD ROUTINES
 */

const char* suite_name(card_t card) { return szSuiteNames[card / kCARDS_PER_SUITE]; }
const char* value_name(card_t card) { return szValueNames[card % kCARDS_PER_SUITE]; }


/* =====================================================================================================================
 * ---------------------------------------------------------------------------------------------------------------------
 * MARK: -
 * MARK: COLLECTION ROUTINES
 */

void collection_constructor(collection_ptr p)
{
    assert(p);

    (*p)._end = (*p)._v;
}


/* =====================================================================================================================
 * ---------------------------------------------------------------------------------------------------------------------
 */

int collection_count(collection_ptr p)
{
    assert(p);
    
    return ((*p)._end - (*p)._v);
}


/* =====================================================================================================================
 * ---------------------------------------------------------------------------------------------------------------------
 */

void collection_push(collection_ptr p, card_t card)
{
    assert(p);
    assert(((*p)._end - (*p)._v) < kCARDS_PER_DECK);
    
    *((*p)._end++) = card;
}


/* =====================================================================================================================
 * ---------------------------------------------------------------------------------------------------------------------
 */

card_t collection_pull(collection_ptr p)
{
    assert(p);
    assert((*p)._end != (*p)._v);
    
    return *(--(*p)._end);
}


/* =====================================================================================================================
 * ---------------------------------------------------------------------------------------------------------------------
 */

card_t collection_peek(collection_ptr p, int index)
{
    assert(p);
    assert((*p)._end != (*p)._v);
    assert(index >= 0);
    assert(index < ((*p)._end - (*p)._v));
    
    return (*p)._v[index];
}


/* =====================================================================================================================
 * ---------------------------------------------------------------------------------------------------------------------
 */

void collection_swap(collection_ptr p, int indexSrc, int indexDst)
{
    assert(p);
    assert((*p)._end != (*p)._v);
    assert(indexSrc >= 0);
    assert(indexDst >= 0);
    assert(indexSrc < ((*p)._end - (*p)._v));
    assert(indexDst < ((*p)._end - (*p)._v));

    card_t  card;
    card                = (*p)._v[indexSrc];
    (*p)._v[indexSrc]   = (*p)._v[indexDst];
    (*p)._v[indexDst]   = card;
}   


#ifndef NDEBUG

/* =====================================================================================================================
 * ---------------------------------------------------------------------------------------------------------------------
 */

void collection_display_card(card_t card)
{
    printf("\n\t[%.2d] %s of %s", card, value_name(card), suite_name(card));
}


/* =====================================================================================================================
 * ---------------------------------------------------------------------------------------------------------------------
 */

void collection_display(collection_ptr p)
{
    for ( int i = 0; i < collection_count(p); i++ )
    {
        collection_display_card(collection_peek(p, i));
    }
}

#else

#define collection_display_card(x)
#define collection_display(x)

#endif

// TODO: perhaps a 'collection_shuffle(collection_ptr)' would be useful?


/* =====================================================================================================================
 * ---------------------------------------------------------------------------------------------------------------------
 * MARK: -
 */

int main(int argc, const char* argv[])
{
    collection_t    deck;
    
    collection_constructor(&deck);


    // add cards to collection 'deck' ...
    for ( int i = 0; i < kCARDS_PER_DECK; i++ )
    {
        collection_push(&deck, i);
    }
    

    // ... display collection 'deck' ...
    printf("\n\nInitial deck ...");
    collection_display(&deck);


    // ... shuffle the collection 'deck' ...
    for ( int i = 0; i < collection_count(&deck); i++ )
    {
        collection_swap(&deck, i, (rand() % kCARDS_PER_DECK));
    }
    
    
    // ... display shuffled collection 'deck' ...
    printf("\n\nShuffled deck ...");
    collection_display(&deck);


    // ... draw cards from the collection 'deck' and add to the collections 'hand1' and  'hand2' ...
    collection_t    hand1;
    collection_constructor(&hand1);

    collection_t    hand2;
    collection_constructor(&hand2);

    while ( collection_count(&deck) )
    {
        collection_push(&hand1, collection_pull(&deck));
        collection_push(&hand2, collection_pull(&deck));
    }
    

    // ... draw cards from the collection 'hand1' till collection is empty ...
    // ... display the card ...
    printf("\n\nHand1 ...");
    while ( collection_count(&hand1) )
    {
        collection_display_card(collection_pull(&hand1));
    }


    // ... draw cards from the collection 'hand2' till collection is empty ...
    // ... display the card ...
    printf("\n\nHand2 ...");
    while ( collection_count(&hand2) )
    {
        collection_display_card(collection_pull(&hand2));
    }
    
    return EXIT_SUCCESS;
}
 
lloyddean, your code is very clean and easy to read while my game is not. I am just starting on Structs in the book and have 1 1/2 chapters left. I need a break from the book so I decided to try to write the BlackJack game to see if I could do it with what I have learned so far. I didn't think about writing it the way you did.

Thanks for showing me!

-Lars
 
Keep at it I think you're doing fine. I think examples of alternate ways of doing things can be educational as well.

It'll get harder before it gets easier!
 
Code:
    // ... shuffle the collection 'deck' ...
    for ( int i = 0; i < collection_count(&deck); i++ )
    {
        collection_swap(&deck, i, (rand() % kCARDS_PER_DECK));
    }
As mentioned previously, this method produces an unfair shuffle
with more ways to produce some sequences than other sequences.
 
As mentioned previously, this method produces an unfair shuffle
with more ways to produce some sequences than other sequences.

This code was written following the first post and makes no claim to having a truly great shuffle routine as that was never my intent.

Now a real bug would've been to point out the fact that I forgot to seed the random number generator!

Thanks.
 
Last edited:
... (1) if you're making a Mac OS X or iOS application, you should be taking advantage of the NS Objects and writing your application in Objective C. The only time someone writes an application in C is when (a) They're forced to, as part of some sort of schooling or (b) they are an "Old Dog" that refuses to learn "New Tricks"

I disagree with this. For efficiency, as little of the program should be written in Objective-C as possible. Objective-C translates into extremely inefficient C. It's a really stinky OOP syntax anyway. Only use Objective-C where absolutely necessary, for the UI.

Remember, to a real programmer, no computer, and no program, is ever fast enough.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.