还记得上初中的时候,我们上微机课,我就喜欢玩小游戏:扫雷
今天我们用VS设计一个简单 9 x 9 扫雷游戏:
设计要求: 1. 9x9的数组地雷区.
2. 每次随机产生10的地雷点
3. 玩家每次可选择一个 点 ,若为雷点则直接结束游戏,否则,在该点显示出:该点一圈的雷点数
4. 但该点一圈的雷点数为‘0’时,再往一圈开拓
5. 当所有的非雷点被排完,而一个雷点也没有被踩到,则游戏结束:恭喜排雷成功!
6. 玩家排的第一个点,不会是雷点
C语言设计理念:
1. 9*9的雷区,我们应该定义 2 个 11x11的数组;mine[11][11],show[11][11]:
一个做为后台布雷数组:mine[11][11],一个作为雷区显示show[11][11]
解释(为什么用11*11的数组):
2 . 每次玩家输入两个数作为数组的一个点,然后进入函数判断该点是否为雷点
若为雷点,直接退出并输出:炸了!
若不是雷点,则进入get_mine_count(mine,show, x, y,&count)函数,判断该点一圈的是否有雷点:
若有雷点,直接返回雷点的个数;
若没有雷点,则再次调用get_mine_count(mine,show, x, y,&count)函数判断;
3. 开始定义一个count = 非雷泪的个数,在每次进入函数get_mine_count(mine,show, x, y,&count)时count减一
直到count == 0 时,就退出游戏并输出:恭喜,扫雷成功!
C程序:
game.h :
#ifndef __GAME_H__
#define __GAME_H__
#define COLS 11
#define ROWS 11
#define COL (COLS-2)
#define ROW (ROWS-2)
#define MAX 10
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
void init_board(char mine[ROWS][COLS],char set, int row, int col); //初始化
void set_mine(char mine[ROWS][COLS], 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,int *count);
#endif//__GAME_H__
test.c :
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
enum Option
{
EXIT,
PLAY
};
void menu(void)
{
printf("**********************************\n");
printf("********* 1 game 0 exit**********\n");
printf("**********************************\n");
}
void game(void)
{
int count = 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);
init_board(show,'*', ROWS, COLS);
display(show, ROWS, COLS);
printf("请输入一个坐标:");
scanf("%d%d",&x,&y);
if(((x>0)&&(x<10))&&((y>0)&&(y<10)))
{
set_mine(mine,x,y); //产生雷点(去掉玩家排的第一个点)
}
get_mine_count(mine,show, x, y,&count); //判断雷点
display(mine, ROWS, COLS);//测试代码;显示布雷情况
display(show, ROWS, COLS);
while (count>0)
{
printf("请输入一个坐标:");
scanf("%d%d",&x,&y);
if(((x>0)&&(x<10))&&((y>0)&&(y<10)))
{
if(mine[x][y] == '1')
{
printf("炸了!\n");
break;
}
else
{
get_mine_count(mine,show, x, y,&count); // 判断雷点
}
display(show, ROWS, COLS);
}
}
if(count == 0)
{
printf("恭喜扫雷成功!\n");
}
}
int Chose(void)
{
int tmp = 0;
do
{
menu();
printf("请选择:>");
scanf("%d",&tmp);
switch (tmp)
{
case PLAY:
{
game();
break;
}
case EXIT:
{
return 0;
}
default:
printf("输入有误:");
}
} while (1);
}
int main()
{
srand((unsigned int)time(NULL));
Chose();
return 0;
}
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]));
}
void set_mine(char mine[ROWS][COLS],int x, int y)
{
int count = MAX;
while(count>0)
{
int X = rand()%9+1;
int Y = rand()%9+1;
if((mine[X][Y] == '0')&&((X!=x)||(Y!=y)))
{
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,int *count) //利用递归判断雷点
{
(*count)--;
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>0)&&(x-1<10))&&((y-1>0)&&(y-1<10))&&(show[x-1][y-1]=='*'))
get_mine_count(mine,show, x-1, y-1,count);
if(((x>0)&&(x<10))&&((y-1>0)&&(y-1<10))&&(show[x][y-1]=='*'))
get_mine_count(mine,show, x, y-1,count);
if(((x+1>0)&&(x+1<10))&&((y-1>0)&&(y-1<10))&&(show[x+1][y-1]=='*'))
get_mine_count(mine,show, x+1, y-1,count);
if(((x+1>0)&&(x+1<10))&&((y>0)&&(y<10))&&(show[x+1][y]=='*'))
get_mine_count(mine,show, x+1, y,count);
if(((x+1>0)&&(x+1<10))&&((y+1>0)&&(y+1<10))&&(show[x+1][y+1]=='*'))
get_mine_count(mine,show, x+1, y+1,count);
if(((x>0)&&(x<10))&&((y+1>0)&&(y+1<10))&&(show[x][y+1]=='*'))
get_mine_count(mine,show, x, y+1,count);
if(((x-1>0)&&(x-1<10))&&((y+1>0)&&(y+1<10))&&(show[x-1][y+1]=='*'))
get_mine_count(mine,show, x-1, y+1,count);
if(((x-1>0)&&(x-1<10))&&((y>0)&&(y<10))&&(show[x-1][y]=='*'))
get_mine_count(mine,show, x-1, y,count);
}
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');
}
我们来玩一局:
雷点布置情况:
开始玩:下5 5位置,再踩一个雷点2 6位置:
我们在正常的玩一把: