I made a one-card game, but it keeps falling into infinite loop

  Kiến thức lập trình

I’ve tried implementing a one-card game with c, but my code is that when I run about 5 times, I fall into infinite loop at least 2 times. I’ve talked to chat-gpt a lot to solve this problem, but I haven’t found an answer… Please fix it!

Below is the code I tried, please tell me the problem, the code works as intended unless it falls into an infinite loop

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

#define NUM_CARDS 52
#define NUM_SUITS 4
#define NUM_RANKS 13
#define INITIAL_HAND_SIZE 5
#define MAX_HAND_SIZE 16

typedef struct {
    char *suit;
    char *rank;
    int value;
} Card;

typedef struct {
    Card hand[MAX_HAND_SIZE];
    int handSize;
} Player;

const char *suits[] = {"Spades", "Hearts", "Clubs", "Diamonds"};
const char *ranks[] = {"2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"};

Card deck[NUM_CARDS];
Player player, computer;
Card openCard;
int deckIndex = 0;
int drawCount = 0;

// Function prototypes
void initialize_deck();
void shuffle_deck();
void deal_cards();
void print_hand(Player *p);
void take_turn(Player *current, Player *opponent, int *turn);
void play_card(Player *p, int cardIndex);
void draw_card(Player *p, int count);
int check_victory(Player *p);
int check_defeat(Player *p);
void apply_attack_card(Player *attacker, Player *defender, int attackValue);
void start_game();
int canPlayCard(Card c);
int isAttackCard(Card c);

int main() {
    srand(time(NULL));
    start_game();
    return 0;
}

void initialize_deck() {
    int k = 0;
    for (int i = 0; i < NUM_SUITS; i++) {
        for (int j = 0; j < NUM_RANKS; j++) {
            deck[k].suit = (char *)suits[i];
            deck[k].rank = (char *)ranks[j];
            deck[k].value = j + 2;
            k++;
        }
    }
    shuffle_deck();
}

void shuffle_deck() {
    for (int i = 0; i < NUM_CARDS; i++) {
        int r = i + rand() / (RAND_MAX / (NUM_CARDS - i) + 1);
        Card temp = deck[i];
        deck[i] = deck[r];
        deck[r] = temp;
    }
}

void deal_cards() {
    player.handSize = INITIAL_HAND_SIZE;
    computer.handSize = INITIAL_HAND_SIZE;
    for (int i = 0; i < INITIAL_HAND_SIZE; i++) {
        player.hand[i] = deck[deckIndex++];
        computer.hand[i] = deck[deckIndex++];
    }
    openCard = deck[deckIndex++];
}

void print_hand(Player *p) {
    for (int i = 0; i < p->handSize; i++) {
        printf("%s of %sn", p->hand[i].rank, p->hand[i].suit);
    }
}

void take_turn(Player *current, Player *opponent, int *turn) {
    printf("%s's turn!n", current == &player ? "Player" : "Computer");
    printf("Open card: %s of %sn", openCard.rank, openCard.suit);
    print_hand(current);
    int played = 0;
    for (int i = 0; i < current->handSize; i++) {
        if (canPlayCard(current->hand[i])) {
            play_card(current, i);
            played = 1;
            if (isAttackCard(openCard)) {
                apply_attack_card(current, opponent, openCard.value == 2 ? 2 : 4);
            }
            break;
        }
    }
    if (!played) {
        printf("No playable card. Drawing a card...n");
        draw_card(current, 1);
    }
    if (check_defeat(current)) {
        printf("%s loses!n", current == &player ? "Player" : "Computer");
        exit(0);
    } else if (check_victory(current)) {
        printf("%s wins!n", current == &player ? "Player" : "Computer");
        exit(0);
    }
    *turn = 1 - *turn;
}

void play_card(Player *p, int cardIndex) {
    openCard = p->hand[cardIndex];
    p->handSize--;
    for (int i = cardIndex; i < p->handSize; i++) {
        p->hand[i] = p->hand[i + 1];
    }
    printf("%s played: %s of %sn", p == &player ? "Player" : "Computer", openCard.rank, openCard.suit);
}

void draw_card(Player *p, int count) {
    for (int i = 0; i < count; i++) {
        if (deckIndex < NUM_CARDS) {
            p->hand[p->handSize++] = deck[deckIndex++];
        }
    }
}

int check_victory(Player *p) {
    return p->handSize == 0;
}

int check_defeat(Player *p) {
    return p->handSize >= MAX_HAND_SIZE;
}

int canPlayCard(Card c) {
    return c.value == openCard.value || c.suit == openCard.suit;
}

int isAttackCard(Card c) {
    return c.value == 2 || c.value == 14; 
}

void apply_attack_card(Player *attacker, Player *defender, int attackValue) {
    int hasDefense = 0;
    for (int i = 0; i < defender->handSize; i++) {
        if (defender->hand[i].value == 2 || defender->hand[i].value == 14) {
            hasDefense = 1;
            break;
        }
    }
    if (!hasDefense) {
        printf("%s draws %d cards.n", defender == &player ? "Player" : "Computer", attackValue);
        draw_card(defender, attackValue);
    } else {
        printf("%s has an attack card to defend.n", defender == &player ? "Player" : "Computer");
    }
}

void start_game() {
    initialize_deck();
    deal_cards();
    int turn = 0;
    while (1) {
        if (turn == 0) {
            take_turn(&player, &computer, &turn);
            if (check_victory(&player) || check_defeat(&computer)) {
                break;
            }
        } else {
            take_turn(&computer, &player, &turn);
            if (check_victory(&computer) || check_defeat(&player)) {
                break;
            }
        }
    }
}

I’ve tried implementing a one-card game with c, but my code is that when I run about 5 times, I fall into infinite loop at least 2 times. I’ve talked to chat-gpt a lot to solve this problem, but I haven’t found an answer… Please fix it!

Below is the code I tried, please tell me the problem, the code works as intended unless it falls into an infinite loop

New contributor

user25529716 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

LEAVE A COMMENT