I'm building a cards game and can't find the last card suit of the players hand

86 Views Asked by At

I'm making a Swedish card game my problem is find the suit of the last card, i've can get the card number but not the suit. i've used this line here to get the number,

teste(hands[HAND_COUNT][j]);

the problem is j is equivelent to the number of suits and not the actual "array". I cant get around this tho.

• A random player shuffles.

• The player opposite the shuffler leaves, cutting the deck in 2 in one random position, and placing the lower part over the upper part.

• The player to the right of the departing player deals the first 10 cards to the player in front of him. right, the next 10 to the player in front of you, the next 10 to the player his left and the last 10 for you. The suit of the last card dealt is trump.

• Players arrange their cards (by suit and value). The first to play (player who draws the first trick) is the player to the right of the giver.

• On the right, the remaining players play in turn, being mandatory to watch (play the suit that was drawn). Not having a card in hand to watch, the player can play any of his cards.

• If no one plays trumps, the player who has played the highest trump wins the trick. drawn suit card. Otherwise, whoever has played the highest wins the trick. trump.

• The player who wins a trick is the first to play the next trick.

• Once the 10 tricks have been played, the points are counted and the result is written.

#include <stdlib.h>
#include <string.h>
#include <time.h>

#define DECK_NSUITS     4
#define DECK_NVALUES    10
#define DECK_SIZE       (DECK_NSUITS * DECK_NVALUES)

#define HAND_COUNT      4
#define HAND_SIZE       (DECK_SIZE / HAND_COUNT)

#define card_suit(card) ((card >> 8) & 0xff)
#define card_value(card) (card & 0xff)
#define card_compose(suit, value) (((suit & 0xff) << 8) | (value & 0xff))
#define card_swap(card1, card2) do { if (*card1 != *card2) { *card1 ^= *card2; *card2 ^= *card1; *card1 ^= *card2; } } while (0)

void deck_build(short * deck) {
    int suit = 0, value = 0;

    for (suit = 1; suit <= DECK_NSUITS; suit++)
        for (value = 1; value <= DECK_NVALUES; value++)
            deck[(suit - 1) * DECK_NVALUES + value - 1] = card_compose(suit, value);
}

void card_output(short card) {
    switch (card_suit(card)) {
        case 1 : printf("%c", 3); break;
        case 2 : printf("%c", 4); break;
        case 3 : printf("%c", 5); break;
        case 4 : printf("%c", 6); break;
    }
    
    switch (card_value(card)) {
        case 1  : printf("A "); break;
        case 8 : printf("Q "); break;
        case 9 : printf("J "); break;
        case 10 : printf("K "); break;
        default : printf("%-2d", card_value(card));
    }
}

void teste(short card) {
    if(card_suit(card)== 1) printf("tem");
    else if(card_suit(card)== 2) printf("twem\n");
    else if(card_suit(card)== 3) printf("tkem\n");
    else if(card_suit(card)== 4) printf("tqem\n");

    if(card_value(card)== 2) printf("tem\n");
    else if(card_value(card)== 3) printf("tejm\n");
    else if(card_value(card)== 4) printf("OLAAA\n");
    else printf("nao tem\n");
    


}

void deck_shuffle(short * deck) {
    int i = 0, r = 0;

    for (i = 0; i < DECK_SIZE; i++) {
        r = rand() % (DECK_SIZE - i);
        card_swap(&deck[r], &deck[i + r]);
    }
}

