首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C語言簡易猜拳遊戲專案:結構體設計、動態記憶體與模組化架構

     編輯:關於C語言

C語言簡易猜拳遊戲專案:結構體設計、動態記憶體與模組化架構

本專案示範一個結構化的 C 語言小專案架構:玩家資料結構體、動態分配/釋放、選單控制、隨機出拳、勝負判定、戰績統計顯示。雖標註「未優化」,但已具備模組化雛形,適合作為專案架構學習範本。

專案結構

guess_game/
├── main.c        // 程式入口
├── player.h      // 玩家結構體與介面宣告
├── player.c      // 玩家模組實作
├── game.h        // 遊戲邏輯介面
├── game.c        // 遊戲核心實作
└── Makefile      // 建置腳本

核心代碼整合版(單檔教學用)

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

#define SIZE 20
#define PASSWD_SIZE 20
#define DEFAULT_NAME "player1"
#define DEFAULT_PASS "123456"
#define TRUE 1

// 玩家結構體
typedef struct Player {
    char name[SIZE];
    char passwd[PASSWD_SIZE];
    int total;     // 總局數
    int victory;   // 勝利局數
} Player;

Player *g_player = NULL;

// 建立玩家 (動態分配)
Player *create_player() {
    Player *p = (Player*)malloc(sizeof(Player));
    if (!p) return NULL;
    memset(p, 0, sizeof(Player));
    strcpy(p->name, DEFAULT_NAME);
    strcpy(p->passwd, DEFAULT_PASS);
    p->total = 0;
    p->victory = 0;
    return p;
}

// 銷毀玩家
void destroy_player() {
    if (g_player) {
        free(g_player);
        g_player = NULL;
    }
}

// 選單顯示
void show_menu() {
    printf("************************************************************\n");
    printf("猜拳遊戲\n");
    printf("1.石頭 2.剪刀 3.布 0.退出\n");
    printf("************************************************************\n");
}

// 電腦隨機出拳
int computer_gesture() {
    return rand() % 3 + 1;  // 1=石頭, 2=剪刀, 3=布
}

// 遊戲主控制迴圈
void game_loop() {
    int player_choice = 0;
    int computer_choice = 0;
    int result = 0;  // 1=玩家贏, 0=平手, -1=電腦贏

    while (TRUE) {
        show_menu();
        // 輸入驗證
        do {
            printf("請選擇: ");
            if (scanf("%d", &player_choice) != 1) {
                while (getchar() != '\n');  // 清理緩衝區
                player_choice = -1;
            }
        } while (player_choice < 0 || player_choice > 3);

        if (player_choice == 0) break;

        computer_choice = computer_gesture();

        // 勝負判定: (player - computer + 3) % 3
        // 1=贏, 0=平, 2=輸
        int diff = (player_choice - computer_choice + 3) % 3;
        g_player->total++;

        if (diff == 1) {
            printf("恭喜你,你贏了!\n");
            g_player->victory++;
        } else if (diff == 0) {
            printf("平局\n");
        } else {
            printf("你輸了,再來一局?\n");
        }
    }
}

// 顯示戰績
void show_stats() {
    printf("\t\t排行榜\n\n");
    printf("\t*********************\n");
    printf("姓名\t總局數\t贏場\t勝率\n");
    if (g_player->total > 0) {
        double rate = (double)g_player->victory / g_player->total * 100;
        printf("%s\t%d\t%d\t%.2f%%\n", g_player->name, g_player->total, g_player->victory, rate);
    } else {
        printf("%s\t0\t0\t0.00%%\n", g_player->name);
    }
}

int main() {
    srand((unsigned)time(NULL));  // 僅初始化一次

    g_player = create_player();
    if (!g_player) {
        fprintf(stderr, "玩家建立失敗\n");
        return 1;
    }

    game_loop();
    show_stats();
    destroy_player();

    return 0;
}

架構優化方向

模組現狀優化建議
玩家管理單一全域指標支援多玩家、鏈表/陣列管理、檔案持久化
遊戲邏輯硬編碼勝負判定資料驅動:結果查表、可配置規則、擴展手勢
隨機數rand() 低品質使用 random()、/dev/urandom、C++11 <random>
輸入處理簡單 scanf完整輸入驗證、支援別名、非阻塞輸入
介面終端機文字ncurses TUI、SDL2 GUI、WebAssembly 網頁版
建置系統無CMake、單元測試 (Unity/CMock)、CI/CD

進階擴展功能

  1. 帳號系統:註冊/登入、密碼雜湊 (bcrypt)、會話管理。
  2. 排行榜:SQLite 儲存、全域排名、分頁顯示。
  3. AI 對手:馬可夫鏈預測玩家習慣、極小化極大算法。
  4. 網路對戰:TCP/UDP、序列化協議 (Protobuf/JSON)、伺服器權威判定。
  5. 圖形化:SDL2/raylib 繪製手勢動畫、粒子效果、音效。

程式碼品質檢查清單

  • ✅ 結構體封裝資料
  • ✅ 動態記憶體配對分配/釋放
  • ✅ 隨機種子僅初始化一次
  • ✅ 輸入驗證與緩衝區清理
  • ⚠️ 全域變數 g_player 耦合度高
  • ⚠️ 魔術數字 (1,2,3) 未用枚舉
  • ⚠️ 無錯誤碼傳遞 (malloc 失敗直接 return)
  • ⚠️ gets/scanf 安全性不足
  • ⚠️ 無單元測試

這個專案雖小,但包含了 C 專案開發的核心要素:資料建模、記憶體管理、模組邊界、隨機數、使用者互動、統計顯示。建議以此為基礎,逐步導入上述優化,體驗從「能跑」到「好維護、可擴展、可測試」的工程化演進過程。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved