目录
游戏基本逻辑
#include"game.h"
void menu()
{
printf("******* 扫雷游戏 *********\n");
printf("***********************************\n");
printf("******* 1.play *********\n");
printf("******* 0.exit *********\n");
printf("***********************************\n");
}
void game()
{
char mine[ROWS][COLS];
char show[ROWS][COLS];
//初始化
board(mine, ROW, COL,'0');
board(show, ROW, COL,'*');
//打印棋盘
displayboard(show, ROW, COL);
//设置雷
set_mine(mine, ROW, COL);
//排除雷
finemine(mine, show, ROW, COL);
}
int main()
{
int input = 1;
srand((unsigned int)time(NULL));
do
{
menu();
printf("请选择=》");
scanf_s("%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 *********\n");
printf("******* 0.exit *********\n");
printf("***********************************\n");
}
选择1:玩游戏
选择0:退出游戏
创建棋盘
//防止排查时出现数组越界,将棋盘的大小扩大
#define ROWS 11
#define COLS 11
//但真正可用的棋盘大小是9行9列的
#define ROW ROWS-2
#define COL COLS-2
//创建两个数组
char mine[ROWS][COLS];//存储随机设置的雷的信息
char show[ROWS][COLS];//展示给玩家的棋盘,存储排查出的雷信息
【说明】:选择宏定义的方式,方便程序的修改
初始化棋盘
board(mine, ROW, COL,'0');
board(show, ROW, COL,'*');
void board(char mine[ROWS][COLS], int row, int col,char set)
{
int i = 0;
int j = 0;
for (i = 1; i <= row; i++)
{
for (j = 1; j <= col; j++)
{
mine[i][j] = set;
}
}
}
【注意】:需要初始化两个区域,一个用于存放布置好雷的信息,初始时用字符0;
另外一个用于存放排查出雷的信息,初始时用字符*
打印棋盘
void displayboard(char mine[ROWS][COLS], int row, int col)
{
int i = 0;
int j = 0;
printf("----------扫雷游戏------------\n");
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 ", mine[i][j]);
}
printf("\n");
}
}
【说明】:打印行号和列号方便玩家使用
设置雷
//随机设置的雷的个数
#define easy_mine_count 10
void set_mine(char mine[ROWS][COLS], int row, int col)
{
int i= easy_mine_count;
while(i>0)
{
int x=rand()%9+1;
int y=rand()%9+1;
if (mine[x][y] == '0')
{
mine[x][y] = '1';
i--;
}
}
}
【注意】:
要在test函数中使用srand((unsigned int)time(NULL));将时间作为随机数种子,确保得到的行列坐标随机值。
这个在之前关于猜数字的游戏中详细讲解过,所以在这里就不过多赘述了。
排除雷
主要逻辑
void finemine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
while (1)
{
int x;
int y;
choose(show);//对疑似雷的坐标进行标记
printf("请输入排查坐标:");
scanf_s("%d%d", &x, &y);
if (x > 0 && x < 10 && y>0 && y < 10)
{
if (mine[x][y] == '0')
{
Number_mine_around(mine, show, x, y);//判断周围雷个数,是否进行展开
displayboard(show, ROW, COL);
}
else
{
printf("你被炸死了!!!\n");
displayboard(mine, ROW, COL);
break;
}
}
else
printf("坐标非法,请重新输入\n");
//判断剩余未知区域的个数,个数为雷数时玩家赢
if (easy_mine_count == count_show_mine(show, ROW, COL))
{
printf("恭喜你,你赢了!!!\n");
displayboard(mine, ROW, COL);
break;
}
}
}
坐标标记函数
//对疑似雷的坐标进行标记
void choose(char show[ROWS][COLS])
{
while (1)
{
int flag = 0;
printf("0.排查坐标 1.标记坐标 2.取消标记\n");
printf("请选择:");
scanf_s("%d", &flag);
if (flag == 1)
{
do
{
int a = 0;
int b = 0;
printf("请输入要标记坐标:");
scanf_s("%d%d", &a, &b);
if (show[a][b] == '*' && a > 0 && a <= ROW && b > 0 && b <= COL)
{
show[a][b] = '#';
displayboard(show, ROW, COL);
break;
}
else if (show[a][b] != '*' && a > 0 && a <= ROW && b > 0 && b <= COL)
{
printf("该坐标已展示,请重新输入\n");
}
else
{
printf("坐标非法,请重新输入\n");
}
} while (1);
}
else if (flag == 0)
{
break;
}
else if (flag == 2)
{
do
{
int a = 0;
int b = 0;
printf("请输入要取消标记坐标:");
scanf_s("%d%d", &a, &b);
if (show[a][b] == '#' && a > 0 && a <= ROW && b > 0 && b <= COL)
{
show[a][b] = '*';
displayboard(show, ROW, COL);
break;
}
else if (show[a][b] != '#' && a > 0 && a <= ROW && b > 0 && b <= COL)
{
printf("该坐标未标记,请重新输入\n");
break;
}
else
{
printf("坐标非法,请重新输入\n");
break;
}
} while (1);
}
else
{
printf("输入错误,请重新输入\n");
}
}
}
展开函数
void Number_mine_around(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{
int i;
int j;
int n = 0;
//判断周围雷个数
for (i = -1; i < 2; i++)
{
for (j = -1; j < 2; j++)
{
if (mine[x + i][y + j] == '1')
{
n++;
}
}
}
show[x][y] = n + '0';
//若周围没有雷,则展开一片
if (show[x][y] == '0')
{
if (x < ROWS && x>0 && y < COLS && y - 1>0 && show[x][y - 1] == '*')
{
Number_mine_around(mine, show, x, y-1);
}
if (x < ROWS && x>0 && y + 1< COLS && y>0 && show[x][y+1] == '*')
{
Number_mine_around(mine, show, x, y + 1);
}
if (x < ROWS && x-1>0 && y < COLS && y>0 && show[x-1][y] == '*')
{
Number_mine_around(mine, show, x - 1, y);
}
if (x + 1< ROWS && x>0 && y < COLS && y>0 && show[x+1][y] == '*')
{
Number_mine_around(mine, show, x + 1, y);
}
}
}
胜负判断函数
//判断剩余未知区域的个数,个数为雷数时玩家赢
int count_show_mine(char show[ROWS][COLS], int row, int col)
{
int count = 0;
int i = 0;
int j = 0;
for (i = 1; i <= row; i++)
{
for (j = 1; j <= col; j++)
{
if (show[i][j] == '*')
{
count++;
}
}
}
return count;
}
完整源代码
声明
#pragma once
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#define ROWS 11
#define COLS 11
#define ROW ROWS-2
#define COL COLS-2
//随机设置的雷的个数
#define easy_mine_count 10
//初始化
void board(char mine[ROWS][COLS],int row,int col,char set);
//打印棋盘
void displayboard(char mine[ROWS][COLS],int row,int col);
//设置雷
void set_mine(char mine[ROWS][COLS],int row,int col);
//排除雷
void finemine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
实现
#include"game.h"
void board(char mine[ROWS][COLS], int row, int col,char set)
{
int i = 0;
int j = 0;
for (i = 1; i <= row; i++)
{
for (j = 1; j <= col; j++)
{
mine[i][j] = set;
}
}
}
void displayboard(char mine[ROWS][COLS], int row, int col)
{
int i = 0;
int j = 0;
printf("----------扫雷游戏------------\n");
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 ", mine[i][j]);
}
printf("\n");
}
}
void set_mine(char mine[ROWS][COLS], int row, int col)
{
int i= easy_mine_count;
while(i>0)
{
int x=rand()%9+1;
int y=rand()%9+1;
if (mine[x][y] == '0')
{
mine[x][y] = '1';
i--;
}
}
}
void Number_mine_around(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{
int i;
int j;
int n = 0;
//判断周围雷个数
for (i = -1; i < 2; i++)
{
for (j = -1; j < 2; j++)
{
if (mine[x + i][y + j] == '1')
{
n++;
}
}
}
show[x][y] = n + '0';
//若周围没有雷,则展开一片
if (show[x][y] == '0')
{
if (x < ROWS && x>0 && y < COLS && y - 1>0 && show[x][y - 1] == '*')
{
Number_mine_around(mine, show, x, y-1);
}
if (x < ROWS && x>0 && y + 1< COLS && y>0 && show[x][y+1] == '*')
{
Number_mine_around(mine, show, x, y + 1);
}
if (x < ROWS && x-1>0 && y < COLS && y>0 && show[x-1][y] == '*')
{
Number_mine_around(mine, show, x - 1, y);
}
if (x + 1< ROWS && x>0 && y < COLS && y>0 && show[x+1][y] == '*')
{
Number_mine_around(mine, show, x + 1, y);
}
}
}
void choose(char show[ROWS][COLS])
{
while (1)
{
int flag = 0;
printf("0.排查坐标 1.标记坐标 2.取消标记\n");
printf("请选择:");
scanf_s("%d", &flag);
if (flag == 1)
{
do
{
int a = 0;
int b = 0;
printf("请输入要标记坐标:");
scanf_s("%d%d", &a, &b);
if (show[a][b] == '*' && a > 0 && a <= ROW && b > 0 && b <= COL)
{
show[a][b] = '#';
displayboard(show, ROW, COL);
break;
}
else if (show[a][b] != '*' && a > 0 && a <= ROW && b > 0 && b <= COL)
{
printf("该坐标已展示,请重新输入\n");
}
else
{
printf("坐标非法,请重新输入\n");
}
} while (1);
}
else if (flag == 0)
{
break;
}
else if (flag == 2)
{
do
{
int a = 0;
int b = 0;
printf("请输入要取消标记坐标:");
scanf_s("%d%d", &a, &b);
if (show[a][b] == '#' && a > 0 && a <= ROW && b > 0 && b <= COL)
{
show[a][b] = '*';
displayboard(show, ROW, COL);
break;
}
else if (show[a][b] != '#' && a > 0 && a <= ROW && b > 0 && b <= COL)
{
printf("该坐标未标记,请重新输入\n");
break;
}
else
{
printf("坐标非法,请重新输入\n");
break;
}
} while (1);
}
else
{
printf("输入错误,请重新输入\n");
}
}
}
void finemine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
while (1)
{
int x;
int y;
choose(show);
printf("请输入排查坐标:");
scanf_s("%d%d", &x, &y);
if (x > 0 && x < 10 && y>0 && y < 10)
{
if (mine[x][y] == '0')
{
Number_mine_around(mine, show, x, y);
displayboard(show, ROW, COL);
}
else
{
printf("你被炸死了!!!\n");
displayboard(mine, ROW, COL);
break;
}
}
else
printf("坐标非法,请重新输入\n");
if (easy_mine_count == count_show_mine(show, ROW, COL))
{
printf("恭喜你,你赢了!!!\n");
displayboard(mine, ROW, COL);
break;
}
}
}
int count_show_mine(char show[ROWS][COLS], int row, int col)//判断剩余未知区域的个数,个数为雷数时玩家赢
{
int count = 0;
int i = 0;
int j = 0;
for (i = 1; i <= row; i++)
{
for (j = 1; j <= col; j++)
{
if (show[i][j] == '*')
{
count++;
}
}
}
return count;
}
逻辑
#include"game.h"
void menu()
{
printf("******* 扫雷游戏 *********\n");
printf("***********************************\n");
printf("******* 1.play *********\n");
printf("******* 0.exit *********\n");
printf("***********************************\n");
}
void game()
{
char mine[ROWS][COLS];
char show[ROWS][COLS];
//初始化
board(mine, ROW, COL,'0');
board(show, ROW, COL,'*');
//打印棋盘
//displayboard(mine, ROW, COL);
displayboard(show, ROW, COL);
//设置雷
set_mine(mine, ROW, COL);
//displayboard(mine, ROW, COL);
//排除雷
finemine(mine, show, ROW, COL);
}
int main()
{
int input = 1;
srand((unsigned int)time(NULL));
do
{
menu();
printf("请选择=》");
scanf_s("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出程序\n");
break;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (input);
return 0;
}