写一个扫雷小游戏

        

目录

        

          1.  游戏逻辑

                     1.1 游戏运行逻辑

                     1.2 代码的实现逻辑

                            1.2.1 代码分模块

                            1.2.2 打印菜单供用户选择

                            1.2.3 操作游戏函数

           2.所用到的知识点

                       1.二维数组

                       2.循环的嵌套

                       3.随机数的生成

                       4.#define定义的符号

                       5.函数的定义与调用

                       6.选择与循环

                       7.数字字符与数字的转化

            3.注意事项


1.1 游戏的运行逻辑

        首先,扫雷在本质上来说就是一个操作两个二维数组来完成游戏的实现。一个二维数组完成对雷盘的埋雷,另一个完成给用户显示的功能。每排一个雷,数组就需要遍历所排的那个元素周边的所有8个元素,并且告知用户这个元素周边有几个雷  (用0来表示非雷,1来表示雷)

1.2 代码的实现逻辑

 1.2.1代码分模块

首先,为什么要代码分模块呢?

                        从初学者的角度来说,这个虽说是个小游戏,但是总代码量也超出了200行,从实

                际的角度讲,分模块写不仅可以讲各个函数独立化是主函数的代码量变少,对于初学者

                来讲更有条理清晰之功效。简直是小白程序员必备技能

                如何分模块呢?

                        首先,创建三个文件,一个测试的源文件(test.c),一个游戏的源文件(game.c)

                 一个游戏的头文件(game.h)

                测试的源文件专门用来存放测试所需要用的代码(废话文学我算是把玩明白了),游戏

                的源文件来存放实现游戏逻辑的代码,而游戏的头文件用来放各种头文件,和各种函数

                声明。

1.2.2 打印菜单供用户选择

#include <stdio.h>

void menu()
{
    printf("*************扫雷*************\n");
    printf("**1.PLAY**************2.EXIT**\n");
    printf("******************************\n");
}


void test()
{
    int input=0;
  do{
    menu();
    scanf("%d",&input);
    switch(input)
    {
        case 1:
            {
                printf("游戏开始\n");
                break;
            }
        case 2:
            {
                printf("游戏结束\n");
                break;
            }
        default :
            {
                printf("请重新输入游戏代码");
                break;
            }
        
      
    }     
    
     }while(input);

}

int main()
{
    test();
}

1.2.3 操作游戏函数

        测试test.c文件

                首先既然是有两个雷盘,一个用于埋雷,一个用给展示给用户首先我们可以先建立两个二维数组用来代表这两个雷盘

                雷盘的大小弄多少比较合适呢?

        一般来说9*9的雷盘已经足够。

                那是不是我们需要9*9的雷盘就需要9*9的二维数组呢?

        这个问题我们就得考虑到数组越界的问题,当我们选择最边的那个元素,我们在遍历他周围元素的时候会不会发生越界,所以为了解决这个问题我们在建立二维数组的时候就直接比我们想要的雷盘大一圈。但给用户展示的时候不会展示到,用户还是操作着9*9的棋盘(为了以后方便修改我们直接写成定义符号的形式)                

      雷盘初始化(不光要初识化内部的雷盘,也要初识化用户看得到的雷盘)

     棋盘的初始化将雷的棋盘全初识化成0;将展示的棋盘全初识化为*

        埋雷

        埋雷需要用到随机数产生1到9的数字,具体需要用到rand函数来实现,埋在内部雷盘里

        展示雷盘

        要将让用户看到的雷盘通过数组的遍历打印出来,为了方便查看最好是将行号打印出来

        排雷        

        通过对所选择位置周围一圈的遍历相加得到的周围有几个雷显示在用户的棋盘上

        如图所示

 判断赢得条件

        在总共9*9得雷盘上放置十个雷,因此我们有9*9-10个位置可以选,所以我们需要把这71个格子都遍历过后才可以算将所有雷遍历成功,所以我们要循环71次,当达到次数得时候说明排雷成功

(具体可结合代码看)

        

//测试的源文件,用来控制整个游戏的流程
#define _CRT_SECURE_NO_WARNINGS
#include "game.h"

void game()
{
    char mine[ROWS][COLS] = { 0 };//用来埋雷
    char show[ROWS][COLS] = { 0 };//用来给用户展示
    //棋盘初识化
    InitBoard(mine, ROWS, COLS, '0');
    InitBoard(show, ROWS, COLS, '*');
    
    //埋雷
    Setmine(mine, ROWS, COLS);
    DisplayBoard(mine, ROW, COL);
    //给用户展示雷盘
    DisplayBoard(show, ROW, COL);
    //排雷
    Findmine(mine, show, ROW, COL);
    DisplayBoard(mine, ROW, COL);


}




