您的位置:首页 > 编程语言 > C语言/C++

使用C语言实现简单的扫雷程序

2018-04-06 16:22 686 查看
使用C语言实现简单的三子棋程序,主要是对二维数组的运用,我们需要一个头文件,两个源文件来实现。

game.h //包含函数的声明,宏定义

test.c //包含主函数,函数调用

game.c //包含函数的定义

整体思路

1.要完成一个简单的扫雷程序,我们需要创建两个二维数组,一个保存我们随机生成的雷,另外一个向外界展示。

//使用宏定义定义常量,方便之后对数组的使用
#define ROW 11 //雷
#define COL 11
#define ROWS 9 //棋盘
#define COLS 9
#define THUNDER 10 //雷数

char mine[ROW][COL] = { 0 }; //存雷数组
char show[ROWS][COLS] = { 0 }; //展示数组
Arr_init(mine, show, ROW, COL, ROWS, COLS); //数组初始化


2.完成对数组的初始化后,我们需要对雷进行放置

void Col_thu(char mine[ROW][COL], int row, int col, int thunder) //布置雷
{
int x, y;
int i = 0;
while (i < thunder) //存放雷的个数等于雷的个数
{
x = rand() % (row-2) + 1;
y = rand() % (col-2) + 1;
if (mine[x][y] == '0')
{
mine[x][y] = '1';
i++;
}
}
}


3.布置完雷后,我们需要打印所需要的棋盘

######存雷棋盘

void Print_che1(char mine[ROW][COL], int row, int col) //打印存雷棋盘
{
int i, j;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
printf("%2c", mine[i][j]);
}
printf("\n");
}
}


展示棋盘

void Print_che2(char show[ROWS][COLS], int rows, int cols) //打印展示棋盘
{
int i, j;
for (i = 0; i <= rows; i++) //方便我们输入坐标
{
printf("%2d", i);
}
printf("\n");
for (i = 0; i < rows; i++)
{
printf("%2d", i+1);
for (j = 0; j < cols; j++)
{
printf("%2c", show[i][j]);
}
printf("\n");
}
}


4.打印完棋盘后,我们开始扫雷了。

在扫雷的过程中,我们需要在没有找到雷时展示输入坐标周围的雷数并进行展开,同时,为了增加游戏的可玩性,当第一次就找到雷时,我们需要将雷转移到其他位置。

统计周围雷数

void Num_mines(char mine[ROW][COL],char show[ROWS][COLS], int x, int y) //计算输入坐标周围的雷数
{
int ch;
ch = mine[x - 1][y - 1] + mine[x - 1][y] + mine[x - 1][y + 1] + mine[x][y - 1] + mine[x][y + 1] + mine[x + 1][y - 1] + mine[x + 1][y] + mine[x + 1][y + 1] - 8 * '0';
show[x - 1][y - 1] = ch + 48; //数字对应的ASCLL与数字字符相差48
}


展开

void open_show(char mine[ROW][COL], char show[ROWS][COLS], int x, int y) //展开
{
if (mine[x - 1][y - 1] == '0') //左上角
{
if (x - 2 >= 0 && y - 2 >= 0) //防止越界情况
Num_mines(mine, show, x - 1, y - 1);
}
if (mine[x - 1][y] == '0') //上
{
if (x - 2 >= 0 && y - 1 >= 0)
Num_mines(mine, show, x - 1, y);
}
if (mine[x - 1][y + 1] == '0') //右上角
{
if (x - 2 >= 0 && y >= 0)
Num_mines(mine, show, x - 1, y + 1);
}
if (mine[x][y - 1] == '0') //左
{
if (x - 1>= 0 && y - 2 >= 0)
Num_mines(mine, show, x, y - 1);
}
if (mine[x][y + 1] == '0') //右
{
if (x - 1 >= 0 && y >= 0)
Num_mines(mine, show, x, y + 1);
}
if (mine[x + 1][y - 1] == '0') //左下角
{
if (x >= 0 && y - 2 >= 0)
Num_mines(mine, show, x + 1, y - 1);
}
if (mine[x + 1][y] == '0') //下
{
if (x >= 0 && y - 1 >= 0)
Num_mines(mine, show, x + 1, y);
}
if (mine[x + 1][y + 1] == '0') //右下角
{
if (x >= 0 && y >= 0)
Num_mines(mine, show, x + 1, y + 1);
}
}


