![]() |
| | #1 |
| Registered User Join Date: Jun 2007 Location: Scotland
Posts: 101
| Blackjack I am trying to write a blackjack game and I am running into a few teething problems. My main() function currently outputs what values are stored for certain variables, just to see if I'm doing things properly. Here is the code: Code: #include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX 10
typedef struct {
int card;
int suit;
int value;
} card_t;
void generate_card(card_t *crd, int *num, int *score);
int main(void) {
/* current scores for dealer and player */
int p_score = 0;
int d_score = 0;
/* number of cards in their hand */
int p_numofcards = 0;
int d_numofcards = 0;
/* initialise hands */
card_t p_hand[MAX];
card_t d_hand[MAX];
srand((unsigned int)time(NULL));
int i;
for(i=0;i<2;i++) { /*loop twice because at the start of blackjack, each player is given two cards*/
generate_card(&p_hand[i], &p_numofcards, &p_score);
generate_card(&d_hand[i], &d_numofcards, &d_score);
}
/* test */
printf("p_score=%d, p_numofcards=%d\n", p_score, p_numofcards);
printf("d_score=%d, d_numofcards=%d\n", d_score, d_numofcards);
int k;
for(k=0;k<2;k++) {
printf("p_hand[%d].card=%d,"
" p_hand[%d].suit=%d, "
" p_hand[%d].value=%d\n",
k,p_hand[i].card,
k,p_hand[i].suit,
k,p_hand[i].value
);
printf("d_hand[%d].card=%d,"
" d_hand[%d].suit=%d,"
" d_hand[%d].value=%d\n",
k,d_hand[i].card,
k,d_hand[i].suit,
k,d_hand[i].value
);
}
return 0;
}
void generate_card(card_t *crd, int *num, int *score) {
/* crd = (card_t *)malloc(MAX*sizeof(card_t)); */
crd->card = (rand() % 13) + 1;
crd->suit = (rand() % 4) + 1;
int c;
for(c=1;c<11;c++) {
if(crd->card == c) { /*if card is 1-10 (ace- 10) then let the value of the card be whatever it is*/
crd->value = c;
(*score)+=c; /*adds to the score (eg. 10 of hearts would add a 10) */
(*num)++; /*increments the number of cards in the players' hand*/
}
}
switch(crd->card) {
case 11: case 12: case 13: /* if card is jack, queen or king...*/
crd->value = 10;
(*score)+=10;
(*num)++;
break;
}
/*free(crd);*/
}
Code: $ gcc -o bjack bjack.c $ ./bjack p_score=8, p_numofcards=2 d_score=8, d_numofcards=2 p_hand[0].card=0, p_hand[0].suit=0, p_hand[0].value=0 d_hand[0].card=0, d_hand[0].suit=134513052, d_hand[0].value=24641422 p_hand[1].card=0, p_hand[1].suit=0, p_hand[1].value=0 d_hand[1].card=0, d_hand[1].suit=134513052, d_hand[1].value=24641422 Code: $ ./bjack p_score=11, p_numofcards=2 d_score=6, d_numofcards=2 p_hand[0].card=0, p_hand[0].suit=0, p_hand[0].value=0 d_hand[0].card=0, d_hand[0].suit=134513052, d_hand[0].value=24641422 p_hand[1].card=0, p_hand[1].suit=0, p_hand[1].value=0 d_hand[1].card=0, d_hand[1].suit=134513052, d_hand[1].value=24641422 Last edited by Tommo; 06-14-2007 at 01:32 PM. |
| Tommo is offline | |
| | #2 |
| and the hat of Jobseeking Join Date: Aug 2001 Location: The edge of the known universe
Posts: 21,680
| > k,p_hand[i].card, Maybe k,p_hand[k].card, Also, you need to introduce the idea of a "deck" of cards, which is initially "shuffled" into random order, then "dealt" one card at a time to each player. Your technique could easily have both players having the same cards. |
| Salem is offline | |
| | #3 |
| Registered User Join Date: Jun 2007 Location: Scotland
Posts: 101
| Haha what a ignoramus I am. Thanks for that Regarding the deck of cards, you're right, it slipped my mind. Should I make an array of size 52, then mark each one null when it has been dealt? Seems kind of resource intensive, what would be a better way? |
| Tommo is offline | |
| | #4 |
| Frequently Quite Prolix Join Date: Apr 2005 Location: Canada
Posts: 7,698
| Why not just start with every card, swap random cards a few times until all the cards are shuffled, and then take the top card off of the stack? Then you could set that card to NULL and take the next one, etc. This method wouldn't use too much CPU time, except for during initialization.
__________________ dwk Seek and ye shall find. quaere et invenies. "Simplicity does not precede complexity, but follows it." -- Alan Perlis "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra "The only real mistake is the one from which we learn nothing." -- John Powell Other boards: DaniWeb, TPS Unofficial Wiki FAQ: cpwiki.sf.net My website: http://dwks.theprogrammingsite.com/ Projects: codeform, xuni, atlantis, nort, etc. |
| dwks is offline | |
| | #5 |
| Math wizard Join Date: Dec 2006 Location: Minot, ND, USA
Posts: 521
| An array of 52 flags is one method (having "char cards[52]"), but it would require checking the array for unused cards and if used, the randomization is rerun. Using a card number from 1 to 52 in an array of 52 with each randomized is another method. Used cards would be zeros in the deck, unused cards (cards still in the deck) would be 1's in the flag method and the card number using the card number method. For determining the card number, come up with a pattern. I use A to K for 1 to 13 then clubs, diamonds, heats, then spades, for the groups of 13 (note that they are in numerical then alphabetical order). These are just some tips though. There's other ways available.
__________________ High elevation is the best elevation. The higher, the better the view! My computer: XP Pro SP3, 3.17 GHz C2D CPU, 4 GB DDRII800 RAM (3 GB effective), X-Fi Platinum sound, GeForce 7600 GT, 1920x1440 resolution, 250 GB HDD, Visual C++ 2008 Express |
| ulillillia is offline | |
| | #6 |
| Woof, woof! Join Date: Mar 2007 Location: Australia
Posts: 3,295
| If you don't want it so 'resource intensive' then use a bitset perhaps? (Or a few bitsets...) You'd need ~7 bytes to store the flags... (52 / 8, 8 bits to a byte) |
| zacs7 is offline | |
| | #7 |
| Registered User Join Date: Jun 2007 Location: Scotland
Posts: 101
| This is actually my second attempt at it, I made a meal of the first one. I actually made provisions for two of the same card being dealt, don't know why it slipped my mind this time. What I did was generate a random card, then see if it was already the the players' hand. If it was, I would generate another one. So something like: Code: while( card has already been dealt ) {
generate_card();
}
Thanks. |
| Tommo is offline | |
| | #8 |
| Registered User Join Date: Jun 2007 Location: Scotland
Posts: 101
| Hi, I have decided to redo it, the way dwks stated. But I'm getting strange output. Basically I have created a deck of cards and have shuffled them. It all seems fine. Then I created a cardtostring function to output '5 of spades' for example. But when testing the function, it produces strange output. Can someone please back me up on this: Code: #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define NUMOFCARDS 52
typedef struct {
int card;
int suit;
int value;
} card_t;
int randy(void);
void swapcards(card_t *c1, card_t *c2);
int value(int a);
void cardtostring(card_t crd, char *str);
int main(void) {
srand((unsigned int)time(NULL));
card_t deck[NUMOFCARDS];
/*this intialises the deck giving each card its attributes*/
int i,k,index;
for(i=0;i<4;i++) {
for(k=0;k<13;k++) {
index = (i*13) + k;
deck[index].card = k+1;
deck[index].suit = i+1;
deck[index].value = value(k+1);
}
}
int h=0;
int j;
while(h < 26) { /*loop 26 times swapping a card from the first 26 with a random one from the last 26*/
j = randy();
swapcards(&deck[h],&deck[j]);
h++;
}
/* this is for testing what card is where in the deck after i shuffled them
int p;
for(p=0;p<52;p++) {
printf("Card % d: (card:%d,suit:%d,value:%d)\n",p+1,deck[p].card,deck[p].suit,deck[p].value);
}
*/
/* something is wrong here. this generates output to test the cardtostring function */
char st[30];
int l;
for(l=0;l<52;l++) {
cardtostring(deck[l], st);
printf("The %dth card on the deck is: %s\n",l+1, st);
strcpy(st,"");
}
return 0;
}
int randy(void) {
/* gen random number between 26 and 52 */
return (rand() % (52-26+1))+ 26;
}
void swapcards(card_t *c1, card_t *c2) { /* function to swap two given cards in the deck */
card_t temp;
temp = *c1;
*c1 = *c2;
*c2 = temp;
}
int value(int a) { /* value of card ace=1,jack=10,king=10 etc (will deal with ace=11 later*/
if(a > 0 && a < 11)
return a;
else
return 10;
}
void cardtostring(card_t crd, char *str) {
/*try to create a string of the form "4 of spades" */
if(crd.card > 1 && crd.card < 11) { /* between 2 and 10 then add it to the string */
sprintf(str,"%d",crd.card);
}
switch(crd.card) { /*here add ace for 1, jack for 11 etc */
case 1:
strcat(str, "Ace");
break;
case 11:
strcat(str, "Jack");
break;
case 12:
strcat(str, "Queen");
break;
case 13:
strcat(str, "King");
break;
}
strcat(str, " of "); /* the of part in '4 of hearts' */
switch(crd.suit) {
case 1:
strcat(str, "spades");
break;
case 2:
strcat(str, "clubs");
break;
case 3:
strcat(str, "hearts");
break;
case 4:
strcat(str, "diamonds");
}
}
|
| Tommo is offline | |
| | #9 |
| Frequently Quite Prolix Join Date: Apr 2005 Location: Canada
Posts: 7,698
| It sounds like none of these case statements are executing: Code: switch(crd.suit) {
case 1:
strcat(str, "spades");
break;
case 2:
strcat(str, "clubs");
break;
case 3:
strcat(str, "hearts");
break;
case 4:
strcat(str, "diamonds");
}
Rather than using the numeric literal "52" in your program, you should probably be using NUMOFCARDS, and NUMCARDS/2 instead of 26. Just a thought. Code: int h=0;
int j;
while(h < 26) { /*loop 26 times swapping a card from the first 26 with a random one from the last 26*/
j = randy();
swapcards(&deck[h],&deck[j]);
h++;
}
Code: int x;
for(x = 0; x < NUMCARDS * 10; x ++) {
swapcards(&deck[rand() % NUMCARDS], &deck[rand() % NUMCARDS]);
}
__________________ dwk Seek and ye shall find. quaere et invenies. "Simplicity does not precede complexity, but follows it." -- Alan Perlis "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra "The only real mistake is the one from which we learn nothing." -- John Powell Other boards: DaniWeb, TPS Unofficial Wiki FAQ: cpwiki.sf.net My website: http://dwks.theprogrammingsite.com/ Projects: codeform, xuni, atlantis, nort, etc. |
| dwks is offline | |
| | #10 |
| Registered User Join Date: Jun 2007 Location: Scotland
Posts: 101
| No the case statements are executing. It is just the odd '4 of <space>' that crops up for no apparent reason. Well no reason that I can see, although there must be one. Here is the output: Code: The 1th card on the deck is: Ace of hearts The 2th card on the deck is: 9 of hearts The 3th card on the deck is: Ace of diamonds The 4th card on the deck is: King of hearts The 5th card on the deck is: 2 of hearts The 6th card on the deck is: 7 of hearts The 7th card on the deck is: 5 of spades The 8th card on the deck is: 3 of spades The 9th card on the deck is: Jack of diamonds The 10th card on the deck is: 4 of The 11th card on the deck is: Ace of spades The 12th card on the deck is: 3 of diamonds The 13th card on the deck is: 7 of spades The 14th card on the deck is: King of spades The 15th card on the deck is: Queen of diamonds The 16th card on the deck is: Ace of clubs The 17th card on the deck is: Queen of hearts The 18th card on the deck is: 5 of hearts The 19th card on the deck is: 7 of diamonds The 20th card on the deck is: 3 of clubs The 21th card on the deck is: 6 of spades The 22th card on the deck is: Jack of hearts The 23th card on the deck is: 7 of clubs The 24th card on the deck is: 10 of spades The 25th card on the deck is: 4 of diamonds The 26th card on the deck is: 4 of spades The 27th card on the deck is: Jack of spades The 28th card on the deck is: 10 of clubs The 29th card on the deck is: 3 of hearts The 30th card on the deck is: 4 of hearts The 31th card on the deck is: 5 of clubs The 32th card on the deck is: 6 of hearts The 33th card on the deck is: 8 of clubs The 34th card on the deck is: 8 of hearts The 35th card on the deck is: 2 of spades The 36th card on the deck is: 10 of hearts The 37th card on the deck is: 9 of clubs The 38th card on the deck is: 4 of clubs The 39th card on the deck is: King of clubs The 40th card on the deck is: 8 of spades The 41th card on the deck is: 2 of diamonds The 42th card on the deck is: Queen of spades The 43th card on the deck is: Queen of clubs The 44th card on the deck is: 5 of diamonds The 45th card on the deck is: 6 of diamonds The 46th card on the deck is: 6 of clubs The 47th card on the deck is: 8 of diamonds The 48th card on the deck is: 9 of diamonds The 49th card on the deck is: 10 of diamonds The 50th card on the deck is: 9 of spades The 51th card on the deck is: 2 of clubs The 52th card on the deck is: King of diamonds Regarding the shuffle, you're right, I will give it a thorough shuffle. And yes, I should be using NUMOFCARDS, I was anxious to test it and it just slipped my mind. Thanks |
| Tommo is offline | |
| | #11 |
| Frequently Quite Prolix Join Date: Apr 2005 Location: Canada
Posts: 7,698
| I'll elaborate on "none of the case statements are executing". Code: switch(crd.suit) {
case 1:
strcat(str, "spades");
break;
case 2:
strcat(str, "clubs");
break;
case 3:
strcat(str, "hearts");
break;
case 4:
strcat(str, "diamonds");
}
}
Code: switch(crd.suit) {
case 1:
strcat(str, "spades");
break;
case 2:
strcat(str, "clubs");
break;
case 3:
strcat(str, "hearts");
break;
case 4:
strcat(str, "diamonds");
break;
default:
strcat(str, "*error*");
}
}
Code: The 10th card on the deck is: 4 of *error* So, for the 10th card, the suit is not 1, 2, 3, or 4. If you look closely, you'll see that there are already four cards, on of each suit, that have the value 4. So, the 4 in the 10th card is messed up as well. The whole card is probably invalid. Careful examination shows that there are only three Aces, and so the tenth card should be the Ace of Spades. This is the very first card since spades are represented as 1 in your program. But wait . . . there are only three Jacks as well. So it's not just the first card that's not being initialized properly. So there's probably something wrong with this code: Code: int i,k,index;
for(i=0;i<4;i++) {
for(k=0;k<13;k++) {
index = (i*13) + k;
deck[index].card = k+1;
deck[index].suit = i+1;
deck[index].value = value(k+1);
}
}
Code: index = (i*4) + k;
__________________ dwk Seek and ye shall find. quaere et invenies. "Simplicity does not precede complexity, but follows it." -- Alan Perlis "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra "The only real mistake is the one from which we learn nothing." -- John Powell Other boards: DaniWeb, TPS Unofficial Wiki FAQ: cpwiki.sf.net My website: http://dwks.theprogrammingsite.com/ Projects: codeform, xuni, atlantis, nort, etc. |
| dwks is offline | |
![]() |
| Thread Tools | |
| Display Modes | |
|
Similar Threads | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Simple Blackjack Program | saber1357 | C Programming | 1 | 03-28-2009 03:19 PM |
| Help with Blackjack program | sugie | C++ Programming | 1 | 04-30-2005 12:30 AM |
| Blackjack! | Dr. Bebop | Game Programming | 1 | 10-03-2002 08:58 PM |
| Blackjack | the_head | C Programming | 1 | 08-03-2002 08:57 AM |
| BlackJack Program... | 67stangman | C++ Programming | 3 | 05-06-2002 10:44 PM |