Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <ctype.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <time.h>
- typedef struct {
- int suit;
- int number;
- char *display;
- } card_t;
- static const int suit = 4;
- static const int number = 13;
- static void shuffle(card_t **cards);
- static card_t **init(const char **suits, const char **numbers);
- static int input_number(int lower, int upper);
- static int ask_players(void);
- static card_t ***deal_to(card_t **cards, int player);
- static void sort(card_t ***players, int player);
- static void compact_one_card(card_t **some_player, int player);
- static void first_play_seven(card_t ***players, int player);
- static int count_card(card_t **some_player, int player);
- static int **init_open(void);
- static void puts_open_card(int **open, const char **suits, const char **numbers);
- static int win(card_t **some_player, int player);
- static void win_first_hand(card_t ***players, int player);
- static void puts_hand(int no, card_t **some_player, int player);
- static int can_put(card_t *card, int **open);
- static int pass_or_not(card_t **some_player, int player, int **open);
- static void play(card_t **some_player, int in, int player, int **open);
- static void choice(int no, card_t **some_player, int player, int **open);
- int main(void);
- static void shuffle(card_t **cards) {
- int i, j;
- card_t *p;
- srand((unsigned) time(NULL));
- for (i = suit * number - 1; i > 0; i--) {
- j = (int) (rand() / ((double) (RAND_MAX) + 1.) * (i + 1));
- p = cards[i];
- cards[i] = cards[j];
- cards[j] = p;
- }
- }
- static card_t **init(const char **suits, const char **numbers) {
- int i, j, k;
- card_t **cards = (card_t **) malloc(suit * number * sizeof(card_t *));
- for (i = 0; i < suit; i++) {
- for (j = 0; j < number; j++) {
- k = i * number + j;
- cards[k] = (card_t *) malloc(sizeof(card_t));
- cards[k]->suit = i;
- cards[k]->number = j;
- cards[k]->display = (char *) malloc((strlen(suits[i]) + 2 + 1) * sizeof(char));
- sprintf(cards[k]->display, "%s%s", suits[i], numbers[j]);
- }
- }
- shuffle(cards);
- return cards;
- }
- static int input_number(int lower, int upper) {
- char in[BUFSIZ];
- int i, ret;
- while (1) {
- printf("(%d - %d): ", lower, upper);
- fgets(in, BUFSIZ, stdin);
- in[strlen(in) - 1] = '\0';
- for (i = 0; i < strlen(in); i++)
- if (!isdigit(in[i])) goto clear;
- ret = atoi(in);
- if (ret < lower || upper < ret) goto clear;
- break;
- clear: ;
- }
- return ret;
- }
- static int ask_players(void) {
- printf("Players? ");
- return input_number(1, 52);
- }
- static card_t ***deal_to(card_t **cards, int player) {
- int i, j;
- card_t ***players = (card_t ***) malloc(player * sizeof(card_t **));
- for (i = 0; i < player; i++) {
- players[i] = (card_t **) malloc((suit * number / player + 1) * sizeof(card_t *));
- for (j = 0; j < suit * number / player + 1; j++) {
- players[i][j] = NULL;
- }
- }
- for (i = 0, j = 0; i < suit * number; i++, j++) {
- players[j % player][i / player] = cards[i];
- }
- return players;
- }
- static void sort(card_t ***players, int player) {
- int i, j, k, c;
- card_t *p;
- for (i = 0; i < player; i++) {
- c = count_card(players[i], player);
- for (j = 1; j < c; j++) {
- p = players[i][j];
- for (k = j - 1; k >= 0 && players[i][k]->number > p->number; k--)
- players[i][k + 1] = players[i][k];
- players[i][k + 1] = p;
- }
- for (j = 1; j < c; j++) {
- p = players[i][j];
- for (k = j - 1; k >= 0 && players[i][k]->suit > p->suit; k--)
- players[i][k + 1] = players[i][k];
- players[i][k + 1] = p;
- }
- }
- }
- static void compact_one_card(card_t **some_player, int player) {
- int i;
- for (i = 0; i < suit * number / player; i++) {
- if (some_player[i]) continue;
- some_player[i] = some_player[i + 1];
- some_player[i + 1] = NULL;
- }
- }
- static void first_play_seven(card_t ***players, int player) {
- int i, j;
- for (i = 0; i < player; i++) {
- for (j = 0; j < suit * number / player + 1; j++) {
- if (!players[i][j]) break;
- if (players[i][j]->number == 7 - 1) {
- players[i][j] = NULL;
- compact_one_card(players[i], player);
- j--;
- }
- }
- }
- }
- static int count_card(card_t **some_player, int player) {
- int i, c = 0;
- for (i = 0; i < suit * number / player + 1; i++) {
- if (!some_player[i]) break;
- c++;
- }
- return c;
- }
- static int **init_open(void) {
- int i, j;
- int **open = (int **) malloc(suit * sizeof(int *));
- for (i = 0; i < suit; i++) {
- open[i] = (int *) malloc(number * sizeof(int));
- for (j = 0; j < number; j++) {
- if (j != 7 - 1) {
- open[i][j] = 0;
- continue;
- }
- open[i][j] = 1;
- }
- }
- return open;
- }
- static void puts_open_card(int **open, const char **suits, const char **numbers) {
- int i, j;
- printf(" ");
- for (i = 0; i < number; i++) {
- if (i != 9) printf(" ");
- printf("%s", numbers[i]);
- }
- puts("");
- for (i = 0; i < suit; i++) {
- printf("%s ", suits[i]);
- for (j = 0; j < number; j++) {
- if (open[i][j] == 0)
- printf(" .");
- else
- printf(" #");
- }
- puts("");
- }
- }
- static int win(card_t **some_player, int player) {
- return count_card(some_player, player) == 0;
- }
- static void win_first_hand(card_t ***players, int player) {
- int i;
- for (i = 0; i < player; i++) {
- if (win(players[i], player)) {
- printf("Player %d win, becouse all hands are 7.\n", i);
- exit(0);
- }
- }
- }
- static void puts_hand(int no, card_t **some_player, int player) {
- int i, c;
- printf("Player %d: ", no);
- c = count_card(some_player, player);
- for (i = 0; i < c; i++) {
- printf("%d:[%s]", i, some_player[i]->display);
- if (i < c - 1) printf(", ");
- }
- printf(" ");
- }
- static int can_put(card_t *card, int **open) {
- int suit = card->suit, number = card->number;
- if (number == 1 - 1)
- return open[suit][2 - 1] == 1;
- else if (number == 13 - 1)
- return open[suit][12 - 1] == 1;
- else
- return open[suit][number - 1] == 1 || open[suit][number + 1] == 1;
- }
- static int pass_or_not(card_t **some_player, int player, int **open) {
- int i, c, ret = 0;
- c = count_card(some_player, player);
- for (i = 0; i < c; i++)
- ret = ret || can_put(some_player[i], open);
- return ret;
- }
- static void play(card_t **some_player, int in, int player, int **open) {
- card_t *card = some_player[in];
- open[card->suit][card->number] = 1;
- some_player[in] = NULL;
- compact_one_card(some_player, player);
- }
- static void choice(int no, card_t **some_player, int player, int **open) {
- int c, in;
- puts_hand(no, some_player, player);
- if (!pass_or_not(some_player, player, open)) {
- puts("pass");
- return;
- }
- c = count_card(some_player, player);
- do {
- in = input_number(0, c - 1);
- } while (!can_put(some_player[in], open));
- play(some_player, in, player, open);
- }
- int main(void) {
- int i;
- int player;
- card_t **cards;
- card_t ***players;
- int **open;
- const char *suits[] = { "♠", "♥", "♦", "♣" };
- const char *numbers[] = { "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K" };
- cards = init(suits, numbers);
- player = ask_players();
- players = deal_to(cards, player);
- sort(players, player);
- first_play_seven(players, player);
- if (suit * number / player <= 4) {
- win_first_hand(players, player);
- }
- open = init_open();
- do {
- for (i = 0; i < player; i++) {
- puts_open_card(open, suits, numbers);
- choice(i, players[i], player, open);
- if (win(players[i], player)) goto over;
- }
- continue;
- over: printf("Player %d win.\n", i);
- break;
- } while (1);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement