Storing info for cards

R

Radith

Hi All,

I have got this task which I cant get my head around:
It asks how I would store information:
I just want to get an opinion from the group:
So here's the question:

"
You have been asked to write a program for a card playing friend. How
would you store information about playing cards? For example how would
you store the fact that a certain card is the 7 of diamonds? (You may
use more than one variable if you wish)
"

All help welcome.
Thanks in advance.

Radith
 
M

Mike Wahler

Radith said:
Hi All,

I have got this task which I cant get my head around:
It asks how I would store information:
I just want to get an opinion from the group:
So here's the question:

"
You have been asked to write a program for a card playing friend. How
would you store information about playing cards? For example how would
you store the fact that a certain card is the 7 of diamonds? (You may
use more than one variable if you wish)
"

All help welcome.
Thanks in advance.

Radith

enum suits {CLUBS, HEARTS, DIAMONDS, SPADES};
enum faces {ACE = 1, JACK = 11, QUEEN, KING};

struct card
{
unsigned int rank;
unsigned char suit;
};

card c = {7, DIAMONDS};


-Mike
 
R

Robert Gamble

Mike said:
enum suits {CLUBS, HEARTS, DIAMONDS, SPADES};
enum faces {ACE = 1, JACK = 11, QUEEN, KING};

struct card
{
unsigned int rank;
unsigned char suit;
};

card c = {7, DIAMONDS};

struct card c = {7, DIAMONDS);

Robert Gamble
 
B

Barry Schwarz

Hi All,

I have got this task which I cant get my head around:
It asks how I would store information:
I just want to get an opinion from the group:
So here's the question:

"
You have been asked to write a program for a card playing friend. How
would you store information about playing cards? For example how would
you store the fact that a certain card is the 7 of diamonds? (You may
use more than one variable if you wish)
"

You have lots of options. Just to start you off consider a struct
with two members or a 2D array of char.


<<Remove the del for email>>
 
R

Robert Gamble

John said:
struct card c = {7, DIAMONDS};

Obviously that was an attempt to keep true to the tradition that any
post correcting a grammatical (or syntactical) error must introduce one
of it's own ;)

Robert Gamble
 
W

Walter Roberson

enum suits {CLUBS, HEARTS, DIAMONDS, SPADES};
enum faces {ACE = 1, JACK = 11, QUEEN, KING};
struct card
{
unsigned int rank;
unsigned char suit;
};
card c = {7, DIAMONDS};

Mike, is there any particular reason you used int for rank when
you only used char for suit? The minimum size for char has
enough range to cover the largest possible card rank, which would
tend to suggest something like using char for each of
the elements.


For that matter, if space is more important than efficiency, then

struct card
{
unsigned char rank: 5;
unsigned char suit: 3;
}

or perhaps


#define rank_of(card) (((card)&0x1e)>>1)
#define suit_of(card) (((card)&0xe1)>>5)
#define is_face_up(card) ((card)&1)
#define build_card(rank,suit,faceup) ((suit)<<5 | ((rank)<<1) | (faceup))

typedef unsigned char card;


Mind you, I wouldn't recommend this latter implementation to anyone who
doesn't understand why the symmetry of the bitmasks is important
in rank_of() and suit_of().
 
K

Keith Thompson

Robert Gamble said:
Obviously that was an attempt to keep true to the tradition that any
post correcting a grammatical (or syntactical) error must introduce one
of it's own ;)

Shouldn't that be "its'"?
 
A

Antonio Contreras

Walter said:
#define rank_of(card) (((card)&0x1e)>>1)
#define suit_of(card) (((card)&0xe1)>>5)
#define is_face_up(card) ((card)&1)
#define build_card(rank,suit,faceup) ((suit)<<5 | ((rank)<<1) | (faceup))

typedef unsigned char card;


Mind you, I wouldn't recommend this latter implementation to anyone who
doesn't understand why the symmetry of the bitmasks is important
in rank_of() and suit_of().

Ok, you wouldn't recommend this implementation to me, cause I can't see
why the symmetry of the two bitmasks is so important.

Correct me if I'm wrong, but

#define suit_of(card) (((card)&0xe0)>>5)

would produce exactly the same result in every situation.
 
P

pete

Radith said:
Hi All,

I have got this task which I cant get my head around:
It asks how I would store information:
I just want to get an opinion from the group:
So here's the question:

"
You have been asked to write a program for a card playing friend. How
would you store information about playing cards? For example how would
you store the fact that a certain card is the 7 of diamonds? (You may
use more than one variable if you wish)

/* BEGIN shuffle.c */

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

#define LU_RAND_SEED 123456789LU
#define LU_RAND(S) ((S) * 69069 + 362437 & 0xffffffffLU)
#define SUITS (sizeof suit / sizeof *suit)
#define RANKS (sizeof rank / sizeof *rank)
#define CARDS (SUITS * RANKS)
#define HAND 5
#define DEALS 5

