Opgaver i denne lektion   Gå til annoteret slide, hvor denne opgave er tilknyttet -- Tastaturgenvej: 'u'   Alfabetisk indeks   Kursets hjemmeside   

Opgaveløsning:
Spillekort


Herunder er min løsning på opgaven, som også involverer en funktion der på tilfældig måde blander et spil kort.

Bemærk anvendelsen af enumeration typer til symbolsk navngivning af (kun) nogle af kortene.

Jeg har valgt at repræsentere et kort som to heltalsværdier (værdier i de to enumeration typer). Dette er langt bedre en f.eks. to tekst-strenge, som er forholdsvis vanskelige at håndtere når kortene skal sorteres. Jokeren håndteres gennem en særlig kulør, og via en særlige "konstruktor" funktion. Jokeren er valgt til at have den største kulør. Ligeledes kommer et es efter de andre værdier. Dette gør sorteringen nemmere.

Udskrivning faciliteres af to arrays of tekststrenge, lokalt i print_card. Disse er statiske, så vi ikke igen og igen skal etablere dem. Denne datastyrede udskrivning er meget lettere at lave end udskrivning via store switch kontrolstrukturer.

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

/* NUMBER_OF_CARDS controls the number of jokers */
#define NUMBER_OF_CARDS 55

enum card_type {club, diamond, heart, spade, joker};
typedef enum card_type card_type;

/* Card values range from 2 to ace. Card values above 10 have symbolic names: */
enum card_value {jack = 11, queen = 12, king = 13, ace = 14};  
typedef enum card_value card_value;

struct card{
  card_type type;
  card_value value;
};
typedef struct card card;

card make_card(card_type t, card_value v);
card make_joker(void);
void put_cards_in_deck(card deck[]);
void print_deck(card deck[]);
void print_card(card c);
int card_compare(const void *ep1, const void *ep2);
void sort_cards(card deck[]);
void swap_cards(card deck[], int i, int j);
void shuffle_cards(card deck[]);

int main(void) {
  card deck[NUMBER_OF_CARDS];

  srand(time(NULL));   /* Seed random number generator */

  put_cards_in_deck(deck);
  printf("INITIAL:\n");
  print_deck(deck);

  shuffle_cards(deck);
  printf("\nAFTER SHUFFLE:\n");
  print_deck(deck);

  sort_cards(deck);
  printf("\nAFTER SORTING:\n");
  print_deck(deck);
  
  return 0;
}

void put_cards_in_deck(card deck[]){
  int ct, cv, i = 0, j;
  card c;

  /* Make 4 x 13 normal cards: */
  for(ct = club; ct <= spade; ct++){
    for(cv = 2; cv <= ace; cv++){
      c = make_card(ct, cv);
      deck[i] = c;
      i++;
    }
  }

  /* Make sufficient jokers, to a total of NUMBER_OF_CARS cards. */
  for(j = 1; j <= NUMBER_OF_CARDS - (4 * (int)king); j++)
    deck[i++] = make_joker();
}

void print_deck(card deck[]){
  int i;
  for (i = 0; i < NUMBER_OF_CARDS; i++) {
    print_card(deck[i]);
    printf("\n");
  }
}


card make_card(card_type t, card_value v){
  card result;
  result.type = t;
  result.value = v;
  return result;
}

card make_joker(void){
  card result;
  result.type = joker;
  result.value = 0;    /* arbitrary, but well-defined */
  return result;
}

  
void print_card(card c){
  static char *card_type_name[] = {"club", "diamond", "heart", "spade", "joker"};
  static char *card_value_name[] = {"two", "three", "four", "five", "six",
                                    "seven", "eight", "nine", "ten", 
                                    "jack", "queen", "king", "ace"};
  if (c.type == joker)
    printf("joker");
  else 
    printf("%s %s", card_type_name[c.type], card_value_name[c.value-2]);
}

void sort_cards(card deck[]){
  qsort(deck, NUMBER_OF_CARDS, sizeof(card), card_compare);
}


int card_compare(const void *ep1, const void *ep2){
  card *cp1 = (card *)ep1,
       *cp2 = (card *)ep2;

  if (cp1->type == cp2->type)
    return cp1->value - cp2->value;
  else 
    return cp1->type - cp2->type;
}


void swap_cards(card deck[], int i, int j){
  card temp_card;
  temp_card = deck[i];
  deck[i] = deck[j];
  deck[j] = temp_card;
}

void shuffle_cards(card deck[]){
  int i, r;
  for(i = 0; i < NUMBER_OF_CARDS; i++){
    r = rand() % NUMBER_OF_CARDS;
    swap_cards(deck, i, r);
  }
}