C语言小游戏实例 C语言

以下设计了三个难度递进的C语言命令行小游戏,分别涵盖基本语法、数组与逻辑、数据结构与状态管理,适合大学教学使用。 游戏一:猜数字(难度:★☆☆☆☆) 教学要点:随机数生成、循环、条件判断、基本输入输出 玩法:系统随机生成1-100数字,玩家输入猜测,提示“太大/太小”,直到猜中并显示猜测次数。
C
// guess_number.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main() {
    int target, guess, attempts = 0;
    srand(time(NULL));
    target = rand() % 100 + 1;  // 1~100随机数

    printf("=== 猜数字游戏 ===\n");
    printf("我已想好一个1~100之间的整数,请猜:\n");

    do {
        printf("输入你的猜测: ");
        scanf("%d", &guess);
        attempts++;

        if (guess > target)
            printf("太大了!\n");
        else if (guess < target)
            printf("太小了!\n");
        else
            printf("恭喜!猜中了,共用了 %d 次猜测。\n", attempts);
    } while (guess != target);

    return 0;
}
游戏二:井字棋(人机随机)(难度:★★☆☆☆) 教学要点:二维数组、函数封装、随机AI、胜负判定 玩法:玩家执X,电脑执O,轮流下子,先连成一行/列/对角线者胜。
C
// tic_tac_toe.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <ctype.h>

char board[3][3];

// 初始化棋盘
void initBoard() {
    for (int i = 0; i < 3; i++)
        for (int j = 0; j < 3; j++)
            board[i][j] = ' ';
}

// 显示棋盘
void printBoard() {
    printf("\n  1   2   3\n");
    for (int i = 0; i < 3; i++) {
        printf("%d", i+1);
        for (int j = 0; j < 3; j++) {
            printf(" %c ", board[i][j]);
            if (j < 2) printf("|");
        }
        printf("\n");
        if (i < 2) printf("  -----------\n");
    }
    printf("\n");
}

// 检查是否胜利
int checkWin(char player) {
    // 行、列、对角线检查
    for (int i = 0; i < 3; i++) {
        if (board[i][0] == player && board[i][1] == player && board[i][2] == player) return 1;
        if (board[0][i] == player && board[1][i] == player && board[2][i] == player) return 1;
    }
    if (board[0][0] == player && board[1][1] == player && board[2][2] == player) return 1;
    if (board[0][2] == player && board[1][1] == player && board[2][0] == player) return 1;
    return 0;
}

// 检查平局
int isDraw() {
    for (int i = 0; i < 3; i++)
        for (int j = 0; j < 3; j++)
            if (board[i][j] == ' ') return 0;
    return 1;
}

// 玩家移动
void playerMove() {
    int row, col;
    while (1) {
        printf("你的回合 (行 列,如 1 2): ");
        scanf("%d %d", &row, &col);
        row--; col--;
        if (row >= 0 && row < 3 && col >= 0 && col < 3 && board[row][col] == ' ') {
            board[row][col] = 'X';
            break;
        }
        printf("无效位置,重新输入!\n");
    }
}

// 电脑随机移动
void computerMove() {
    int row, col;
    printf("电脑思考中...\n");
    while (1) {
        row = rand() % 3;
        col = rand() % 3;
        if (board[row][col] == ' ') {
            board[row][col] = 'O';
            break;
        }
    }
}

int main() {
    srand(time(NULL));
    initBoard();
    printBoard();

    while (1) {
        playerMove();
        printBoard();
        if (checkWin('X')) { printf("你赢了!\n"); break; }
        if (isDraw()) { printf("平局!\n"); break; }

        computerMove();
        printBoard();
        if (checkWin('O')) { printf("电脑赢了!\n"); break; }
        if (isDraw()) { printf("平局!\n"); break; }
    }
    return 0;
}
游戏三:推箱子(单关卡)(难度:★★★☆☆) 教学要点:复杂状态管理、结构体、模块化设计、键盘输入处理 玩法:WASD移动,将两个箱子推到目标点(显示为★)。胜利后自动退出。
C
// sokoban.c
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>   // Windows下用_getch(),Linux可替换为curses或termios
#include <stdbool.h>

#define WIDTH  8
#define HEIGHT 7

// 静态层:0空地 1墙 2目标点
int staticMap[HEIGHT][WIDTH] = {
    {1,1,1,1,1,1,1,1},
    {1,2,0,0,0,0,0,1},
    {1,0,1,0,1,0,0,1},
    {1,0,0,3,0,0,0,1},   // 注意3和4是动态数据,这里初始用箱子/玩家标记,实际动态独立存储
    {1,0,0,0,4,0,0,1},
    {1,0,0,0,0,0,0,1},
    {1,1,1,1,1,1,1,1}
};

// 动态数据
int playerX, playerY;
bool boxMap[HEIGHT][WIDTH];   // 箱子位置
int targetCount = 0;          // 目标点总数