void menu()
{
    printf("*************扫雷*************\n");
    printf("**1.PLAY**************2.EXIT**\n");
    printf("******************************\n");
}


void test()
{
    int input = 0;
    do {
        menu();
        scanf("%d", &input);
        switch (input)
        {
        case 1:
        {
            game();
            break;
        }
        case 2:
        {
            printf("游戏结束\n");
            break;
        }
        default:
        {
            printf("请重新输入游戏代码");
            break;
        }


        }

    } while (input);

}

int main()
{
    srand((unsigned int)time(NULL));
       test();
}

游戏 头文件

ROW COL指的是用户可操作的大小

ROWS COLS指的是系统为放置数组越界真正的棋盘大小

初始化数组:注意在这里的char board只是接收参数的一个形参名字可以跟实际参数名相同,但函数定义只能有一个所以形参的名字一定要慎重,要分得清,一个函数多次使用

//游戏的头文件,用来存放各种头文件,和函数的声明,符号的定义
#pragma once
#include <stdlib.h>
#include <time.h>
#include <stdio.h>

#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define EASY_COUNT_MINE 10


//初始化棋盘
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);

//埋雷
void setmine(char mine[ROWS][COLS], int rows, int cols);

//给用户展现棋盘
void DisplayBoard(char show[ROWS][COLS], int row, int col);

//排雷
void Findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);

游戏的源文件

//游戏的源文件,用来实现游戏的运行逻辑
#define _CRT_SECURE_NO_WARNINGS
#include "game.h"

void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{
    int i = 0;
    int j = 0;
    for (i = 0; i < rows; i++)
    {
        for (j = 0; j < cols; j++)
        {

            board[i][j] = set;
        }

    }

}


//埋雷

void Setmine(char mine[ROWS][COLS], int rows, int cols)
{
    int x = 0;
    int y = 0;
    int ret = EASY_COUNT_MINE;
    while (ret)
    {
        x = rand() % 9 + 1;
        y = rand() % 9 + 1;
        if (mine[x][y] == '0')
        {
            mine[x][y] = '1';
            ret--;
        }
    }
}

//给用户展示棋盘

void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
    int i = 0;
    int j = 0;
    for (i = 0; i <= row; i++)//打印行号
    {
        printf("%d ", i);
    }
    printf("\n");
    for (i = 1; i <= row; i++)//打印列号 
    {
        printf("%d ", i);
        for (j = 1; j <= col; j++)
        {
            printf("%c ", board[i][j]);
        }
        printf("\n");
    }

}

//排雷

int count_find(char mind[ROWS][COLS], int x, int y)
{
    return mind[x - 1][y] +
        mind[x - 1][y - 1] +
        mind[x][y - 1] +
        mind[x + 1][y - 1] +
        mind[x + 1][y] +
        mind[x + 1][y + 1] +
        mind[x][y + 1] +
        mind[x - 1][y + 1] - 8 * '0';
}

void  Findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
    printf("请输入坐标");
    int x = 0;
    int y = 0;
    int flag = 0;
    int ret = EASY_COUNT_MINE;

    while (flag<row* col-ret)
    {
        printf("请输入坐标");
        scanf("%d %d", &x, &y);
        if (x >= 1 && x <= row && y >= 1 && y <= row)
        {
            if (mine[x][y] == '1')
            {
                printf("很遗憾你被炸死了\n");
                break;
            }
            //排雷
            else
            {
                int n = count_find(mine, x, y);
                show[x][y] = n + '0';
                DisplayBoard(show, row, col);
                flag++;
            }
            
        }
        else
        {
            printf("输入错误,请重新输入");
        }
    }
    if (flag == row*col-EASY_COUNT_MINE)
    {
        printf("恭喜,排雷成功\n");

    }
}

注意事项

        1.同一个函数不能反复定义,可以重复调用,(要注意形参名得合理使用,不能混淆不清)

        2.如果传的参数挺多一定要将顺序排列清除,接收得时候也同样可以将实参的函数名,和形参的函数名写成一样,并且一定要注意顺序一样,不能出现货不对板的情况 

        3.在二维数组遍历打印的时候一定要记得换行,虽然是二维数组但是在打印的时候却不会换行需要手动来换。

        4.整型的数字如何转换成字符数字,只需要将数字加上字符'0'

        同理一个字符数字减去字符'0'可得整型数字 

        5.最最最重要的是搞清楚函数实参于形参

猜你喜欢

转载自blog.csdn.net/weixin_60359155/article/details/121280467