《C语言实现扫雷游戏:从零开始的编程实践》

在这里插入图片描述

🚀个人主页:BabyZZの秘密日记
📖收入专栏:C语言


C语言实现扫雷游戏:从零开始的编程实践

在编程学习的过程中,实现一个经典的游戏是一个非常有趣且富有挑战性的项目。今天,我们将通过C语言来实现一个简单的扫雷游戏,并详细解析代码的实现过程。这个项目不仅涵盖了数组、函数、随机数生成等基础知识,还展示了如何通过模块化设计来构建一个完整的游戏程序。

一、扫雷游戏简介

扫雷是一款经典的单人游戏,目标是在不触发地雷的情况下,清除所有未被标记为地雷的方格。游戏开始时,玩家看到的是一个由若干行和列组成的网格,每个方格初始状态为隐藏。地雷随机分布在网格中,玩家通过点击方格来揭示其内容。如果方格内有地雷,则游戏失败;如果没有地雷,则会显示该方格周围(包括上下左右及对角线方向)地雷的数量。玩家可以根据这些提示,推断出哪些方格可能有地雷,并避开它们。

二、代码结构与模块化设计

我们的扫雷游戏代码由三个主要文件组成:game.hgame.ctest.c。这种模块化设计有助于代码的组织和维护。

(一)game.h:头文件

头文件是C语言中用于声明函数和宏定义的地方,它为其他文件提供了接口。在我们的项目中,game.h 文件定义了游戏的基本参数(如网格的行数和列数、地雷数量等),并声明了实现游戏功能的函数。

#pragma once  // 防止头文件重复包含

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

// 定义棋盘的大小和地雷数量
#define ROW 9       // 棋盘行数
#define COL 9       // 棋盘列数
#define ROWS ROW + 2 // 扩展棋盘的行数,用于处理边界情况
#define COLS COL + 2 // 扩展棋盘的列数,用于处理边界情况
#define Eayscountmine 10 // 地雷数量

// 声明函数原型
void Initboard(char board[ROWS][COLS], int rows, int cols, char set);  // 初始化棋盘
void Displayboard(char board[ROWS][COLS], int row, int col);           // 显示棋盘
void Setmine(char board[ROWS][COLS], int row, int col);                // 随机设置地雷
void Findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col); // 玩家寻找地雷

(二)game.c:游戏逻辑实现

game.c 文件包含了游戏的核心逻辑,包括初始化棋盘、设置地雷、显示棋盘以及玩家寻找地雷的过程。

1. 初始化棋盘

Initboard 函数用于初始化棋盘,将每个方格设置为指定的字符(如 '0''*')。这个函数通过两层嵌套循环遍历整个棋盘数组,并为每个方格赋值。

void Initboard(char board[ROWS][COLS], int rows, int cols, char set)
{
    for (int i = 0; i < rows; i++)  // 遍历行
    {
        for (int j = 0; j < cols; j++)  // 遍历列
        {
            board[i][j] = set;  // 将每个位置设置为指定字符
        }
    }
}

功能解析

  • board 是一个二维字符数组,用于存储棋盘的状态。
  • rowscols 分别表示棋盘的行数和列数。
  • set 是要初始化的字符,例如 '0' 表示无地雷,'*' 表示隐藏状态。
2. 显示棋盘

Displayboard 函数负责将棋盘以友好的格式显示给玩家。它在棋盘的顶部和左侧添加了坐标标记,方便玩家输入坐标。

void Displayboard(char board[ROWS][COLS], int row, int col)
{
    printf("========扫雷========\n");
    for (int i = 0; i <= col; i++)  // 打印列坐标
    {
        printf("%d ", i); 
    }
    printf("\n");
    for (int i = 1; i <= row; i++)  // 遍历行
    {
        printf("%d ", i);  // 打印行坐标
        for (int j = 1; j <= col; j++)  // 遍历列
        {
            printf("%c ", board[i][j]);  // 打印每个位置的内容
        }
        printf("\n");
    }
    printf("\n");
}

功能解析

  • 顶部的数字表示列的编号,左侧的数字表示行的编号。
  • 每个方格的内容通过 board[i][j] 获取并打印。
3. 设置地雷

Setmine 函数通过随机数生成器在棋盘上随机放置地雷。为了避免重复放置地雷,它会检查目标位置是否已经被设置过地雷。

void Setmine(char board[ROWS][COLS], int row, int col) 
{   
    int count = Eayscountmine;  // 地雷数量
    while (count)  // 直到所有地雷设置完成
    {
        int x = rand() % row + 1;  // 随机生成行坐标
        int y = rand() % col + 1;  // 随机生成列坐标
        if (board[x][y] == '0')  // 如果该位置尚未设置地雷
        {
            board[x][y] = '1';  // 设置地雷
            count--;  // 地雷数量减1
        }
    }
}

功能解析

  • 使用 rand() 函数生成随机坐标。
  • 检查 board[x][y] 是否为 '0',以确保不会重复设置地雷。
4. 寻找地雷

Findmine 函数是游戏的主循环,玩家通过输入坐标来揭示方格内容。如果揭示的方格有地雷,游戏失败;否则,会显示该方格周围的地雷数量,并继续游戏。玩家的目标是清除所有无地雷的方格。

void Findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
    int x = 0;  // 玩家输入的行坐标
    int y = 0;  // 玩家输入的列坐标
    int win = 0;  // 清除的方格数量
    while (win < row * col - Eayscountmine)  // 直到清除所有非地雷方格
    { 
        printf("请输入坐标: ");
        scanf("%d %d", &x, &y);  // 获取玩家输入的坐标
        if (x >= 1 && x <= row && y >= 1 && y <= col)  // 检查坐标是否有效
        {
            if (mine[x][y] == '1')  // 如果该位置有地雷
            {
                printf("很遗憾,失败\n"); 
                Displayboard(mine, ROW, COL);  // 显示地雷分布
                break;
            }
            else
            {
                int count = getminecount(mine, x, y);  // 获取周围地雷数量
                show[x][y] = count + '0';  // 更新显示棋盘
                Displayboard(show, ROW, COL);  // 显示当前棋盘
                win++;  // 清除方格数量加1
            }
        }
        else
        {
            printf("输入不在范围:x(1~9), y(1~9)\n");
        }
    }
    if (win == row * col - Eayscountmine)  // 如果清除所有非地雷方格
    {
        printf("恭喜你,扫雷成功\n"); 
        Displayboard(mine, ROW, COL);  // 显示地雷分布
    }
}

功能解析

  • mine 数组存储地雷的实际分布,show 数组存储显示给玩家的内容。
  • 玩家输入坐标后,程序会检查该位置是否有地雷。
  • 如果没有地雷,程序会计算该位置周围的地雷数量,并更新 show 数组。
5. 计算周围地雷数量

getminecount 函数用于计算指定位置周围的地雷数量。它通过遍历周围 8 个方向的方格来实现。

int getminecount(char mine[ROWS][COLS], int x, int y)
{
    int count = 0;
    for (int i = -1; i <= 1; i++)  // 遍历周围行
    {
        for (int j = -1; j <= 1; j++)  // 遍历周围列
        {
            count += (mine[x + i][y + j] - '0');  // 累加周围地雷数量
        }
    }
    return count;
}

功能解析

  • 通过 mine[x + i][y + j] 访问周围方格。
  • 使用 (mine[x + i][y + j] - '0') 将字符转换为数字。

(三)test.c:游戏入口与菜单

test.c 文件是游戏的入口,它负责初始化随机数种子、显示菜单并根据用户选择调用游戏函数。

#define _CRT_SECURE_NO_WARNINGS 1  // 禁用安全警告

#include "game.h"

// 显示菜单
void menu()
{
    printf("#####################\n");   
    printf("####   1. play	 ####\n"); 
    printf("####   0. exit	 ####\n");
    printf("#####################\n"); 
}

// 游戏主函数
void game()
{
    char mine[ROWS][COLS] = { 0 };  // 用于存储地雷分布
    char show[ROWS][COLS] = { 0 };  // 用于显示给玩家的棋盘

    Initboard(mine, ROWS, COLS, '0');  // 初始化地雷棋盘
    Initboard(show, ROWS, COLS, '*');  // 初始化显示棋盘

    Displayboard(show, ROW, COL);  // 显示初始棋盘

    Setmine(mine, ROW, COL);  // 随机设置地雷

    Findmine(mine, show, ROW, COL);  // 玩家寻找地雷
}

// 主测试函数
void test()
{
    srand((unsigned int)time(NULL));  // 初始化随机数种子
    int input = 0;  // 用户输入
    do
    { 
        menu();  // 显示菜单
        printf("请选择是否开始游戏:");   
        scanf("%d", &input);  // 获取用户输入
        switch (input)
        {
            case 1:  // 开始游戏
                game(); 
                break; 
            case 0:  // 退出游戏
                printf("你选择退出\n"); 
                break; 
            default:  // 无效输入
                printf("输入不在范围,请重新输入\n"); 
                break;
        }
    } while (input);  // 循环直到用户选择退出
} 

// 主函数
int main()
{
    test();  // 调用测试函数
    return 0; 
}

功能解析

  • menu 函数显示游戏菜单,提供开始游戏和退出的选项。
  • game 函数初始化棋盘,设置地雷,并调用寻找地雷的函数。
  • test 函数循环显示菜单并处理用户输入。

三、运行与体验

编译并运行程序后,玩家将看到一个简单的菜单,可以选择开始游戏或退出。游戏开始后,玩家会看到一个由 * 组成的棋盘,表示所有方格都处于隐藏状态。通过输入坐标,玩家可以揭示方格内容。如果揭示的方格有地雷,游戏失败;否则,会显示该方格周围的地雷数量。玩家可以根据这些提示继续寻找地雷,直到清除所有无地雷的方格,或者触发地雷导致游戏失败。

四、总结

通过这个简单的扫雷游戏项目,我们学习了如何使用C语言实现一个完整的程序,包括模块化设计、函数的定义与调用、数组的使用以及随机数生成等知识。虽然这个版本的扫雷游戏功能较为基础,但它为我们提供了一个很好的起点,可以在此基础上进行扩展和优化。例如,我们可以增加标记地雷的功能、调整地雷数量和棋盘大小、优化用户界面等。通过不断改进和扩展,我们可以逐步提升自己的编程能力和对游戏开发的理解。

希望这个项目能激发你对编程的兴趣,同时也为你提供了一个实践和学习的平台。如果你对这个项目有任何疑问或建议,欢迎随时交流和讨论。让我们一起在编程的世界中不断探索和进步!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值