🃏 カードゲーム - 解答と解説

課題3-1の要件

1. プログラムの実装 (card_game.c)

#include <stdio.h> #include <stdlib.h> #include <time.h> // トランプのスート(マーク)を定義 typedef enum { SPADES, HEARTS, DIAMONDS, CLUBS, SUIT_MAX } Suit; // カード構造体 typedef struct { Suit suit; // スート int number; // 数字(1-13) int is_dealt; // 配布済みフラグ } Card; // 手札構造体 typedef struct { Card* cards; // カードの配列 int num_cards; // 手札の枚数 } Hand; // デッキ構造体 typedef struct { Card cards[52]; // 52枚のカード int top; // 次に引くカードの位置 } Deck; // 関数のプロトタイプ宣言 void initializeDeck(Deck* deck); void shuffleDeck(Deck* deck); Card drawCard(Deck* deck); void displayCard(const Card* card); const char* getSuitName(Suit suit); void initializeHand(Hand* hand); void addCardToHand(Hand* hand, Card card); void displayHand(const Hand* hand); int calculateScore(const Hand* hand); void freeHand(Hand* hand); int main() { system("chcp 65001"); // 日本語表示対応 srand((unsigned int)time(NULL)); Deck deck; Hand player_hand; // デッキの初期化とシャッフル initializeDeck(&deck); shuffleDeck(&deck); // 手札の初期化 initializeHand(&player_hand); // 5枚のカードを配る for (int i = 0; i < 5; i++) { Card card = drawCard(&deck); addCardToHand(&player_hand, card); } // 手札の表示 printf("あなたの手札:\n"); displayHand(&player_hand); // 得点計算と表示 int score = calculateScore(&player_hand); printf("\n得点: %d\n", score); // メモリの解放 freeHand(&player_hand); return 0; } void initializeDeck(Deck* deck) { int index = 0; for (int suit = 0; suit < SUIT_MAX; suit++) { for (int number = 1; number <= 13; number++) { deck->cards[index].suit = suit; deck->cards[index].number = number; deck->cards[index].is_dealt = 0; index++; } } deck->top = 0; } void shuffleDeck(Deck* deck) { for (int i = 51; i > 0; i--) { int j = rand() % (i + 1); Card temp = deck->cards[i]; deck->cards[i] = deck->cards[j]; deck->cards[j] = temp; } } Card drawCard(Deck* deck) { Card card = deck->cards[deck->top]; deck->cards[deck->top].is_dealt = 1; deck->top++; return card; } const char* getSuitName(Suit suit) { switch (suit) { case SPADES: return "♠"; case HEARTS: return "♥"; case DIAMONDS: return "♦"; case CLUBS: return "♣"; default: return "?"; } } void displayCard(const Card* card) { const char* number_str; switch (card->number) { case 1: number_str = "A"; break; case 11: number_str = "J"; break; case 12: number_str = "Q"; break; case 13: number_str = "K"; break; default: printf("%d", card->number); number_str = ""; } printf("%s%s ", getSuitName(card->suit), number_str); } void initializeHand(Hand* hand) { hand->cards = NULL; hand->num_cards = 0; } void addCardToHand(Hand* hand, Card card) { hand->num_cards++; hand->cards = (Card*)realloc(hand->cards, sizeof(Card) * hand->num_cards); hand->cards[hand->num_cards - 1] = card; } void displayHand(const Hand* hand) { for (int i = 0; i < hand->num_cards; i++) { displayCard(&hand->cards[i]); } printf("\n"); } int calculateScore(const Hand* hand) { int score = 0; for (int i = 0; i < hand->num_cards; i++) { if (hand->cards[i].number > 10) score += 10; else score += hand->cards[i].number; } return score; } void freeHand(Hand* hand) { if (hand->cards != NULL) { free(hand->cards); hand->cards = NULL; } hand->num_cards = 0; }

2. プログラムの解説

2.1 データ構造

2.2 主要な関数(続き)

3. メモリ管理のポイント

3.1 動的メモリ割り当て

4. 改良のポイント

4.1 基本的な改良案

4.2 発展的な機能追加

5. よくある問題と解決策

5.1 メモリ関連の問題

5.2 ロジックの問題

6. テストのポイント

6.1 テストケース