扫雷

char Find_thu(char mine[ROW][COL], char show[ROWS][COLS], int row, int col, int i) //找雷
{
int x, y;
flag1:
printf("请玩家输入坐标");
scanf("%d %d", &x, &y);
flag:
if ((x > 0 && x <= 9) && (y>0 && y <= 9)) //判断输入坐标的正确性
{
if (mine[x][y] == '0')//没找到雷
{
Num_mines(mine, show, x, y); //计算输入坐标周围的雷数
open_show(mine, show, x, y);
return '0';
}
else //找到雷
{
if (i == 0) //第一个就找到雷
{
mine[x][y] = '0';
while (1)
{
int a, b;
a = rand() % (row - 2) + 1;
b = rand() % (col - 2) + 1;
if (mine[a][b] == '0')
{
mine[a][b] = '1';
goto flag;
}
}
}
else
{
show[x - 1][y - 1] = '1';
return '1';
}
}
}
else
{
printf("输入错误\n");
goto flag1;
}
}


确定大致思路后,我们完成程序的流程部分,并放入我们所创建的文件中。

代码如下:

game.h //包含函数的声明,宏定义

#ifndef _GAME_H__
#define _GAME_H__

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

#define ROW 11//雷
#define COL 11
#define ROWS 9 //棋盘
#define COLS 9
#define THUNDER 10 //雷数

void Arr_init(char mine[ROW][COL], char show[ROWS][COLS], int row, int col, int rows, int cols); //数组初始化
void Col_thu(char mine[ROW][COL], int row, int col, int thunder); //布置雷
void Print_che1(char mine[ROW][COL], int row, int col); //打印存雷棋盘
void Print_che2(char show[ROWS][COLS], int rows, int cols); //打印展示棋盘
char Find_thu(char mine[ROW][COL], char show[ROWS][COLS], int row, int col, int i); //找雷

#endif // GAME_H__


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()  //游戏函数
{
int i;
char mine[ROW][COL] = {0};//存雷数组
char show[ROWS][COLS] = { 0 };//展示数组
Arr_init(mine, show, ROW, COL, ROWS, COLS);//数组初始化
Col_thu(mine, ROW, COL, THUNDER); //布置雷
Print_che2(show, ROWS, COLS); //打印展示棋盘
for (i = 0; i < ROWS * COLS - THUNDER; i++)
{
char n;
n = Find_thu(mine, show, ROW, COL, i); //找雷
Print_che2(show, ROWS, COLS); //打印展示棋盘
if (n == '0')
{
printf("_______________________\n");
}
else
{
printf("你踩到雷了,游戏结束\n");
Print_che1(mine, ROW, COL); //打印存雷棋盘
break;
}
}
if (i == ROWS * COLS - THUNDER)
printf("游戏成功\n");
}

void test() //游戏流程函数
{
int input;
srand((unsigned)time(NULL));
do
{
menu();
printf("请输入选择:");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
break;
default:
printf("输入错误,请重新输入\n");
}
} while (input);
}

int main()
{
test();
system("pause");
return 0;
}


game.c //包含函数的定义

#include "game.h"

void Arr_init(char mine[ROW][COL], char show[ROWS][COLS], int row, int col, int rows, int cols)//数组初始化
{
int i, j;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
mine[i][j] = '0';//改变存雷数组
}
}
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
show[i][j] = '*';//改变展示数组
}
}
}

