poker.c (16537B)
1 /* Exercise 7.14 */ 2 3 /* Fig. 7.24: fig07_24.c 4 Card shuffling dealing program */ 5 #include <stdio.h> 6 #include <stdlib.h> 7 #include <time.h> 8 9 #define CARDS 5 10 #define DECK 26 11 #define PLAYERS 2 12 13 /* Points setting * 14 * NOTE: the points *must* have an offset >= 15 and P_PAIR 15 * must should be >= 15 too to works properly. Else, 16 * Else, the game will sh0w only INVALID results and 17 * wrong winners. 18 */ 19 #define OFFSET 15 20 21 /* I'll tweak these, maybe.. a day :-) */ 22 #define P_PAIR OFFSET 23 #define P_DOUBLE P_PAIR + OFFSET 24 #define P_TRIS P_DOUBLE + OFFSET 25 #define P_SCALE P_TRIS + OFFSET 26 #define P_FULL P_SCALE + OFFSET 27 #define P_POKER P_FULL + OFFSET 28 #define P_COLOR P_POKER + OFFSET 29 #define P_SFLUSH P_COLOR + OFFSET 30 #define P_RFLUSH P_SFLUSH + OFFSET 31 32 /* prototypes */ 33 void shuffle( int wDeck[][ 13 ] ); 34 35 void deal( int wDeck[][ 13 ], const char *wFace[], const char *wSuit[], 36 int cards[][CARDS][2], int player, int wCards, int show); 37 38 int getp(int cards[][CARDS][2], int player, const char *wFace[], 39 const char *wSuit[], int n_cards, int *r_suit, int type[]); 40 41 void order(int a[][CARDS][2], int p, int size); 42 void rswap(int *a, int *b); 43 44 int chcs(int cards[][CARDS][2], int player, int type[], const char *wFace[], 45 const char *wSuit[], int wDeck[][13], int n_cards); 46 47 int main(void) 48 { 49 int i, type[1 + PLAYERS], winner[3] = { 0 }, points[1 + PLAYERS] = { 0 }; 50 int p[1 + PLAYERS][2] = { { 0 } }; 51 int cards[1 + PLAYERS][CARDS][2] = { { { 0 } } }; 52 53 /* initialize suit array */ 54 const char *suit[ 4 ] = { "Hearts", "Diamonds", "Clubs", "Spades" }; 55 56 /* initialize face array */ 57 const char *face[ 13 ] = 58 { "Ace", "Deuce", "Three", "Four", 59 "Five", "Six", "Seven", "Eight", 60 "Nine", "Ten", "Jack", "Queen", "King" }; 61 62 /* initialize deck array */ 63 int deck[ 4 ][ 13 ] = { { 0 } }; 64 65 srand( time( 0 ) ); /* seed random-number generator */ 66 67 shuffle( deck ); 68 69 /* S t a r t */ 70 printf("GaMe STaRTeD!\n\n"); 71 printf("Deck: %d\nCards for player: %d\nNumber of players: %d\n\n\n", 72 DECK, CARDS, PLAYERS); 73 74 for(i = 0; i < PLAYERS + 1; i++) { 75 if(!i) 76 printf("*** Computer is playing..\n"); 77 else 78 printf("*** Player %d is playing..\n", i); 79 80 printf("-----------------------------------------\n"); 81 deal( deck, face, suit, cards, i, CARDS, !i ? i : 1); 82 83 printf("\n\n"); 84 85 /* p[i][0] == points 86 * p[i][1] == suit of highest card (whitin the highest kind) 87 * i == the player 88 * p[0][?] == the computer 89 */ 90 p[i][0] = getp(cards, i, face, suit, CARDS, &p[i][1], type); 91 92 printf("\nScore: %d ", p[i][0]); 93 if(i) printf("(suit points reserved: %d)", 4 - p[i][1]); 94 95 printf("\n"); 96 printf("-----------------------------------------\n"); 97 98 /* so */ 99 points[i] = p[i][0] - p[i][1]; /* points - seed(0 highest, 3 lowest) */ 100 printf("\n\n"); 101 } 102 103 /* Changes */ 104 105 /* Change the cards, if needed */ 106 if( chcs(cards, 0, type, face, suit, deck, CARDS) ) { 107 /* If cards are changed */ 108 p[0][0] = getp(cards, 0, face, suit, CARDS, &p[0][1], type); 109 printf("\n"); 110 } 111 112 /* F i n i s h */ 113 114 /* Check the winner and print the classifies */ 115 for(i = 0; i < PLAYERS + 1; i++) { 116 if(p[i][0] > winner[0]) { 117 winner[0] = p[i][0]; 118 winner[1] = p[i][1]; 119 winner[3] = i; 120 } 121 else if(p[i][0] == winner[0]) { /* Pair: check the suit */ 122 if(p[i][1] < winner[1]) { 123 winner[0] = p[i][0]; 124 winner[1] = p[i][1]; 125 winner[3] = i; 126 } 127 } 128 } /* end for (i) */ 129 130 printf("\n\tC l a s s i f i e s\n\n"); 131 printf("%16s%9s\n", "Player", "Points"); 132 printf("%16s%9d\n", "PC", p[0][0]); 133 for(i = 1; i < PLAYERS + 1; i++) { 134 printf("%16d%9d\n", i, p[i][0]); 135 } 136 printf("\n"); 137 138 if(!winner[3]) 139 printf("* Computer won with %d points.\n", winner[0]); 140 else 141 printf("* Player %d won with %d points.\n", winner[3], winner[0]); 142 143 printf("\n"); 144 return 0; /* indicates successful termination */ 145 146 } /* end main */ 147 148 /* shuffle cards in deck */ 149 void shuffle( int wDeck[][ 13 ] ) 150 { 151 int row; /* row number */ 152 int column; /* column number */ 153 int card; /* counter */ 154 155 /* for each of the 52 cards, choose slot of deck randomly */ 156 for ( card = 1; card <= DECK; card++ ) { 157 158 /* choose new random location until unoccupied slot found */ 159 do { 160 row = rand() % 4; 161 column = rand() % 13; 162 } while( wDeck[ row ][ column ] != 0 ); /* end do...while */ 163 164 /* place card number in chosen slot of deck */ 165 wDeck[ row ][ column ] = card; 166 } /* end for */ 167 168 } /* end function shuffle */ 169 170 /* deal cards in deck */ 171 void deal( int wDeck[][ 13 ], const char *wFace[], const char *wSuit[], 172 int cards[][CARDS][2], int player, int wCards, int show) 173 { 174 int card; /* card counter */ 175 int row; /* row counter */ 176 int column; /* column counter */ 177 int i = 0; 178 179 if(show == 2) 180 printf("==> Computer is changing cards..\n\n"); 181 182 /* deal each of the 52 cards */ 183 for ( card = 1; card <= DECK; card++ ) { 184 /* loop through rows of wDeck */ 185 for ( row = 0; row <= 3; row++ ) { 186 187 /* loop through columns of wDeck for current row */ 188 for ( column = 0; column <= 12; column++ ) { 189 /* if slot contains current card, display card */ 190 if ( wDeck[ row ][ column ] == card ) { 191 192 if(show == 2) 193 printf( "%5s of %-8s => ", wFace[cards[player][i][0]], 194 wSuit[cards[player][i][1]]); 195 196 cards[player][i][0] = column; 197 cards[player][i][1] = row; 198 199 if(!show) 200 printf("%15s", " HIDDEN "); 201 else 202 printf( "%5s of %-8s", wFace[ column ], wSuit[ row ]); 203 204 ++i; 205 206 if(show != 2) printf("%c", !(card % 2) ? '\n' : '\t'); 207 else printf("\n"); 208 209 wDeck[row][column] = 0; 210 211 /* dealing only "wCards" cards */ 212 if(i == wCards) { 213 printf("\n"); 214 return; 215 } 216 217 } /* end if */ 218 219 } /* end for */ 220 221 } /* end for */ 222 223 } /* end for */ 224 225 } /* end function deal */ 226 227 /* Get the points of a player */ 228 int getp(int cards[][CARDS][2], int player, const char *wFace[], 229 const char *wSuit[], int n_cards, int *r_suit, int type[]) 230 { 231 int i, points; 232 int scale = 0, n; 233 int o[13][2] = { { 0 } }; /* occurrences */ 234 235 236 int kind = 0, face, suit; 237 /* 0 = nothing 238 * 1 = Pair 239 * 2 = Double 240 * 3 = Tris 241 * 4 = scale 242 * 5 = Full 243 * 6 = Poker 244 * 7 = Color 245 * 8 = straight flush 246 * 9 = royal flush 247 */ 248 249 /* Inizitialize the o[0,12][1] to 4. Note that 4 is 250 * a value (random) greather then highest suit (3). */ 251 for(i = 0; i < 13; i++) 252 o[i][1] = 4; 253 254 /* count the occurrences of each card's face and 255 * save to the current index the highest suit */ 256 for(i = 0; i < n_cards; i++) { 257 ++o[cards[player][i][0]][0]; 258 259 /* store the index of the highest suit */ 260 if(o[cards[player][i][0]][1] > cards[player][i][1]) 261 o[cards[player][i][0]][1] = cards[player][i][1]; 262 263 } 264 265 /* Ok, now don't forget this: 266 * 267 * o[i][0] == the occurrences 268 * o[i][1] == the suit 269 * i == the face 270 */ 271 272 /* check if there is a pair/double/tris/full/poker */ 273 for(i = 0; i < 13; i++) { 274 switch(o[i][0]) { 275 case 2: 276 /* if this is the 1st pair */ 277 if(!kind) /* is a pair */ 278 kind = 1; 279 280 /* else could be a double */ 281 else if(kind == 1) 282 kind = 2; 283 284 else /* else is full */ 285 kind = 3; 286 287 break; 288 case 3: 289 /* If is the current game is a pair */ 290 if(kind == 1) 291 kind = 5; /* then become "full" */ 292 293 else /* else is tris */ 294 kind = 3; 295 296 break; 297 case 4: 298 /* Oh, this is Poker! :-) */ 299 kind = 6; 300 break; 301 default: 302 /* !o[i][0] */ 303 ; 304 305 } /* end switch (o[i]) */ 306 307 if( o[i][0] > 1 && (kind != 2 || (kind == 2 && face < i)) ) { 308 /* If is double and the current pair is not greather 309 * then previous, then i don't store its face/suit */ 310 311 face = i; 312 suit = o[i][1]; 313 } 314 315 } /* end for (i) */ 316 317 318 /* Here i've checked: pair, double, tris, full and poker. 319 * "face" and "suit" contains the highest value of the current 320 * "kind". The suit is required if there are an "equal" result 321 * for change (increment or decrement) the current value of 322 * each one basing on the suit. 323 * Missing: scale, color and "all cards are not equals". */ 324 325 326 /* if all cards are different store the highest of these */ 327 if(kind == 0 && !scale) { 328 for(i = 0, face = -1; i < n_cards; i++) { 329 330 /* search the highest */ 331 if((!face ? 13 : face) < (!cards[player][i][0] ? 13 : 332 cards[player][i][0]) ) { 333 face = cards[player][i][0]; 334 suit = cards[player][i][1]; 335 } 336 337 /* if are equal, store the suit */ 338 else if(face == cards[player][i][0]) { 339 if(suit < cards[player][i][1]) { 340 suit = cards[player][i][1]; 341 } 342 } 343 344 } 345 } 346 347 /* check the color */ 348 for(i = 0, n = 4; i < n_cards; i++) { 349 if(! (n == 4) ) { 350 if(cards[player][i][1] != n) 351 n = - 1; 352 } 353 else 354 n = cards[player][i][1]; 355 } 356 if(n != -1) /* live enjoy: life's colored :-) */ 357 kind = 7; 358 359 /* check the scale / *_flush */ 360 order(cards, player, n_cards); 361 362 for(i = n = 1; i < n_cards; i++) { 363 if(cards[i - 1][0] + 1 != cards[i][0]) { 364 n = 0; 365 break; 366 } 367 } 368 if(n) { /* This is scale / *_flush */ 369 370 if(kind == 7) { /* *_flush */ 371 if(face == 0) { /* royal flush */ 372 kind = 9; 373 } 374 375 else { /* straight flush */ 376 kind = 8; 377 } 378 } 379 else { /* just scale */ 380 kind = 4; 381 } 382 } 383 384 *r_suit = suit; 385 type[player] = kind; 386 387 /* Print the kind of game and assign the points */ 388 switch(kind) { 389 case 0: /* Nothing */ 390 printf("All cards are differents!\n" 391 "You could win with the %s of %s\n", 392 wFace[face], wSuit[suit]); 393 394 points = face; 395 break; 396 case 1: /* Pair */ 397 printf("Oh, it is a pair of %ss!\n", wFace[face]); 398 399 points = P_PAIR + face; 400 break; 401 case 2: /* Double */ 402 printf("Double to %ss\n", wFace[face]); 403 404 points = P_DOUBLE + face; 405 break; 406 case 3: /* Tris */ 407 printf("This is tris of %ss!\n", wFace[face]); 408 409 points = P_TRIS + face; 410 break; 411 case 4: /* Scale */ 412 printf("Yeah, you have done a scale to %s\n", wFace[face]); 413 414 points = P_SCALE + face; 415 break; 416 case 5: /* Full */ 417 printf("*** FULL of %ss!\n", wFace[face]); 418 419 points = P_FULL + face; 420 break; 421 case 6: /* Poker */ 422 printf("Wow, it's Poker of %ss!\n", wFace[face]); 423 424 points = P_POKER + face; 425 break; 426 case 7: /* Color */ 427 printf("%d points of color (%s)\n", P_COLOR, wSuit[suit]); 428 429 points = P_COLOR + face; 430 break; 431 case 8: /* Straight flush */ 432 printf("* Straight flush to %s*\n", wFace[face]); 433 434 points = P_SFLUSH + face; 435 break; 436 case 9: /* Royal flush */ 437 printf("*| Royal Flush (%s) |*\n", wSuit[suit]); 438 439 points = P_RFLUSH + face; 440 break; 441 default: /* (?) */ 442 printf("### error in function getp()\n"); 443 exit(-1); 444 445 } /* end switch(kind) */ 446 447 if(!face) points += 13; /* add the Ace's points */ 448 449 return points + 1; /* + 1 == [1,13] rather then [0,12] */ 450 } /* eof getp() */ 451 452 /* Order an array in descending mode */ 453 void order(int a[][CARDS][2], int p, int size) 454 { 455 int i, hold; 456 457 for(i = 1; i < size; i++) { 458 if(a[p][i - 1][0] > a[p][i][0]) { 459 /* swap the face */ 460 hold = a[p][i][0]; 461 a[p][i][0] = a[p][i - 1][0]; 462 a[p][i - 1][0] = hold; 463 464 /* swap the suit */ 465 hold = a[p][i][1]; 466 a[p][i][1] = a[p][i - 1][1]; 467 a[p][i - 1][1] = hold; 468 } 469 } /* end for (i) */ 470 471 } /* eof order() */ 472 473 /* Change the cards if needed, else return 0 */ 474 int chcs(int cards[][CARDS][2], int player, int type[], const char *wFace[], 475 const char *wSuit[], int wDeck[][13], int n_cards) 476 { 477 int i, ret; 478 479 switch(type[player]) { 480 case 9: /* Royal flush */ 481 case 8: /* Straight flush */ 482 483 ret = 0; 484 break; 485 case 7: /* Color */ 486 /* Try to do a Royal flush */ 487 ret = 0; 488 489 for(i = 0; i < n_cards; i++) { 490 if(cards[player][i][0] + 1 == cards[player][i + 1][0]) { 491 ++ret; 492 } 493 } 494 495 /* if miss only a card to Royal Flush */ 496 if(ret == 3) { 497 /* risk: change one card */ 498 499 if(cards[player][0][0] + 1 == cards[player][1][0]) { 500 rswap(&cards[player][0][0], &cards[player][n_cards - 1][0]); 501 rswap(&cards[player][0][1], &cards[player][n_cards - 1][1]); 502 } 503 504 ret = 1; 505 } 506 else /* do nothing */ 507 ret = 0; 508 509 break; 510 511 case 5: /* Full */ 512 case 4: /* Scale */ 513 514 /* Stay */ 515 ret = 0; 516 517 break; 518 519 case 6: /* Poker */ 520 521 /* cards is ordered so the "intruder" 522 * have to be at begin or at end */ 523 524 if(cards[n_cards - 1][0] != cards[2][0]) { 525 526 /* copy [0] to [n_cards - 1] */ 527 528 /* the face */ 529 rswap(&cards[player][n_cards - 1][0], &cards[player][0][0]); 530 531 /* the suit */ 532 rswap(&cards[player][n_cards - 1][1], &cards[player][0][1]); 533 } 534 535 /* else cards[player][n_cards - 1][0] <=> cards[player][2][0] */ 536 537 /* and insert a new card on [0] */ 538 deal( wDeck, wFace, wSuit, cards, player, 1, 2); 539 540 ret = 1; 541 break; 542 case 2: /* Double */ 543 /* change 1 card */ 544 545 /* cards is ordered so the "intruder" 546 * have to be at begin or at end */ 547 548 if(cards[player][n_cards - 1][0] != cards[player][5][1] && 549 cards[player][n_cards - 1][0] != cards[player][3][0]) { 550 551 /* the face */ 552 rswap(&cards[player][n_cards - 1][0], &cards[player][0][0]); 553 554 /* the suit */ 555 rswap(&cards[player][n_cards - 1][1], &cards[player][0][1]); 556 } 557 558 /* else cards[0][0] is already free */ 559 deal( wDeck, wFace, wSuit, cards, player, 1, 2); 560 561 ret = 1; 562 break; 563 case 3: /* Tris */ 564 /* change 2 cards */ 565 566 /* cards is ordered so the "intruderS" 567 * DON'T have to be at middle */ 568 569 for(i = 0; i < n_cards / 2; i++) { 570 if(cards[i][0] == cards[2][0]) 571 break; 572 } 573 574 if(!i) { 575 /* the face */ 576 rswap(&cards[player][n_cards - 1][0], &cards[player][0][0]); 577 rswap(&cards[player][n_cards - 2][0], &cards[player][1][0]); 578 579 /* the suit */ 580 rswap(&cards[player][n_cards - 1][1], &cards[player][0][1]); 581 rswap(&cards[player][n_cards - 2][1], &cards[player][1][1]); 582 } 583 else if(i == 1) { 584 /* the face */ 585 rswap(&cards[player][n_cards - 1][0], &cards[player][2][0]); 586 587 /* the suit */ 588 rswap(&cards[player][n_cards - 1][1], &cards[player][2][1]); 589 } 590 591 /* insert 2 cards on [0] and [1] */ 592 deal( wDeck, wFace, wSuit, cards, player, 2, 2); 593 594 ret = 2; 595 break; 596 case 1: /* Pair */ 597 /* change 3 cards */ 598 599 for(i = 0; i < n_cards; i++) { 600 if(cards[player][i][0] == cards[player][i + 1][0]) 601 break; 602 } 603 604 605 /* The face */ 606 rswap(&cards[player][n_cards - 1][0], &cards[player][i][0]); 607 rswap(&cards[player][n_cards - 2][0], &cards[player][i+1][0]); 608 609 /* The suit */ 610 rswap(&cards[player][n_cards - 1][1], &cards[player][i][1]); 611 rswap(&cards[player][n_cards - 2][1], &cards[player][i+1][1]); 612 613 deal( wDeck, wFace, wSuit, cards, player, 3, 2); 614 615 ret = 3; 616 break; 617 case 0: /* Nothing */ 618 /* Change all cards */ 619 ret = 0; 620 621 /* If i have a Jack, a Queen, a King or an Ace, hold it */ 622 for(i = 0; i < n_cards; i++) { 623 /* 9 == Ten */ 624 if( (!cards[player][i][0] ? 13 : cards[player][i][0]) > 9 && 625 (!cards[player][i][0] ? 13 : cards[player][i][0]) > ret) { 626 ret = (!cards[player][i][0] ? 13 : cards[player][i][0]); 627 628 rswap(&cards[player][0][0], &cards[player][i][0]); 629 rswap(&cards[player][0][1], &cards[player][i][1]); 630 } 631 } 632 rswap(&cards[player][0][0], &cards[player][n_cards - 1][0]); 633 rswap(&cards[player][0][1], &cards[player][n_cards - 1][1]); 634 635 /* else change all cards */ 636 637 if(!ret) { 638 deal( wDeck, wFace, wSuit, cards, player, n_cards, 2); 639 ret = n_cards; 640 } 641 else { 642 deal( wDeck, wFace, wSuit, cards, player, n_cards - 1, 2); 643 ret = n_cards - 1; 644 } 645 646 break; 647 default: /* (?) */ 648 printf("### error in function chcs()\n"); 649 exit(-1); 650 651 } /* end switch (type[player]) */ 652 653 654 if(ret) 655 printf("Computer has changed %d %s.\n\n", 656 ret, ret > 1 ? "cards" : "card" ); 657 658 return ret; 659 } /* eof chcs() */ 660 661 /* Swap two variable for reference */ 662 void rswap(int *a, int *b) 663 { 664 int hold; 665 666 hold = *a; 667 *a = *b; 668 *b = hold; 669 } /* eof rswap() */ 670