Thread: now what am i doing wrong

  1. #1
    Registered User
    Join Date
    Apr 2019
    Posts
    808

    now what am i doing wrong

    i have the following code
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    enum Suit { SPADES = 0, HEARTS = 1, CLUBS = 2, DIAMONDS = 3};
    enum Card_Value {TWO =2, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING, ACE};
    typedef struct
    {
        enum Suit suit;
        enum Card_Value card;
    } Card;
    typedef struct
    {
        char player_name[10];
        Card hand[5];
    }Hand;
    
    void initalize_random_generator(void);
    void shuffle_deck(Card *p_deck_index);
    Card * deck(void);
    int main()
    {
        Card *p_deck_index;
        int i;
    
        initalize_random_generator();
        p_deck_index = deck();
        shuffle_deck(p_deck_index);
    
        for (i = 0; i < 52; i++)
        {
            printf("card at index %d has suit: %d and face value: %d\n", i, p_deck_index[i].suit, p_deck_index[i].card);
        }
        return 0;
    }
    
    void initalize_random_generator(void)
    {
        srand((unsigned) time(NULL));
    }
    
    Card * deck(void)
    {
        static Card deck[52];
    
        return deck;
    }
    
    void shuffle_deck(Card *p_deck_index)
    {
        int count_cards = 0, card_found = 0;
        int i;
        int suit_value, face_value;
        while (count_cards < 52)
        {
            suit_value = rand() % 4;
            face_value = rand() % 14 + 2;
            for (i = 0; i < count_cards + 1; i++)
            {
                if (p_deck_index[i].suit == suit_value && p_deck_index[i].card == face_value)
                {
                    card_found = 1;
                }
            }
            if (!card_found)
            {
                p_deck_index[i].suit = suit_value;
                p_deck_index[i].card = face_value;
                count_cards ++;
            }
            else
            {
                card_found = 0;
            }
        }
    }
    if i compile this i get no warning and no errors. run it as is and i get values that i shouldn't get like 0 or 1 for face value and i get the same output over and over (at least the first 5 or 6 are the same.

    if i try to debug it with the built in debugger the debugger closes before it gets to the first line in main (initalize_random_generator())

    if i change the modulus operator for face_value from 14 to 12 as i want values between 2 and 14 again it compiles no errors or warnings this time though i get no output and it starts thrashing the pants out of the cpu and swap.

    coop

  2. #2
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    948
    See which card you're setting in lines 67 and 68. Shouldn't that be at p_deck_index[count_cards], not p_deck_index[i]?

    Also check out the Fisher-Yates shuffle algorithm.

    Also, I would expect it to become an infinite loop if you change the 14 to 12 because you're trying to fill 52 slots, each with a unique value, but you have only 48 unique values. By the 49th slot you're guaranteed that all 48 values have been used, and your algorithm will keep trying and failing to find an unused value. That should chew up the CPU but shouldn't thrash swap at all (it's not memory-intensive at all).

  3. #3
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    good catch on the p_deck_index why am i trying to fill 52 slots with 48 variables 4^12 is 16,777,216
    coop

  4. #4
    Registered User
    Join Date
    Feb 2019
    Posts
    1,078
    Why this complex shuffle?
    Here's a small change:
    Code:
    /* card.c
    
       gcc -std=c11 -o card card.c
    */
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    enum Suit { 
      SPADES = 0, 
      HEARTS, 
      CLUBS, 
      DIAMONDS 
    };
    
    enum Card_Value { 
      ACE = 1, 
      TWO, 
      THREE, 
      FOUR, 
      FIVE, 
      SIX, 
      SEVEN, 
      EIGHT, 
      NINE, 
      TEN, 
      JACK, 
      QUEEN, 
      KING 
    };
    
    typedef struct
    {
      enum Suit suit;
      enum Card_Value card;
    } Card;
    
    static void init_deck( Card * );
    static void shuffle_deck ( Card * );
    static char *get_card( Card * );
    
    int main( void )
    {
      Card deck[52];
      int i;
    
      init_deck( deck );
    
      srand( time(NULL) );
    
      shuffle_deck ( deck );
    
      for ( i = 0; i < 52; i++ )
        printf( "%s ", get_card( deck + i ) );
      putchar('\n');
    }
    
    void init_deck( Card *deckp )
    {
      int i, j, k;
    
      k = 0;
      for (i = SPADES; i <= DIAMONDS; i++)
        for (j = ACE; j <= KING; j++)
          deckp[k++] = (Card){ i, j };
    }
    
    #define swap_cards( a, b ) { Card tmp; tmp = (a); (a) = (b); (b) = tmp; }
    
    void shuffle_deck ( Card *deckp )
    {
      int i, j;
      Card tmp;
    
      for ( i = 0; i < 52; i++ )
      {
        j = rand() % 52;
        swap_cards( deckp[i], deckp[j] );
      }
    }
    
    static char *get_card( Card *card )
    {
      static char *cards[][13] = { 
        /* spaces   */ { u8"��", u8"��", u8"��", u8"��", u8"��", 
                         u8"��", u8"��", u8"��", u8"��", u8"��", 
                         u8"��", u8"��", u8"��" },
        /* hearts   */ { u8"��", u8"��", u8"��", u8"��", u8"��", 
                         u8"��", u8"��", u8"��", u8"��", u8"��", 
                         u8"��", u8"��", u8"��" },
        /* clubss   */ { u8"��", u8"��", u8"��", u8"��", u8"��", 
                         u8"��", u8"��", u8"��", u8"��", u8"��", 
                         u8"��", u8"��", u8"��" },
        /* diamonds */ { u8"��", u8"��", u8"��", u8"��", u8"��", 
                         u8"��", u8"��", u8"��", u8"��", u8"��", 
                         u8"��", u8"��", u8"��" },
      };
    
      return cards[card->suit][card->card - 1];
    }
    Result:
    Code:
    $ gcc -std=c11 -o card card.c
    $ ./card
    �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� ��
    With a little more work you can generate the appropriate string from the UTF8 codes, instead of using this table.
    Last edited by flp1969; 05-10-2019 at 01:22 PM.

  5. #5
    Registered User
    Join Date
    Feb 2019
    Posts
    1,078
    Sorry... after editing the post, this form isn't accepting the correct UTF-8 codes...
    U+1F0A1 ~ U+1F0AB (A~J) and U+1F0AD (Q), U+1F0AE (K) - spades
    U+1F0B1 ~ U+1F0BB (A~J) and U+1F0BD (Q), U+1F0BE (K) - hearts
    U+1F0D1... - clubs
    U+1F0C1... - diamonds (use ctrl+u on terminal to enter the hex codes).

    Example:

    now what am i doing wrong-untitled-jpg
    Last edited by flp1969; 05-10-2019 at 01:29 PM.

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by flp1969
    Why this complex shuffle?
    While I'm now of the opinion that for these student practice programs where getting the pseudorandomness right isn't the point, it doesn't really matter, I do note that your suggested implementation is a biased shuffle, whereas christop's suggestion in post #2 would be fair and yet also roughly as easy to implement in-place.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    a couple of questions u have declared all the functions as static what does this do?
    line 54 the call to get card you pass deck + i what does this do is it equivalent to deck[i]?
    line 65
    Code:
    deckp[k++] = (Card){ i, j };
    is this the same as writing Card.suit = i and Card.card = j
    lastly how do i type the UTF-8 codes into the terminal do i hold down ctrl-u while typing the rest??
    many thanks
    coop

  8. #8
    Registered User
    Join Date
    Feb 2019
    Posts
    1,078
    A simple function to print UTF-8 string with the card, accondingly to your criteria:
    Code:
    // suite: { 0 /* spades */, 1 /* hearts */, 2 /* clubs */, 3 /* diamonds */ }
    // card: { 0 = ace, 2 = 1, ..., 10 = 9, J = 10, Q = 11, K = 12 }
    //
    // returns, string with a single UTF-8 char.
    char *card2utf8( int suite, int card )
    {
      static char s[5] = { 0 };
    
      int c = 0x1f0a1;
    
      switch ( suite )
      {
        case 2: // clubs
          c += 0x10;
        case 3: // diamonds
          c += 0x10;
        case 1: // hearts
          c += 0x10;
      }  
    
      switch ( card )
      {
        case 0 ... 10:
          c += card; break;
        default:
          c += card + 1;
      }
    
      s[0] = 0xf0 | ((c >> 18) & 7);
      s[1] = 0x80 | ((c >> 12) & 0x3f);
      s[2] = 0x80 | ((c >> 6) & 0x3f);
      s[3] = 0x80 | (c & 0x3f);
    
      return s;
    }

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by cooper1200
    u have declared all the functions as static what does this do?
    In this case, nothing much because you only have one source file, but it is still good to do. In more complex programs, this is good practice for helper functions in that it declares the function names as having static linkage, meaning that those names in this translation unit (source file + included headers) only refer to the respective functions in that translation unit. So, you avoid name collisions as you can freely have another helper function of the same name in another source file.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    Registered User
    Join Date
    Feb 2019
    Posts
    1,078
    Quote Originally Posted by cooper1200 View Post
    a couple of questions u have declared all the functions as static what does this do?
    line 54 the call to get card you pass deck + i what does this do is it equivalent to deck[i]?
    Yep... the symbol 'deck' is a pointer to the begining of the array (or converted to).
    Quote Originally Posted by cooper1200
    Code:
    deckp[k++] = (Card){ i, j };
    is this the same as writing Card.suit = i and Card.card = j
    it is the same as writing
    Code:
    deckp[k].suit = i; deckp[k].card = j; k++;

  11. #11
    Registered User
    Join Date
    Feb 2019
    Posts
    1,078
    Quote Originally Posted by cooper1200 View Post
    lastly how do i type the UTF-8 codes into the terminal do i hold down ctrl-u while typing the rest??
    On linux, you can press Ctrl+U, release them and type the hexadecimal code of an UNICODE character and press ENTER.

    Ctrl+u, release, 0 3 b 2, <enter> = β

  12. #12
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    im doing somthing wrong here i replaced all the utf8 codes that were lost with the ones you printed out below and all i get is (null) 52 times
    coop

  13. #13
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    its working now i was displaying the output on x-term rather than xfce

  14. #14
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    im a little confused with the bitwise operations s0 for example or 240 with the result of ((127185 >> 18 and'ed with 7 but 127185 is 17 bits long

  15. #15
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    Quote Originally Posted by flp1969 View Post
    On linux, you can press Ctrl+U, release them and type the hexadecimal code of an UNICODE character and press ENTER.

    Ctrl+u, release, 0 3 b 2, <enter> = β
    if i do this on xfce terminal i get bad command or file name

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Why so wrong numbers? As I write so wrong?
    By Dmy in forum C++ Programming
    Replies: 2
    Last Post: 07-31-2017, 02:10 PM
  2. Replies: 3
    Last Post: 11-14-2011, 06:35 PM
  3. wrong wrong with my xor function?
    By Anddos in forum C++ Programming
    Replies: 5
    Last Post: 04-26-2009, 01:38 PM
  4. whats wrong with this? no errors but wrong result
    By InvariantLoop in forum C Programming
    Replies: 6
    Last Post: 01-28-2005, 12:48 AM
  5. Replies: 9
    Last Post: 07-15-2004, 03:30 PM

Tags for this Thread