IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 关于c语言扫雷游戏 -> 正文阅读

[C++知识库]关于c语言扫雷游戏

本次用c语言完成扫雷游戏的最初版

在开始要先有计划,对自己写的代码要有一个基本逻辑,对要写的游戏也需要有一个具体的逻辑,要是埋头就写结束后就可能有很多问题。

所有的代码我放在最后一段了。下面是我在学习后的理解想看的可以看下。

本次将扫雷分两部分来写。分别为:1、游戏框架?2、游戏主体函数和实现

1、游戏框架

首先一个游戏进入要有菜单,进入游戏和退出游戏可供玩家选择

我们也可以用一do while循环来供玩家选择多轮游戏

进入游戏就是游戏主体函数

退出就是退出游戏

最后就是对玩家的选项进行判断

#include"game.h"

int main()
{
    int input = 0;
    srand((unsigned int)time(NULL));//用于随机数
    do
    {
        menu();//菜单
        printf("\n\n请选择:>\n");
        scanf("%d", &input);
        switch(input)
        {
        case 1:
            game();//游戏主体函数
            break;
        case 0:
            printf("游戏已退出!\n");
            break;
        default:
            printf("输入有误!请重新输入!\n");
            break;
        };
    }while(input);
    return 0;
}
void menu()//菜单函数实现
{
    printf("*************************************\n");
    printf("****                             ****\n");
    printf("****   1、play        0、exit    ****\n");
    printf("****                             ****\n");
    printf("*************************************\n");
}

2、游戏主体

void game()//主体实现
{
    //需要两个数组
    //一个用来存放地雷
    //另一个用来存放提示
    char mine[Wids][Lens] = {0};//地雷
    char show[Wids][Lens] = {0};//提示
    //初始化数组
    initboard(mine, Wids, Lens, '0');
    initboard(show, Wids, Lens, '*');

    //打印棋盘
    displayboard(mine, Wid, Len);
    displayboard(show, Wid, Len);

    //埋雷
    setmine(mine, Wid, Len);
    //displayboard(mine, Wid, Len);

    //查雷
    findmine(mine, show, Wid, Len);
}

首先要对扫雷这个游戏进行逻辑分析,我们要将扫雷分解成为两部分来进行

第一个部分:我们要埋雷,将地雷随机埋进棋盘中

第二个部分:我们要查雷,锁定坐标得到提示,提示即周围一格内所有的地雷总数

所以我们需要两个二维数组来存放

一个存放地雷,一个存提示

    char mine[9][9] = {0};//地雷
    char show[9][9] = {0};//提示

接着我们需要对齐进行初始化

在初始化的时候我们知道数组的规格

首先我们要知道如果我们想创建一个9*9的棋盘,那么在扫雷中我们需要一个11*11的数组才可以存下。我们知道,提示是得到周围一格内所有的地雷数,如果我们想要的到9*9最边边那一列的提示的话那么数组可能会溢出。例如,我们要得到最右下角的那一块的提示,那么它需要将周围一格内所有的地雷进行判断和计数,但我们给的只有一格9*9的棋盘,所以可能溢出。为此我们需要将棋盘行和列各加两个,保证数组不会溢出。两个数组都加是因为我们要保证其坐标一致,方便后续操作。

这时我们就可以在头文件中进行宏定义。

#define Len 9
#define Wid 9
#define Lens 11
#define Wids 11

在我们的到这些参数后就可以进行数组初始化和棋盘打印了

我们在初始化的时候需要考虑我们要送进去的内容,我们上面使用的是char型数组,所以我们这里也都使用字符来送入。

地雷 = ‘1’? ? ? ? 无地雷 = ‘0’? ? ? 未提示 = ?? ? ? 提示 = ‘0’ ~ ‘9’

    //需要两个数组
    //一个用来存放地雷
    //另一个用来存放提示
    char mine[Wids][Lens] = {0};//地雷
    char show[Wids][Lens] = {0};//提示
    //初始化数组
    initboard(mine, Wids, Lens, '0');
    initboard(show, Wids, Lens, '*');

下面是对其函数的实现

void initboard(char board[Wids][Lens], int wids, int lens, char set)//初始化数组实现
{
    int i, j;
    for(i = 0; i < wids; i++)
    {
        for(j = 0; j < lens; j++)
        {
            board[i][j] = set;
        }
    }
}

接着我们将打印棋盘的函数也写出

    //打印棋盘
    displayboard(mine, Wid, Len);
    displayboard(show, Wid, Len);

? ? ? 对其实现