struct poker {
int suit;
int rank;
};

long unsigned shuffle(int *, int, long unsigned);
int compar_rank(void const*, void const*);
int compar_suit(void const*, void const*);
int straight(struct poker *);
int pair(struct poker *);
int flush(struct poker *);
int three(struct poker *);
int four(struct poker *);
int full(struct poker *);
int two_pair(struct poker *);
void s_sort(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *));

int main(void)
{
size_t card;
struct poker hand[HAND];
long unsigned deal;
long unsigned seed = LU_RAND_SEED;
char *suit[] = {"Hearts","Diamonds","Clubs","Spades"};
char *rank[] = {"Deuce","Three","Four","Five","Six",
"Seven","Eight","Nine","Ten","Jack","Queen","King","Ace"
};
int deck[CARDS];

putchar('\n');
/**/
seed = (long unsigned)time(0);
/*//**/
deal = DEALS;
while (deal-- != 0) {
seed = shuffle(deck, CARDS, seed);
for (card = 0; card != HAND; ++card) {
hand[card].suit = deck[card] % SUITS;
hand[card].rank = deck[card] % RANKS;
}
if (pair(hand)) {
if (three(hand)) {
if (four(hand)) {
puts("Four of a Kind:");
} else {
if (full(hand)) {
puts("Full House:");
} else {
puts("Three of a Kind:");
}
}
} else {
if (two_pair(hand)) {
puts("Two Pair:");
} else {
puts("Pair:");
}
}
} else {
switch (2 * flush(hand) + straight(hand)) {
case 0:
s_sort(hand, HAND, sizeof *hand, compar_rank);
printf("%s High:\n", rank[hand[4].rank]);
break;
case 1:
puts("Straight:");
break;
case 2:
puts("Flush:");
break;
default:
puts("Straight Flush:");
break;
}
}
putchar('\n');
for (card = 0; card != HAND; ++card) {
printf("%s of %s\n",
rank[deck[card] % RANKS],
suit[deck[card] % SUITS]);
}
putchar('\n');
}
return 0;
}

int pair(struct poker *hand)
{
s_sort(hand, HAND, sizeof *hand, compar_rank);
return hand[1].rank == hand[0].rank
|| hand[2].rank == hand[1].rank
|| hand[3].rank == hand[2].rank
|| hand[4].rank == hand[3].rank;
}

int three(struct poker *hand)
{
s_sort(hand, HAND, sizeof *hand, compar_rank);
return hand[0].rank == hand[2].rank
|| hand[1].rank == hand[3].rank
|| hand[2].rank == hand[4].rank;
}

int four(struct poker *hand)
{
s_sort(hand, HAND, sizeof *hand, compar_rank);
return hand[0].rank == hand[3].rank
|| hand[1].rank == hand[4].rank;
}

int full(struct poker *hand)
{
s_sort(hand, HAND, sizeof *hand, compar_rank);
return hand[1].rank == hand[0].rank
&& hand[4].rank == hand[3].rank
&&(hand[2].rank == hand[1].rank
|| hand[3].rank == hand[2].rank);
}

int two_pair(struct poker *hand)
{
s_sort(hand, HAND, sizeof *hand, compar_rank);
return hand[1].rank == hand[0].rank
&& hand[2].rank == hand[3].rank
|| hand[1].rank == hand[0].rank
&& hand[4].rank == hand[3].rank
|| hand[1].rank == hand[2].rank
&& hand[4].rank == hand[3].rank;
}

int straight(struct poker *hand)
{
s_sort(hand, HAND, sizeof *hand, compar_rank);
return hand[4].rank == hand[3].rank + 1
&& hand[3].rank == hand[2].rank + 1
&& hand[2].rank == hand[1].rank + 1
&&(hand[1].rank == hand[0].rank + 1
|| hand[1].rank == 0 && hand[0].rank == 12);
}

int flush(struct poker *hand)
{
s_sort(hand, HAND, sizeof *hand, compar_suit);
return hand[0].suit == hand[4].suit;
}

int compar_rank(void const *first, void const *second)
{
int int_1 = (*(struct poker*)first).rank;
int int_2 = (*(struct poker*)second).rank;

return int_2 > int_1 ? -1 : int_2 != int_1;
}

int compar_suit(void const *first, void const *second)
{
int int_1 = (*(struct poker*)first).suit;
int int_2 = (*(struct poker*)second).suit;

return int_2 > int_1 ? -1 : int_2 != int_1;
}

long unsigned shuffle(int *array, int n, long unsigned seed)
{
int i, r;

array[0] = 0;
for (i = 1; n > i; ++i) {
seed = LU_RAND(seed);
r = seed % (i + 1);
array = 0;
array = array[r];
array[r] = i;
}
return seed;
}

void s_sort(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *))
{
size_t bytes;
unsigned char *array, *after, *i, *j, *k, *p1, *p2, *end, swap;

array = base;
after = nmemb * size + array;
if (nmemb > (size_t)-1 / 3 - 1) {
nmemb = nmemb / 3 - 1;
} else {
nmemb = (nmemb * 3 + 1) / 7;
}
while (nmemb != 0) {
bytes = nmemb * size;
i = bytes + array;
do {
j = i - bytes;
if (compar(j, i) > 0) {
k = i;
do {
p1 = j;
p2 = k;
end = p2 + size;
do {
swap = *p1;
*p1++ = *p2;
*p2++ = swap;
} while (p2 != end);
if (bytes + array > j) {
break;
}
k = j;
j -= bytes;
} while (compar(j, k) > 0);
}
i += size;
} while (i != after);
nmemb = (nmemb * 3 + 1) / 7;
}
}

/* END shuffle.c */
 
M

Mike Wahler

John Doe said:
struct card c = {7, DIAMONDS};

If you're gonna be a nit-picky smart-ass, you better be correct.

Well, that was my error (see my original post).
I suspect Robert just copy-pasted and inserted
the 'struct' keyword. But imo he got the message
across.

-Mike
 
M

Mike Wahler

Robert Gamble said:
Obviously that was an attempt to keep true to the tradition that any
post correcting a grammatical (or syntactical) error must introduce one
of it's own ;)

But it didn't. It was there already. However your post
does have a punctuation error. :)

-Mike
 
M

Mike Wahler

Walter Roberson said:
Mike, is there any particular reason you used int for rank
you only used char for suit?

Midcourse design change. :) I originally was going to
use characters (e.g. 'C', 'H', 'D', 'S') for the suit,
but then went with the enum. Didn't even think to change
the type.
The minimum size for char has
enough range to cover the largest possible card rank, which would
tend to suggest something like using char for each of
the elements.
Right.



For that matter, if space is more important than efficiency, then

I wasn't concerned with 'efficiency' of any sort, only
demonstrating a data structure

-Mike
 
T

Thad Smith

Walter said:
#define rank_of(card) (((card)&0x1e)>>1)
#define suit_of(card) (((card)&0xe1)>>5)
#define is_face_up(card) ((card)&1)
#define build_card(rank,suit,faceup) ((suit)<<5 | ((rank)<<1) | (faceup))

typedef unsigned char card;


Mind you, I wouldn't recommend this latter implementation to anyone who
doesn't understand why the symmetry of the bitmasks is important
in rank_of() and suit_of().

I'll bite -- what advantage would there be to having the symmetrical bit
masks?

Thad
 
R

Robert Gamble

Mike said:
But it didn't. It was there already.

Your original post had a closed-curly bracket, not a parenthesis.
However your post does have a punctuation error. :)

The emoticon is serving as puncutation, the grammatical error was the
fact that "it's" should have been "its". Keith pointed this out but
his correction, in keeping with tradition I'm sure, was incorrect.

Robert Gamble
 
M

Mike Wahler

Robert Gamble said:
Mike Wahler wrote:

Your original post had a closed-curly bracket, not a parenthesis.

Sorry, my mistake.
The emoticon is serving as puncutation, the grammatical error was the
fact that "it's" should have been "its".

You're calling that a grammatical error, I called it
a punctuation error.
Keith pointed this out but
his correction, in keeping with tradition I'm sure, was incorrect.

His correction of your incorrect use of "it's" was correct. The
apostrophe is only used with "'it" to form the contraction for
"it is". The possessive does not use the apostrophe.

-Mike
 
A

Antonio Contreras

Mike said:
Sorry, my mistake.


You're calling that a grammatical error, I called it
a punctuation error.


His correction of your incorrect use of "it's" was correct. The
apostrophe is only used with "'it" to form the contraction for
"it is". The possessive does not use the apostrophe.


Precisely. Keith answer was:

Shouldn't that be "its'"?

Can't you see the little apostrophe after "its"? That single character
makes his answer incorrect. :p
 
O

Old Wolf

Mike said:
You're calling that a grammatical error, I called it
a punctuation error.


His correction of your incorrect use of "it's" was correct. The
apostrophe is only used with "'it" to form the contraction for
"it is". The possessive does not use the apostrophe.

Your correction of his Robert's observation of Keith's correction
of Robert's incorrect usage seems to be incorrect. :)

Keith wrote that it should be " its' " (note the trailing
apostrophe), which is incorrect (not correct, as you said).
However you correctly pointed out that the possessive of "it"
does not use an apostrophe at all. In fact it is the
only English word that has this property.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top