C++实战,扫雷游戏详解

扫雷是一款家喻户晓的windows自带游戏,为了提高初学者学习兴趣,扫雷也是一个经典的C语言项目,今天就给大家分享一下。

我这个版本提供了可展开,第一次不会被炸死的功能。

小编是一个有着6年工作经验的工程师,关于C++,编程,自己有做材料的整合,一个完整的C++编程学习路线,学习资料和工具,能够进我的群7253,-91790收取,免费送给大家,希望你也能凭着自己的努力,成为下一个优秀的程序员

game.h----------

#define _CRT_SECURE_NO_WARNINGS 1

#ifndef __Mine_Clearance__

#define __Mine_Clearance__

#include <stdio.h>

#include <stdlib.h>

#include <time.h>

#define M 10//定义炸弹数量

#define ROW 10//定义棋盘大小

#define COL 10

void init(char mine[ROW][COL], char show[ROW][COL], char spread[ROW][COL]);//声明game.c中的函数。

void displayboard(char show[ROW][COL]);

void displaymine(char mine[ROW][COL]);

void Set_Mine(char mine[ROW][COL], int m);

void sweep_Mine(char mine[ROW][COL], char show[ROW][COL], int x, int y);

int check_win(char mine[ROW][COL], char show[ROW][COL], int m );

void prevent_first_death(char mine[ROW][COL], int x, int y);

int mineNum(char mine[ROW][COL], int x, int y);

void spread(char mine[ROW][COL], char show[ROW][COL], const x, const y); #endif

game.c

----------

#define _CRT_SECURE_NO_WARNINGS 1

#include "game.h"

void init(char mine[ROW][COL], char show[ROW][COL], char spread[ROW][COL])//初始化棋盘

{

int i = 0;

int j = 0;

for (i = 0; i < ROW-1 ; i++)//初始化9*9棋盘

{

for (j = 0; j < COL-1; j++)

{

mine[i][j] = ' ';

show[i][j] = '*';

}

}

}

void displayboard(char show[ROW][COL])//打印9*9棋盘

{

int i, j;

printf(" |");

for (i = 1; i < ROW; i++)

{

printf("%d ", i);

}

printf(" —|—————————— ");

for (i = 0; i < ROW-1; i++)

{

printf("%2d|", i + 1);

for (j = 0; j < COL-1; j++)

{

printf("%c ",show[i][j]);

}

printf(" ");

}

}

void displaymine(char mine[ROW][COL]) //展示雷盘 测试时使用

{

int i, j;

printf(" |");

for (i = 1; i <= 10; i++)

{

printf("%d ", i);

}

printf(" --|-------------------- ");

for (i = 0; i < ROW-1; i++)

{

printf("%2d|", i + 1);

for (j = 0; j < COL-1; j++)

{

printf("%c ", mine[i][j]);

}

printf(" ");

}

}

void Set_Mine(char mine[ROW][COL], int m) //随机放置雷,可以通过在头文件中修改 M 的值从而修改 m 的大小 改变布置的雷数

{

int x, y;

while(m)

{

x = rand() % 10 + 0;

y = rand() % 10 + 0;

if (mine[x][y] == ' ')

{

mine[x][y] = '$';

m--;

}

}

m = M;

}

int mineNum(char mine[ROW][COL], int x, int y) //统计周边8个格子的雷数

{

int count = 0;

if (mine[x - 1][y - 1] == '$')

{

count++;

}

if (mine[x - 1][y] == '$')

{

count++;

}

if (mine[x - 1][y + 1] == '$')

{

count++;

}

if (mine[x][y + 1] == '$')

{

count++;

}

if (mine[x + 1][y + 1] == '$')

{

count++;

}

if (mine[x + 1][y] == '$')

{

count++;

}

if (mine[x + 1][y - 1] == '$')

{

count++;

}

if (mine[x][y - 1] == '$')

{

count++;

}

return count;

}

void spread(char mine[ROW][COL], char show[ROW][COL], const x, const y) //展开函数

{

int ret = 0; int i = 0; int j = 0;

int a = x; int b = y;

if ( (x >= 0)

&& (x <= 9)

&& (y >= 0)

&& (y <= 9))

{

if (mine[x - 1][y - 1] == ' ') //如果该区域不是雷

{

a = x - 1;

b = y - 1;

ret = mineNum(mine, a, b); //返回以该区域为中心雷的数量

if (ret == 0) //若在这八个区域中哪个区域的周围8个格子无雷

{

show[a][b] = ' '; //如果周围没有雷就向玩家展示‘ ’空格

mine[a][b] = '0'; //将雷盘中的区域改为‘0’可方便测试用

spread(mine, show, a, b); //则将这个区域的坐标赋值给x和y,再次进行展开

}

else

{

show[a][b] = '0' + ret;

mine[a][b] = '0';

}

}

if (mine[x][y - 1] == ' ') //以下的另外七个区域同理

{

a = x;

b = y - 1;

ret = mineNum(mine, a, b);

if (ret == 0)

{

show[a][b] = ' ';

mine[a][b] = '0';

spread(mine, show, a, b);

}

else

{

show[a][b] = '0' + ret;

mine[a][b] = '0';

}

}

if (mine[x - 1][y] == ' ')

{

a = x - 1;

b = y;

ret = mineNum(mine, a, b);

if (ret == 0)

{

show[a][b] = ' ';

mine[a][b] = '0';

spread(mine, show, a, b);

}

else

{

show[a][b] = '0' + ret;

mine[a][b] = '0';

}

}

if (mine[x + 1][y - 1] == ' ')

{

a = x + 1;

b = y - 1;

ret = mineNum(mine, a, b);

if (ret == 0)

{

show[a][b] = ' ';

mine[a][b] = '0';

spread(mine, show, a, b);

}

else

{

show[a][b] = '0' + ret;

mine[a][b] = '0';

}

}

if (mine[x + 1][y] == ' ')

{

a = x + 1;

b = y;

ret = mineNum(mine, a, b);

if (ret == 0)

{

show[x + 1][y] = ' ';

mine[a][b] = '0';

spread(mine, show, a, b);

}

else

{

show[x + 1][y] = '0' + ret;

mine[a][b] = '0';

}

}

if (mine[x + 1][y + 1] == ' ')

{

a = x + 1;

b = y + 1;

ret = mineNum(mine, a, b);

if (ret == 0)

{

show[x + 1][y + 1] = ' ';

mine[a][b] = '0';

spread(mine, show, a, b);

}

else

{

show[x + 1][y + 1] = '0' + ret;

mine[a][b] = '0';

}

}

if (mine[x][y + 1] == ' ')

{

a = x;

b = y + 1;

ret = mineNum(mine, a, b);

if (ret == 0)

{

show[x][y + 1] = ' ';

mine[a][b] = '0';

spread(mine, show, a, b);

}

else

{

show[x][y + 1] = '0' + ret;

mine[a][b] = '0';

}

}

if (mine[x - 1][y + 1] == ' ')

{

a = x - 1;

b = y + 1;

ret = mineNum(mine, a, b);

if (ret == 0)

{

show[x - 1][y + 1] = ' ';

mine[a][b] = '0';

spread(mine, show, a, b);

}

else

{

show[x - 1][y + 1] = '0' + ret;

mine[a][b] = '0';

}

}

}

}

void sweep_Mine(char mine[ROW][COL], char show[ROW][COL], int x, int y) //扫雷函数

{

int ret = 0;

if ( mine[x][y] == ' ') //玩家没有踩到雷,即展示该区域周边的雷数,如果雷数为0就显示空格

{

ret=mineNum(mine, x, y);

if (ret == 0)

{

show[x][y] = ' ';

}

else

{

show[x][y] = '0' + ret; //如果有炸弹就显示炸弹的数量

}

spread(mine, show, x, y); //并在此调用展开函数,对周边区域进行展开

}

else if(mine[x][y] == '$')

{

show[x][y] = mine[x][y]; //如果玩家踩到炸弹就显示$

}

}

void prevent_first_death(char mine[ROW][COL],int x,int y) //防止玩家第一次被炸死

{

int m = 0; int n = 0;

if(mine[x][y] == '$')

{

do

{

m = rand() % 11 + 0;

n = rand() % 11 + 0; //如果玩家踩到雷,就重新随机一个没有雷的地方,将炸弹移动到那里

if (mine[m][n] == ' ')

{

mine[x][y] = ' '; //将该区域设置为空格

mine[m][n] = '$';

break;

}

}

while (1);

}

}

int check_win(char mine[ROW][COL], char show[ROW][COL], int m ) //判断输赢

{

int i, j,num;

num = M;

for (i = 0; i < ROW; i++)

{

for (j = 0; j < COL;j++)

{

if (show[i][j]=='*') //如果在展示棋盘上剩余 ‘*’的数量和雷数相同,那么就表示扫雷成功

{

num--;

}

else if (show[i][j] == '$') //如果显示盘上出现了 ‘$’说明玩家踩到了雷

{

return 1;

} else if(num == 0)

{

return 0;

}

}

} return -1;

}

test.c

----------

#define _CRT_SECURE_NO_WARNINGS 1

#include "game.h"

void mune()

{

printf("****************************************************************** ");

printf("————————1.开始扫雷——————0.退出游戏————————— ");

printf("****************************************************************** ");

}

void game()

{

char mine[ROW][COL];

char show[ROW][COL] ;

char spread[ROW][COL];

int x, y,m;

int row, col;

int count=0;

int ret;

row = ROW;

col = COL;

m = M;//将定义中的雷数M赋值给m

init(mine, show, spread);

Set_Mine(mine, m);

//displaymine(mine);//在测试中显示雷

do

{

displayboard(show);

count++;

printf("————————————————");

printf("开始扫雷>:");

scanf("%d %d", &x, &y);

getchar();

x = x - 1;

y = y - 1;

if (count == 1)

{

prevent_first_death(mine, x, y);

}

sweep_Mine(mine, show, x, y);

ret=check_win(mine,show,m);

if(ret == 1)

{

displayboard(show);

printf("————————————————");

printf("踩到炸弹 GG ");

break;

}

else if(ret == 0)

{

displayboard(show);

printf("————————————————");

printf("扫雷成功! ");

break;

}

} while (1);

}

int main()

{

int n = 0;

do

{

mune();

printf("——请选择:");

scanf("%d",&n);

printf("————————————————————————————————— ");

getchar();

if(n == 1)

{

game();

}

else if(n == 0)

{

break;

}

else

{

printf("输入有误 重新输入 ");

}

} while (1);

return 0;

}

欢迎批评指正!

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容