void displayboard(char board[Wids][Lens], int wid, int len)//打印棋盘实现
{
    int i, j;
    printf("------棋盘-------\n");
    for(i = 0; i <= len; i++)
    {
        printf("%d ", i);
    }
    printf("\n");
    for(i = 1; i <= wid; i++)
    {
        printf("%d ", i);
        for(j = 1; j <= len; j++)
        {
            printf("%c ", board[i][j]);
        }
        printf("\n");
    }
    printf("------棋盘-------\n");
}

最后就是我们重要的两部分 埋地雷和查地雷了

首先埋地雷

我们的目标是将10个地雷随机的埋入9*9的格子中

    //埋雷
    setmine(mine, Wid, Len);

下面是实现

void setmine(char board[Wids][Lens], int wid, int len)//埋雷实现
{
    //需要随机值

    int count = setmine_count;
    while(count)
    {
        int x = rand() % wid + 1;
        int y = rand() % len + 1;
        if(board[x][y] == '0')
        {
            board[x][y] = '1';
            count--;
        }
    }
}

接着是查地雷

    //查雷
    findmine(mine, show, Wid, Len);

在实现函数时,我们要知道首先需要:

玩家输入坐标,接着对坐标进行判断,是否在1-9这个范围内。

若符合,则对坐标进行是否有地雷的判断

有地雷,游戏结束

无地雷,进行周围一格内所有的地雷进行检测并计数,并对棋盘进行提示

下面是对函数的实现

static findmine_count(char board[Wids][Lens], int x, int y)//查雷实现
{
    return board[x - 1][y - 1] +
            board[x - 1][y] +
            board[x - 1][y + 1] +
            board[x][y - 1] +
            board[x][y + 1] +
            board[x + 1][y - 1] +
            board[x + 1][y] +
            board[x + 1][y - 1] - 8 * '0';
}
void findmine(char mine[Wids][Lens], char show[Wids][Lens], int wid, int len)
{
    //需要玩家输入坐标,对坐标进行判断
    //对有雷和无雷进行实现
    int x = 0;
    int y = 0;
    int count = 0;
    while(count != wid * len - setmine_count)
    {
        printf("\n\n请输入要查的坐标:>\n");
        scanf("%d %d", &x, &y);
        if(x >= 1 && x <= wid && y >= 1 && y <= len)
        {
            //有雷 被炸死
            //没有雷 计算周围一格内的雷数并显示
            if(mine[x][y] == '1')
            {
                printf("\n\n\n*****************\n");
                printf("*** 菜      菜***\n");
                printf("***           ***\n");
                printf("***     菜    ***\n");
                printf("***           ***\n");
                printf("***菜       菜***\n");
                printf("*****************\n\n\n\n");
                break;
            }
            else
            {
                int set = findmine_count(mine, x, y);//计算周围一周的雷数
                show[x][y] = set + '0';//一个数字  +  '0'字符零 = 当前数字的字符形式
                displayboard(show, wid, len);
                count++;
            }
        }
        else
        {
            printf("\n\n输入的坐标有误!请重新输入!\n\n");
        }
    }
    if(count == wid * len - setmine_count)
    {
        printf("\n\n打得好啊!\n\n");
        displayboard(show, wid, len);
        printf("\n\n\n");
    }
}

使用static可以对当前函数进行修饰,使其只能在本文件内使用,不会导致其他文件内出现重名等现象。

至此,完成扫雷游戏,其中还可以有很多优化,碍于本人技术有限,琢磨半天递归也没给点一下如果周围没有0则全部点亮提示给整出来。还有上面的那个查雷其实可以用循环实现看起来厉害一点,这里可以直接把board[x][y]排除的,我这里直接在后面多 - '0' 也可以吧。

static findmine_count(char board[Wids][Lens], int x, int y)//查雷实现
{
    int i,j;
    int sum = 0;
    for(i = -1; i < 2; i++)
    {
        for(j = -1; j < 2; j++)
        {
            sum = sum + board[x + i][y + j];
        }
    }
    return sum - 9 * '0';
}

下面是所有的代码

主函数:main.c

/**              扫雷                **/

#include"game.h"

int main()
{
    int input = 0;
    srand((unsigned int)time(NULL));
    do
    {
        menu();//菜单
        printf("\n\n请选择:>\n");
        scanf("%d", &input);
        switch(input)
        {
        case 1:
            game();//游戏主体函数
            break;
        case 0:
            printf("游戏已退出!\n");
            break;
        default:
            printf("输入有误!请重新输入!\n");
            break;
        };
    }while(input);
    return 0;
}

game.h

#ifndef GAME_H_INCLUDED
#define GAME_H_INCLUDED

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


#define Len 9
#define Wid 9
#define Lens 11
#define Wids 11
#define setmine_count 10 //地雷数

void menu();//菜单函数声明
void game();//主体函数声明
void initboard(char board[Wids][Lens], int wids, int lens, char set);//初始化数组声明
void displayboard(char board[Wids][Lens], int wid, int len);//打印棋盘声明
void setmine(char board[Wids][Lens], int wid, int len);//埋雷声明
void findmine(char mine[Wids][Lens], char show[Wids][Lens], int wid, int len);//查雷声明



#endif // GAME_H_INCLUDED

game.c

#include"game.h"


void menu()//菜单函数实现
{
    printf("*************************************\n");
    printf("****                             ****\n");
    printf("****   1、play        0、exit    ****\n");
    printf("****                             ****\n");
    printf("*************************************\n");
}

void game()//主体实现
{
    //需要两个数组
    //一个用来存放地雷
    //另一个用来存放提示
    char mine[Wids][Lens] = {0};//地雷
    char show[Wids][Lens] = {0};//提示
    //初始化数组
    initboard(mine, Wids, Lens, '0');
    initboard(show, Wids, Lens, '*');

    //打印棋盘
    displayboard(mine, Wid, Len);
    displayboard(show, Wid, Len);

    //埋雷
    setmine(mine, Wid, Len);
    //displayboard(mine, Wid, Len);

    //查雷
    findmine(mine, show, Wid, Len);
}

void initboard(char board[Wids][Lens], int wids, int lens, char set)//初始化数组实现
{
    int i, j;
    for(i = 0; i < wids; i++)
    {
        for(j = 0; j < lens; j++)
        {
            board[i][j] = set;
        }
    }
}


void displayboard(char board[Wids][Lens], int wid, int len)//打印棋盘实现
{
    int i, j;
    printf("------棋盘-------\n");
    for(i = 0; i <= len; i++)
    {
        printf("%d ", i);
    }
    printf("\n");
    for(i = 1; i <= wid; i++)
    {
        printf("%d ", i);
        for(j = 1; j <= len; j++)
        {
            printf("%c ", board[i][j]);
        }
        printf("\n");
    }
    printf("------棋盘-------\n");
}

void setmine(char board[Wids][Lens], int wid, int len)//埋雷实现
{
    //需要随机值

    int count = setmine_count;
    while(count)
    {
        int x = rand() % wid + 1;
        int y = rand() % len + 1;
        if(board[x][y] == '0')
        {
            board[x][y] = '1';
            count--;
        }
    }
}

static findmine_count(char board[Wids][Lens], int x, int y)//查雷实现
{
    int i,j;
    int sum = 0;
    for(i = -1; i < 2; i++)
    {
        for(j = -1; j < 2; j++)
        {
            sum = sum + board[x + i][y + j];
        }
    }
    return sum - 9 * '0';

//    return board[x - 1][y - 1] +
//            board[x - 1][y] +
//            board[x - 1][y + 1] +
//            board[x][y - 1] +
//            board[x][y + 1] +
//            board[x + 1][y - 1] +
//            board[x + 1][y] +
//            board[x + 1][y - 1] - 8 * '0';
}


void findmine(char mine[Wids][Lens], char show[Wids][Lens], int wid, int len)
{
    //需要玩家输入坐标,对坐标进行判断
    //对有雷和无雷进行实现
    int x = 0;
    int y = 0;
    int count = 0;
    while(count != wid * len - setmine_count)
    {
        printf("\n\n请输入要查的坐标:>\n");
        scanf("%d %d", &x, &y);
        if(x >= 1 && x <= wid && y >= 1 && y <= len)
        {
            //有雷 被炸死
            //没有雷 计算周围一格内的雷数并显示
            if(mine[x][y] == '1')
            {
                printf("\n\n\n*****************\n");
                printf("*** 菜      菜***\n");
                printf("***           ***\n");
                printf("***     菜    ***\n");
                printf("***           ***\n");
                printf("***菜       菜***\n");
                printf("*****************\n\n\n\n");
                break;
            }
            else
            {
                int set = findmine_count(mine, x, y);//计算周围一周的雷数
                show[x][y] = set + '0';//一个数字  +  '0'字符零 = 当前数字的字符形式
                displayboard(show, wid, len);
                count++;
            }
        }
        else
        {
            printf("\n\n输入的坐标有误!请重新输入!\n\n");
        }
    }
    if(count == wid * len - setmine_count)
    {
        printf("\n\n打得好啊!\n\n");
        displayboard(show, wid, len);
        printf("\n\n\n");
    }
}

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-12-13 12:37:21  更:2021-12-13 12:39:49 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 12:54:29-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码