扫雷(C语言版)
这个扫雷是在9*9的格子里,一共有10个地雷.
游戏功能:输入扫雷坐标后可以将周围没有地雷的坐标展开,可以标记可能有地雷的坐标,标记错了可以取消标记,利用清屏函数实现每次输完正确的坐标后可以清空屏幕再打印存放地雷的棋盘,
game.h(头文件)
void lay_mines (char arr1[H][L],int h,int l);//布雷
void display_board(char arr[H][L], int h, int l); //打印数组
void find_mines(char arr1[H][L], char arr2[H][L], int h, int l); //输入坐标扫雷
void sign_mines(char arr1[H][L], char arr2[H][L], int h, int l);//标记雷
void not_sign_mines(char arr1[H][L], char arr2[H][L], int h, int l);//取消标记
void unfold_mines (char arr1[H][L], char arr2[H][L], int h, int l,int a, int b);//展开周围没有雷的坐标
test.c(测试游戏功能)
# include "game2.h"
void menu()
{
printf ("**********************************\n");
printf ("********* 扫雷游戏 **********\n");
printf ("******** (1)play **********\n");
printf ("******** (0)exit **********\n");
printf ("**********************************\n");
printf ("注:游戏坐标为0~9\n");
}
void empty(char arr[H][L],int h,int l,char p)
{
int i = 0, j = 0;
for (i=0; i<h; i++)
{
for(j=0; j<l; j++)
{
arr[i][j] = p;
}
}
}
void display_board(char arr[H][L], int h, int l)
{
int i = 0, j = 0;
for (i=0; i<l; ++i)
{
printf ("%-4d",i);
}
printf ("\n");
for (i=1; i<h; ++i)
{
printf (" %-2d|",i);
for (j=1; j<l; ++j)
{
printf (" %c ",arr[i][j]);
if(j<l-1)
{
printf ("|");
}
}
printf ("\n");
for (j=0; j<l; ++j)
{
printf ("--- ");
}
printf ("\n");
}
}
void game ()
{
char arr1[H][L] = {'0'};
char arr2[H][L] = {'0'};
empty (arr1, H, L, '0');
empty (arr2, H, L, '*');
system("cls");
lay_mines (arr1, Hh, Ll);
#if DISPLAY_BOARD
display_board(arr1, Hh+1, Ll+1);
#endif
display_board (arr2, Hh+1, Ll+1);
find_mines(arr1, arr2, Hh, Ll);
}
int main()
{
int input = 0;
srand ((unsigned) time (NULL));
do
{
menu();
printf ("请选择0(exit)/1(play):\n");
scanf ("%d",&input);
switch(input)
{
case 0: printf ("退出游戏!!!\n");
break;
case 1: game ();
break;
default: printf ("你输入的有误,请重新输入!!\n");
break;
}
}while (input);
system ("pause");
return 0;
}
game.c(游戏主要函数)
#include "game2.h"
void lay_mines (char arr[H][L],int h,int l)
{
int a = 0, i = 0, j = 0 ;
while(a<MINE_NUM)
{
i = rand()% Hh +1;
j = rand()% Ll +1;
if (arr[i][j] == '0')
{
arr[i][j] = '1';
a++;
}
}
}
void unfold_mines (char arr1[H][L] , char arr2[H][L] ,int a, int b)
{
arr2[a][b] = ((arr1[a-1][b-1] + arr1[a-1][b] + arr1[a-1][b+1]
+ arr1[a][b-1] + arr1[a][b+1]
+ arr1[a+1][b-1] + arr1[a+1][b] + arr1[a+1][b+1])
- 8*'0')+'0' ;
if(arr2[a][b] == '0')
{
if (a-1>0 && b-1>0 && arr2[a-1][b-1] == '*')
{
unfold_mines (arr1, arr2, a-1, b-1);
}
if (a-1>0 && b>0 && arr2[a-1][b] == '*')
{
unfold_mines (arr1, arr2, a-1, b);
}
if (a-1>0 && b+1>0 && arr2[a-1][b+1] == '*')
{
unfold_mines (arr1, arr2, a-1, b+1);
}
if (a>0 && b-1>0 && arr2[a][b-1] == '*')
{
unfold_mines (arr1, arr2, a, b-1);
}
if (a>0 && b+1>0 && arr2[a][b+1] == '*')
{
unfold_mines (arr1, arr2, a, b+1);
}
if (a+1>0 && b-1>0 && arr2[a+1][b-1] == '*')
{
unfold_mines (arr1, arr2, a+1, b-1);
}
if (a+1>0 && b>0 && arr2[a+1][b] == '*')
{
unfold_mines (arr1, arr2, a+1, b);
}
if (a+1>0 && b+1>0 && arr2[a+1][b+1] == '*')
{
unfold_mines (arr1, arr2, a+1, b+1);
}
}
}
void first_mine(char arr1[H][L], char arr2[H][L], int a, int b)
{
int i = 0, j = 0;
if (arr1[a][b] == '1')
{
arr1[a][b] = '0';
while (1)
{
i = rand()% Hh +1;
j = rand()% Ll +1;
if (arr1[i][j] == '0')
{
arr1[i][j] = '1';
break;
}
}
}
}
int have_mine(char arr[H][L],int h, int l)
{
int i = 0, j = 0, sign_count = 0, left_count = 0;
for (i=1; i<h; ++i)
{
for (j=1; j<l; ++j)
{
if (arr[i][j] == '*')
{
left_count ++;
}
if (arr[i][j] == '#')
{
sign_count ++;
}
}
}
#if HAVE_MINE
printf ("sign_count = %d\n",sign_count);
printf ("left_count = %d\n",left_count);
#endif
if ((left_count+sign_count) == MINE_NUM)
{
return 0;
}
else
{
return 1;
}
}
void sign_mines(char arr1[H][L], char arr2[H][L], int h, int l)
{
int a = 0, b = 0;
printf("请输入你要标记的坐标:\n");
scanf ("%d%d",&a, &b);
if(arr2[a][b] == '*')
{
system("cls");
arr2[a][b] = '#';
display_board (arr2, Hh+1, Ll+1);
}
else
{
printf ("你输入的坐标有误\n");
}
}
void not_sign_mines(char arr1[H][L], char arr2[H][L], int h, int l)
{
int a = 0, b = 0;
printf("请输入你要取消标记的坐标:\n");
scanf ("%d%d",&a, &b);
if(arr2[a][b] == '#')
{
system("cls");
arr2[a][b] = '*';
display_board (arr2, Hh+1, Ll+1);
}
else
{
printf ("你输入的坐标有误\n");
}
}
void find_mines(char arr1[H][L], char arr2[H][L], int h, int l)
{
int a = 0, b = 0, times = 0, t = 0;
int is_pai = 0;
do
{
times ++;
printf("标记(1)/取消标记(2)/排雷(3)\n");
scanf ("%d", &is_pai);
if (is_pai == 1)
{
sign_mines(arr1, arr2, h, l);
}
else if (is_pai == 2)
{
not_sign_mines( arr1, arr2, h, l);
}
else if (is_pai == 3)
{
printf ("请输入你要排的雷的坐标:\n");
scanf ("%d%d", &a, &b);
if (arr2[a][b] != '*')
{
printf ("你输入的坐标有误!\n");
}
else if (arr2[a][b] == '*' && a>=1 && a<=h && b>=1 &&b<=h)
{
if(times == 1)
{
first_mine(arr1, arr2, a, b);
}
if (times !=1 && arr1[a][b] == '1')
{
printf ("恭喜你,被炸死了!!!\n");
display_board(arr1, h+1, l+1);
break;
}
else
{
system("cls");
unfold_mines (arr1 , arr2 , a, b);
display_board(arr2, h+1, l+1);
}
}
else
{
printf ("你的输入有误!!!\n");
}
}
else
{
printf ("你的输入有误!!!\n");
}
t = have_mine(arr2, Hh+1, Ll+1);
}while (t);
if (t == 0)
{
printf ("恭喜你,把雷排完了!!!\n");
display_board(arr1, h+1, l+1);
}
}