void Col_thu(char mine[ROW][COL], int row, int col, int thunder) //布置雷 { int x, y; int i = 0; while (i < thunder) //存放雷的个数等于雷的个数 { x = rand() % (row-2) + 1; y = rand() % (col-2) + 1; if (mine[x][y] == '0') { mine[x][y] = '1'; i++; } } }

void Print_che1(char mine[ROW][COL], int row, int col) //打印存雷棋盘 { int i, j; for (i = 0; i < row; i++) { for (j = 0; j < col; j++) { printf("%2c", mine[i][j]); } printf("\n"); } }

void Print_che2(char show[ROWS][COLS], int rows, int cols) //打印展示棋盘
{
int i, j;
for (i = 0; i <= rows; i++)//方便我们输入坐标
{
printf("%2d", i);
}
printf("\n");
for (i = 0; i < rows; i++)
{
printf("%2d", i+1);
for (j = 0; j < cols; j++)
{
printf("%2c", show[i][j]);
}
printf("\n");
}
}

void Num_mines(char mine[ROW][COL],char show[ROWS][COLS], int x, int y)//计算输入坐标周围的雷数
{
int ch;
ch = mine[x - 1][y - 1] + mine[x - 1][y] + mine[x - 1][y + 1] + mine[x][y - 1] + mine[x][y + 1] + mine[x + 1][y - 1] + mine[x + 1][y] + mine[x + 1][y + 1] - 8 * '0';
show[x - 1][y - 1] = ch + 48;//数字对应的ascll与数字字符相差48
}

void open_show(char mine[ROW][COL], char show[ROWS][COLS], int x, int y)//展开
{
if (mine[x - 1][y - 1] == '0')//左上角
{
if (x - 2 >= 0 && y - 2 >= 0) //防止越界情况
Num_mines(mine, show, x - 1, y - 1);
}
if (mine[x - 1][y] == '0')//上
{
if (x - 2 >= 0 && y - 1 >= 0)
Num_mines(mine, show, x - 1, y);
}
if (mine[x - 1][y + 1] == '0')//右上角
{
if (x - 2 >= 0 && y >= 0)
Num_mines(mine, show, x - 1, y + 1);
}
if (mine[x][y - 1] == '0')//左
{
if (x - 1>= 0 && y - 2 >= 0)
Num_mines(mine, show, x, y - 1);
}
if (mine[x][y + 1] == '0')//右
{
if (x - 1 >= 0 && y >= 0)
Num_mines(mine, show, x, y + 1);
}
if (mine[x + 1][y - 1] == '0')//左下角
{
if (x >= 0 && y - 2 >= 0)
Num_mines(mine, show, x + 1, y - 1);
}
if (mine[x + 1][y] == '0')//下
{
if (x >= 0 && y - 1 >= 0)
Num_mines(mine, show, x + 1, y);
}
if (mine[x + 1][y + 1] == '0')//右下角
{
if (x >= 0 && y >= 0)
Num_mines(mine, show, x + 1, y + 1);
}
}

char Find_thu(char mine[ROW][COL], char show[ROWS][COLS], int row, int col, int i)//找雷
{
int x, y;
flag1:
printf("请玩家输入坐标");
scanf("%d %d", &x, &y);
flag:
if ((x > 0 && x <= 9) && (y>0 && y <= 9))//判断输入坐标的正确性
{
if (mine[x][y] == '0')//没找到雷
{
Num_mines(mine, show, x, y);//计算输入坐标周围的雷数
open_show(mine, show, x, y);
return '0';
}
else //找到雷
{
if (i == 0)//第一个就找到雷
{
mine[x][y] = '0';
while (1)
{
int a, b;
a = rand() % (row - 2) + 1;
b = rand() % (col - 2) + 1;
if (mine[a][b] == '0')
{
mine[a][b] = '1';
goto flag;
}
}
}
else
{
show[x - 1][y - 1] = '1';
return '1';
}

}
}
else
{
printf("输入错误\n");
goto flag1;
}
}


到这里,我们的程序就完成了,我们看看程序的效果





以上就是一个简单的扫雷程序,多有不足之处,还望指教。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: