首先,演示一下:
要写出扫雷,首先要对扫雷有一个基本的认识。
分析一下:
(1):初始化棋盘
初始化棋盘分为两步:第一步,我们给一个全为“*”的棋盘;第二步,我们考虑到在计算雷周围数目的数目的时候,位于边界的位置不好求,所以我们在棋盘的每一边都增加1行或者1列。
(2)布雷:
布雷我们主要是在随机产生的位置上布雷,所以我们就要用到rand()。
(3):打印棋盘
打印棋盘也分为两步:第一步,我们要计算点开一个格子以后周围雷的数目;
第二步,如果我们点开的格子是0,就用递归调用显示他周围的一片空白区域。
(4):判断
如果踩中雷,我们就说结束了;如果排完雷,我们就说排雷成功了。
这四步呢,一定要捋清楚!
在这里呢,我用到了两个菜单,其实原理很简单,只是把雷的个数改变了
程序代码:
game.h
#ifndef __GAME_H__
#define __GAME_H__
#define COLS 11
#define ROWS 11
#define COL (COLS-2)
#define ROW (ROWS-2)
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#pragma warning (disable:4996)
void init_board(char mine[ROWS][COLS], char set, int row, int col);//初始化棋盘
void set_mine(char mine[ROWS][COLS],int max, int x, int y);//布雷
void display(char mine[ROWS][COLS], int row, int col);//打印棋盘
void get_mine_count(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y);//统计周围雷的数目以及为0时的处理
#endif//__GAME_H__
game.c
#include"game.h"
void init_board(char mine[ROWS][COLS], char set, int row, int col)
{
memset(mine, set, row*col*sizeof(mine[0][0]));//初始化棋盘,set表示对棋盘布置0还是*
}
void set_mine(char mine[ROWS][COLS], int max,int x, int y)//布雷定义雷的个数,随机产生一个位置布雷,依次递减
{
int count = max;
while (count>0)
{
int X = rand() % 9 + 1;
int Y = rand() % 9 + 1;
if ((X != x) && (Y != y) && mine[X][Y] == '0')//避免新的雷步到了原来的位置上
{
mine[X][Y] = '1';
count--;
}
}
}
void display(char mine[ROWS][COLS], int row, int col)//打印棋盘,为了美观在这里要注意空格
{
int x = 0;
int y = 0;
printf(" ");
for (x = 1; x <= 9; x++)
{
printf("%d ", x);
}
printf("\n");
for (x = 1; x <= 9; x++)
{
printf("%d ", x);
for (y = 1; y <= 9; y++)
{
printf("%c ", mine[x][y]);
}
printf("\n");
}
}
void get_mine_count(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{
//玩家选择了一个位置以后,如果该位置为'0',就把空格赋给它,表示空白。然后通过递归显示周围的一片
if ((mine[x - 1][y - 1] + mine[x][y - 1] + mine[x + 1][y - 1] + mine[x + 1][y] + mine[x + 1][y + 1] + mine[x][y + 1] + mine[x - 1][y + 1] + mine[x - 1][y] - 7 * '0') == '0')
{
show[x][y] = ' ';
if (((x - 1>=1) && (x - 1<=ROW)) && ((y - 1>=1) && (y - 1<=COL)) && (show[x - 1][y - 1] == '*'))
get_mine_count(mine, show, x - 1, y - 1);
if (((x >= 1) && (x <= ROW)) && ((y - 1 >= 1) && (y - 1 <= COL)) && (show[x][y - 1] == '*'))
get_mine_count(mine, show, x, y - 1);
if (((x + 1 >= 1) && (x + 1 <= ROW)) && ((y - 1 >= 1) && (y - 1 <= COL)) && (show[x + 1][y - 1] == '*'))
get_mine_count(mine, show, x + 1, y - 1);
if (((x + 1 >= 1) && (x + 1 <= ROW)) && ((y >= 1) && (y <= COL)) && (show[x + 1][y] == '*'))
get_mine_count(mine, show, x + 1, y);
if (((x + 1 >= 1) && (x + 1 <= ROW)) && ((y + 1 >= 1) && (y + 1 <= COL)) && (show[x + 1][y + 1] == '*'))
get_mine_count(mine, show, x + 1, y + 1);
if (((x >= 1) && (x <= ROW)) && ((y + 1 >= 1) && (y + 1 <= COL)) && (show[x][y + 1] == '*'))
get_mine_count(mine, show, x, y + 1);
if (((x - 1 >= 1) && (x - 1 <= ROW)) && ((y + 1 >= 1) && (y + 1 <= COL)) && (show[x - 1][y + 1] == '*'))
get_mine_count(mine, show, x - 1, y + 1);
if (((x - 1 >= 1) && (x - 1 <= ROW)) && ((y >= 1) && (y <= COL)) && (show[x - 1][y] == '*'))
get_mine_count(mine, show, x - 1, y);
}
else show[x][y] = (mine[x - 1][y - 1] + mine[x][y - 1] + mine[x + 1][y - 1] + mine[x + 1][y]
+ mine[x + 1][y + 1] + mine[x][y + 1] + mine[x - 1][y + 1] + mine[x - 1][y] - 7 * '0');
}
test.c
#include"game.h"
void menu()//菜单
{
printf("**********************************\n");
printf("********* 1.play 0.exit**********\n");
printf("**********************************\n");
}
void second_menu()//二级菜单显示
{
printf("**********************************\n");
printf(" 1.简单 \n");
printf(" 2.中等 \n");
printf(" 3.困难 \n");
printf("**********************************\n");
}
void game(num)//游戏环节
{
int max = num;//在这里实现了改变雷的个数,也是选择困难度传参的地方
int blank = COL*ROW - max;
int x = 0;
int y = 0;
char mine[ROWS][COLS] = { 0 };
char show[ROWS][COLS] = { 0 };
init_board(mine, '0', ROWS, COLS);//初始化11*11棋盘为0,考虑到最角落统计周围8格的总数
init_board(show, '*', ROWS, COLS);//初始化9*9的棋盘为*
display(show, ROWS, COLS);//打印棋盘
while (blank)//循环条件是你排除的只剩下雷了
{
int i = 1;
printf("请输入一个坐标:");
scanf("%d%d", &x, &y);
set_mine(mine, max, x, y);//输入坐标以后在布雷,就免去了玩家第一次输入就踩雷
if (((x >= 1) && (x <= ROW)) && ((y >= 1) && (y <= COL)))
{
if (mine[x][y] == '1')
{
printf("你选中了雷!\n");
break;
}
else
{
get_mine_count(mine, show, x, y);//统计周围雷的数目以及打开0时的处理
}
blank--;
display(show, ROWS, COLS);
//display(mine, ROWS, COLS);//测试雷数,也就是直接看结果
}
else
{
printf("你输入的坐标有误!\n");
}
}
if (blank == 0)
{
printf("德玛西亚!\n");
}
}
void test()//对菜单进行选择
{
int input = 0;
srand((unsigned int)time(NULL));
do
{
menu();
printf("请选择开始还是退出:");
scanf("%d", &input);
switch (input)
{
case 1:
{
int input = 0;
do{
second_menu();
int easy_mine_num = 10;
int medium_mine_num = 15;
int difficult_mine_num = 20;
printf("请选择困难度:");
scanf("%d", &input);
switch (input)
{
case 1:
game(easy_mine_num);
input = 0;
break;
case 2:
game(medium_mine_num);
input = 0;
break;
case 3:
game(difficult_mine_num);
input = 0;
break;
default:
printf("输入有误,重新开始:\n");
}
} while (input);
}
break;
case 0:
break;
default:
printf("您的选择有误,请重新选择1:\n");
}
} while (input);
}
int main()
{
test();
system("pause");
return 0;
}