// 保存初始状态
int initPlayerX, initPlayerY;
bool initBoxMap[HEIGHT][WIDTH];

// 初始化:从静态地图中提取玩家、箱子、目标点
void initGame() {
    targetCount = 0;
    for (int i = 0; i < HEIGHT; i++) {
        for (int j = 0; j < WIDTH; j++) {
            if (staticMap[i][j] == 2) targetCount++;
            if (staticMap[i][j] == 3) {  // 临时表示箱子
                boxMap[i][j] = true;
                staticMap[i][j] = 0;     // 还原为空地
            } else if (staticMap[i][j] == 4) { // 临时表示玩家
                playerX = i; playerY = j;
                staticMap[i][j] = 0;
            } else {
                boxMap[i][j] = false;
            }
        }
    }
    // 保存初始状态
    initPlayerX = playerX;
    initPlayerY = playerY;
    for (int i = 0; i < HEIGHT; i++)
        for (int j = 0; j < WIDTH; j++)
            initBoxMap[i][j] = boxMap[i][j];
}

// 重置游戏
void resetGame() {
    playerX = initPlayerX;
    playerY = initPlayerY;
    for (int i = 0; i < HEIGHT; i++)
        for (int j = 0; j < WIDTH; j++)
            boxMap[i][j] = initBoxMap[i][j];
}

// 显示地图
void drawMap() {
    system("cls");  // 清屏,Windows使用,Linux可改为system("clear")
    for (int i = 0; i < HEIGHT; i++) {
        for (int j = 0; j < WIDTH; j++) {
            if (i == playerX && j == playerY) {
                // 玩家站在目标点上显示特殊符号
                if (staticMap[i][j] == 2) printf("♀ ");
                else printf("♂ ");
            }
            else if (boxMap[i][j]) {
                // 箱子在目标点上显示为★
                if (staticMap[i][j] == 2) printf("★ ");
                else printf("■ ");
            }
            else {
                if (staticMap[i][j] == 1) printf("█ ");
                else if (staticMap[i][j] == 2) printf("☆ ");
                else printf("  ");
            }
        }
        printf("\n");
    }
    printf("\nWASD移动,R重置,Q退出\n");
}

// 检查胜利(所有箱子是否都在目标点上)
bool checkWin() {
    for (int i = 0; i < HEIGHT; i++) {
        for (int j = 0; j < WIDTH; j++) {
            if (boxMap[i][j] && staticMap[i][j] != 2) return false;
        }
    }
    return true;
}

// 尝试移动
bool move(int dx, int dy) {
    int newX = playerX + dx;
    int newY = playerY + dy;

    // 边界或墙壁
    if (newX < 0 || newX >= HEIGHT || newY < 0 || newY >= WIDTH) return false;
    if (staticMap[newX][newY] == 1) return false;

    // 前方有箱子
    if (boxMap[newX][newY]) {
        int pushX = newX + dx;
        int pushY = newY + dy;
        if (pushX < 0 || pushX >= HEIGHT || pushY < 0 || pushY >= WIDTH) return false;
        if (staticMap[pushX][pushY] == 1) return false;
        if (boxMap[pushX][pushY]) return false;  // 箱子前还有箱子

        // 推动箱子
        boxMap[pushX][pushY] = true;
        boxMap[newX][newY] = false;
        playerX = newX;
        playerY = newY;
        return true;
    }
    // 空地或目标点
    else {
        playerX = newX;
        playerY = newY;
        return true;
    }
}

int main() {
    initGame();
    char ch;
    while (1) {
        drawMap();
        if (checkWin()) {
            printf("恭喜过关!按任意键退出...\n");
            getch();
            break;
        }
        ch = getch();
        switch (ch) {
            case 'w': case 'W': move(-1, 0); break;
            case 's': case 'S': move(1, 0); break;
            case 'a': case 'A': move(0, -1); break;
            case 'd': case 'D': move(0, 1); break;
            case 'r': case 'R': resetGame(); break;
            case 'q': case 'Q': return 0;
        }
    }
    return 0;
}
编译与运行说明 猜数字 / 井字棋:直接使用任意C编译器(gcc、clang、MSVC)编译运行,无需额外依赖。 推箱子: Windows:使用gcc sokoban.c -o sokoban.exe,依赖<conio.h>。 Linux/macOS:需替换_getch()为getchar()或使用curses库。教学环境中可统一使用Windows或安装conio.h模拟库。 教学建议 猜数字:让学生理解循环和随机数,可扩展为计分、难度选择。 井字棋:讲解二维数组遍历、函数模块化,可让学生尝试实现“智能AI”(如优先防守)。 推箱子:演示复杂状态管理、重置功能、胜利检测,适合作为课程大作业基础。 这三个游戏逐步增加数据结构复杂度,便于学生循序渐进掌握C语言核心编程能力
← 返回列表

评论 (0)

登录后可以发表评论

立即登录
💬

还没有评论,快来发表第一条评论吧!