要求:
1>第一次下子,不炸死。
2>坐标周围没雷,可以实现展开。
实现
1.用一个二维字符数组mine[ROWS] [COLS]来存储雷,现在我们用字符1来表示有雷,字符0表示无雷。再用一个二维字符数组show[ROWS][COLS]将所有的元素初始化为*,并打印作为展现给玩家的。同时用show数组来表示对应的mine数组中周围雷即字符0的个数。对于边缘的格子无法计算雷的个数,因此只需再增加2行2列即可,即ROWS=COLS=12 。
2.第一次下子,不炸死
在设置雷前先让玩家输入一个坐标(x,y),再设置雷,然后再计算周围雷的个数,即相当于第一次无效。
3.坐标周围没雷,可以实现展开。
可用递归函数实现。
4.此游戏还存在一个问题,若确定一个坐标不是雷,则可重复输入此坐标直到玩家胜利。因为计数器自增的条件是只要满足x,y对应的位置为非雷。此时只需增加一个循环即可。
while (show[x][y]!='*')
{
printf("输入非法,请重新输入:");
scanf("%d%d", &x, &y);
printf("\n");
}
1 game.h
game.h
#define _CRT_SECURE_NO_WARNINGS
#ifndef __GAME_H__
#define __GAME_H__
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#define ROW 10
#define COL 10
#define ROWS ROW+2
#define COLS COL+2
#define COUNT 10
void InitBoard(char arr[ROWS][COLS], int row, int col, char set);
void Display(char arr[ROWS][COLS], int row, int col);
void Setmine(char arr[ROWS][COLS], int row, int col);
void blank(char mine[ROWS][COLS], char show[ROWS][COLS] ,int x, int y);
#endif //__GAME_H__
2 test.c
test.c
#include "game.h"
int GetMineCount(char mine[ROWS][COLS], int x, int y)//求mine[x][y]周围8个元素中雷的总个数
{
return mine[x-1][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]-7*'0';
}
void game()
{
int ret = 0;
int count = 0;
int x = 0;
int y = 0;
char show[ROWS][COLS];
char mine[ROWS][COLS];
InitBoard(mine, ROWS, COLS, '0');//初始化数组,全置为字符0
InitBoard(show, ROWS, COLS, '*');//初始化数组
Display(show, ROWS, COLS);//打印数组,注意打印的行和列都是序号1到10的数组元素
Display(mine, ROWS, COLS);//打印雷的具体分布,便于调试
flag: printf("请输入坐标(x,y)");
scanf("%d%d", &x,&y);
if (x>=1&&x<=10&&y>=1&&y<=10)//对输入的合法性进行检验
{
Setmine(mine, ROWS, COLS);//随机设置雷的位置
show[x][y] = GetMineCount(mine, x, y);//将(x,y)处*赋值为雷的个数
blank(mine, show, x, y);//实现展开的函数,递归函数
}
else
{
printf("输入有误\n");
goto flag;
}
Display(show, ROWS, COLS);
Display(mine, ROWS, COLS);
while (count<ROW*COL-COUNT)
{
printf("请输入坐标(x,y)");
scanf("%d%d", &x,&y);
while (show[x][y]!='*')
{
printf("输入非法,请重新输入:");
scanf("%d%d", &x, &y);
printf("\n");
}
if (x>=1&&x<=10&&y>=1&&y<=10)
{
if (mine[x][y] == '0')
{
blank(mine, show, x, y);
Display(show, ROWS, COLS);
Display(mine, ROWS, COLS);
count++;
}
else
{
printf("踩雷了,失败\n");
Display(mine, ROWS, COLS);
return ;
}
}
else
{
printf("输入有误\n");
}
}
printf("恭喜,扫雷成功!\n");
}
void menu()
{
printf("********************************\n");
printf("*********1.play 0.exit********\n");
printf("********************************\n");
}
void test()
{
int input = 0;
srand((unsigned) time(NULL));
do
{
menu();
printf("请选择:");
scanf("%d", &input);
switch(input)
{
case 0:
break;
case 1:
game();
break;
default :
printf("输入非法,请重新输入\n");
}
}while(input);//可以不断玩游戏
}
int main()
{
test();
return 0;
}
3 game.c//函数具体实现
game.c
#include "game.h"
void InitBoard(char arr[ROWS][COLS], int row, int col, char set)//初始化数组函数
{
int i = 0;
int j = 0;
for (i=0; i<ROWS ; i++)
{
for (j=0; j<COLS; j++)
{
arr[i][j] = set;
}
}
}
void Display(char arr[ROWS][COLS], int row, int col)
{
int i = 0;
int j = 0;
printf(" ");
for (i=1; i<=row-2; i++)
{
printf("%d ", i);
}
printf("\n");
for (i=1; i<=row-2; i++)
{
printf("%2d ", i);
for (j=1; j<=col-2; j++)
{
printf("%c ",arr[i][j]);
}
printf("\n");
}
}
void Setmine(char arr[ROWS][COLS], int row, int col)
{
int count = 0;
int i = 0;
int j = 0;
while (count<COUNT)
{
i = rand()%10+1;
j = rand()%10+1;
if (arr[i][j]=='0')
{
arr[i][j] = '1';
count++;
}
}
}
void blank(char mine[ROWS][COLS], char show[ROWS][COLS] ,int x, int y)//递归调用
{
if (mine[x][y]=='0')
{
show[x][y] = GetMineCount(mine, x, y);
if (show[x][y] == '0')
{
show[x][y] = ' ';
if (show[x - 1][y - 1] == '*')
{
blank(mine, show, x - 1, y - 1);
}
if (show[x - 1][y] == '*')
{
blank(mine, show, x - 1, y);
}
if (show[x - 1][y + 1] == '*')
{
blank(mine, show, x - 1, y + 1);
}
if (show[x][y + 1] == '*')
{
blank(mine, show, x, y + 1);
}
if (show[x + 1][y + 1] == '*')
{
blank(mine, show, x + 1, y + 1);
}
if (show[x + 1][y] == '*')
{
blank(mine, show, x + 1, y);
}
if (show[x + 1][y - 1] == '*')
{
blank(mine, show, x + 1, y - 1);
}
if (show[x][y - 1] == '*')
{
blank(mine, show, x, y - 1);
}
}
}
}
)
此图未运行完全。