int main() {
    short deck[DECK_SIZE];
    short hands[HAND_COUNT][HAND_SIZE];
    int i, j;

    /* start randon number genereation */
    srand(time(NULL));
    
    /* deck build */
    deck_build(deck);

    /* deck destribution to the players hands */
    for (i = 0; i < HAND_COUNT; i++)
    memcpy(hands[i], &deck[i * HAND_SIZE], HAND_SIZE * sizeof(short));

    /* hand presentation */
    printf("BARALHO:\n");
    for (i = 0; i < HAND_COUNT; i++) {
        for (j = 0; j < HAND_SIZE; j++) {
            card_output(hands[i][j]);
        }
        printf("\n");
    }
    printf("\n");

    /* deck shuffle */
    deck_shuffle(deck);

    /* deck destribution to the players hands */
    for (i = 0; i < HAND_COUNT; i++)
    memcpy(hands[i], &deck[i * HAND_SIZE], HAND_SIZE * sizeof(short));

    
    /* player que baralha */
    int num = (rand() %
    (4)) + 1;
    printf("player%d baralha:\n", num);

    /* hand presentation */
    for (i = 0; i < HAND_COUNT; i++) {
        for (j = 0; j < HAND_SIZE; j++) {
            card_output(hands[i][j]);
        }
        printf("\n");
    }
   
    printf("\n");printf("\n");
    
    /* parte a hand */
    if(num == 4){
        printf("player1 parte:\n");
    }else{
        printf("player%d parte:\n", num+1);
    }
    
    for (i = 0; i < HAND_COUNT; i++) {
        for (j = 0; j < HAND_SIZE; j++) {
            card_output(hands[i][j+1]);
        }
        printf("\n");
    }

    printf("\n");printf("\n");


    /* dá a hand */
    if(num+1==4){
      printf("player1 da:\n");
    }
    else if(num+1==5){
      printf("player2 da:\n");
    }else{
        printf("player%d da:\n", num+2);
    }

    for (i = 0; i < HAND_COUNT; i++) {
        printf("player%d: ", i+1);
        for (j = 0; j < HAND_SIZE; j++) {
            if(j != 0)  
            {
                card_output(hands[i][j+1]);
            } else
            {
                card_output(hands[i][j]);
            }
        } 
        printf("\n");
    }


    printf("\n");printf("\n");

    /* começa o jogo */
    teste(hands[HAND_COUNT][j]);
    return 0;
} ```
1

There are 1 best solutions below

0
NoDakker On

I tried out your code and was having an issue getting my mind wrapped around setting up hand and deck arrays in two dimensions and locating where the missing information was occurring. When I've played around with making any type of card games, I've usually used single dimension arrays for the card deck and going from there. My guess is that someplace in the evaluation of the two-dimensional array there was a scenario where one array element was being left out.

With that in mind, I did some refactoring of the code to view the card deck and hands as one-dimensional arrays. Evaluating a card in the deck for its suit and/or value was handled by calculating the array index via evaluation of the "i" and "j" loop values accordingly to acquire card locations and value. Following is a refactored version of your code.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#define DECK_NSUITS     4
#define DECK_NVALUES    10
#define DECK_SIZE       (DECK_NSUITS * DECK_NVALUES)

#define HAND_COUNT      4
#define HAND_SIZE       (DECK_SIZE / HAND_COUNT)

#define card_suit(card) ((card >> 8) & 0xff)
#define card_value(card) (card & 0xff)
#define card_compose(suit, value) (((suit & 0xff) << 8) | (value & 0xff))
#define card_swap(card1, card2) do { if (*card1 != *card2) { *card1 ^= *card2; *card2 ^= *card1; *card1 ^= *card2; } } while (0)

#if defined(_WIN32) || defined(__MSDOS__)
   #define SPADE   "\x06"
   #define CLUB    "\x05"
   #define HEART   "\x03"
   #define DIAMOND "\x04"
#else
   #define SPADE   "\xE2\x99\xA0"
   #define CLUB    "\xE2\x99\xA3"
   #define HEART   "\xE2\x99\xA5"
   #define DIAMOND "\xE2\x99\xA6"
#endif

void deck_build(short * deck)
{
    int suit = 0, value = 0;

    for (suit = 0; suit < DECK_NSUITS; suit++)
        for (value = 0; value < DECK_NVALUES; value++)
        {
            deck[suit * DECK_NVALUES + value] = card_compose((suit + 1), (value + 1));
        }
}

void card_output(short card)
{
    switch (card_value(card))
    {
    case 1  :
        printf("A");
        break;
    case 8 :
        printf("Q");
        break;
    case 9 :
        printf("J");
        break;
    case 10 :
        printf("K");
        break;
    default :
        printf("%d", card_value(card));
    }

    switch (card_suit(card))
    {
    case 1 :
        printf("%s ", HEART);    /* Hearts   */
        break;
    case 2 :
        printf("%s ", DIAMOND);    /* Diamonds */
        break;
    case 3 :
        printf("%s ", CLUB);    /* Clubs    */
        break;
    case 4 :
        printf("%s ", SPADE);    /* Spades   */
        break;
    }
}

void teste(short card)
{
    if(card_suit(card)== 1) printf("tem ");
    else if(card_suit(card)== 2) printf("twem ");
    else if(card_suit(card)== 3) printf("tkem ");
    else if(card_suit(card)== 4) printf("tqem ");

    if(card_value(card)== 2) printf("tem\n");
    else if(card_value(card)== 3) printf("tejm\n");
    else if(card_value(card)== 4) printf("OLAAA\n");
    else printf("nao tem\n");
}

void deck_shuffle(short * deck)
{
    int i = 0, r = 0;

    /* Start randon number genereation */
    srand(time(NULL));

    for (i = 0; i < DECK_SIZE; i++)
    {
        r = rand() % (DECK_SIZE - i);
        card_swap(&deck[r], &deck[i + r]);
    }
}

int main()
{
    short deck[DECK_SIZE];
    short hands[DECK_SIZE];
    int i, j;

    /* Deck build */
    deck_build(deck);

    /* Deck destribution to the players hands */
    for (i = 0; i < HAND_COUNT; i++)
        memcpy(&hands[i *  HAND_SIZE], &deck[i * HAND_SIZE], HAND_SIZE * sizeof(short));

    /* Hand presentation */
    printf("BARALHO:\n");
    for (i = 0; i < HAND_COUNT; i++)
    {
        for (j = 0; j < HAND_SIZE; j++)
        {
            card_output(hands[i * HAND_SIZE + j]);
        }
        printf("\n");
    }
    printf("\n");

    /* Deck shuffle */
    deck_shuffle(deck);

    /* Deck destribution to the players hands */
    for (i = 0; i < HAND_COUNT; i++)
        memcpy(&hands[i * HAND_SIZE], &deck[i * HAND_SIZE], HAND_SIZE * sizeof(short));

    /* Player que baralha */
    int num = (rand() % (4)) + 1;
    printf("Player%d shuffle:\n", num);

    /* Hand presentation after shuffle */
    for (i = 0; i < HAND_COUNT; i++)
    {
        for (j = 0; j < HAND_SIZE; j++)
        {
            card_output(hands[i * HAND_SIZE + j]);
        }
        printf("\n");
    }

    printf("\n");

    /* Cutting the deck */
    if(num == 4)
    {
        printf("Player1 cut deck:\n");
    }
    else
    {
        printf("Player%d cut deck:\n", num+1);
    }

    for (i = 0; i < HAND_COUNT; i++)
    {
        for (j = 0; j < HAND_SIZE; j++)
        {
            card_output(hands[i * HAND_SIZE + j]);
        }
        printf("\n");
    }

    printf("\n");

    /* dá a hand */
    if((num+1) == 4)
    {
        printf("Player1 da:\n");
    }
    else if((num+1) == 5)
    {
        printf("Player2 da:\n");
    }
    else
    {
        printf("Player%d da:\n", num + 2);
    }

    for (i = 0; i < HAND_COUNT; i++)
    {
        printf("player%d: ", i+1);
        for (j = 0; j < HAND_SIZE; j++)
        {
                card_output(hands[i * HAND_SIZE + j]);
        }
        printf("\n");
    }

    printf("\n");

    /* começa o jogo */
    teste(hands[DECK_SIZE - 1]);
    return 0;
}

Some items to point out with this refactored code:

  • Instead of starting the for loops at one, the for loops start at zero, which is a more usual and customary convention.
  • Simulation of the two-dimensional array presentation is performed by multiplying the outer loop value, "i" by the size of the hands and/or the number of cards in a suit and then adding the offset value of "j".
  • To make it more portable (FYI, I build my programs on a Linux machine), a character definition block was added to print/display the appropriate suit character.

Testing out this code resulted in the following terminal output.

@Vera:~/C_Programs/Console/SwedishCards/bin/Release$ ./SwedishCards 
BARALHO:
A♥ 2♥ 3♥ 4♥ 5♥ 6♥ 7♥ Q♥ J♥ K♥ 
A♦ 2♦ 3♦ 4♦ 5♦ 6♦ 7♦ Q♦ J♦ K♦ 
A♣ 2♣ 3♣ 4♣ 5♣ 6♣ 7♣ Q♣ J♣ K♣ 
A♠ 2♠ 3♠ 4♠ 5♠ 6♠ 7♠ Q♠ J♠ K♠ 

Player4 shuffle:
7♥ 3♥ 3♣ K♦ 7♣ 2♥ Q♦ Q♠ K♣ K♥ 
A♦ Q♥ 5♣ 3♦ 6♦ 6♠ 7♦ 5♦ 7♠ J♠ 
A♣ 2♣ K♠ J♦ A♠ 4♥ 4♦ Q♣ A♥ J♥ 
5♥ 2♠ 3♠ 4♠ J♣ 6♥ 4♣ 6♣ 5♠ 2♦ 

Player1 cut deck:
7♥ 3♥ 3♣ K♦ 7♣ 2♥ Q♦ Q♠ K♣ K♥ 
A♦ Q♥ 5♣ 3♦ 6♦ 6♠ 7♦ 5♦ 7♠ J♠ 
A♣ 2♣ K♠ J♦ A♠ 4♥ 4♦ Q♣ A♥ J♥ 
5♥ 2♠ 3♠ 4♠ J♣ 6♥ 4♣ 6♣ 5♠ 2♦ 

Player2 da:
player1: 7♥ 3♥ 3♣ K♦ 7♣ 2♥ Q♦ Q♠ K♣ K♥ 
player2: A♦ Q♥ 5♣ 3♦ 6♦ 6♠ 7♦ 5♦ 7♠ J♠ 
player3: A♣ 2♣ K♠ J♦ A♠ 4♥ 4♦ Q♣ A♥ J♥ 
player4: 5♥ 2♠ 3♠ 4♠ J♣ 6♥ 4♣ 6♣ 5♠ 2♦ 

twem tem

Hopefully, you can understand my utilization of a single dimension array and I have not complicated this for you. Doing these refinements let me define the for loops in a more customary way, plus allowed for some simplification of some of the testing.

Give this a try and see if it meets the spirit of your project.