头文件game.h
#ifndef __GAME_H__
#define __GAME_H__
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<string.h>
//9*9棋盘,周围多一圈方便判断周围雷的个数
#define ROWS_SET 9
#define COLS_SET 9
#define ROWS (ROWS_SET+2)
#define COLS (COLS_SET+2)
#define MINE_MAX 10
void init(char a[ROWS][COLS]);
void display(char a[ROWS][COLS]);
void set_main(char a[ROWS][COLS]);
void open_s(char a[ROWS][COLS]);
void game();
#endif //__GAME_H__
源文件
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
enum Option //用枚举,后面switch方便阅读
{
EXIT, //0,有逗号
PLAY //1,没逗号
}; //这有个分号
void menu()
{
printf("**********************************\n");
printf("****** 1.play 0.exit *******\n");
printf("**********************************\n");
}
void test()
{
int input = 0;
srand((unsigned int)time(NULL));
while(1)
{
menu();
scanf("%d",&input);
switch(input)
{
case PLAY:
game();
break;
case EXIT:
exit(1);
break;
default:
printf("选择错误\n");
break;
}
}
}
int main()
{
test();
return 0;
}
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
//初始化
void init(char a[ROWS][COLS])
{
//int i = 0;
//int j = 0;
//for(i=0;i<ROWS;i++)
// for(j=0;j<COLS;j++)
// a[i][j]=' ';
memset(a, ' ',ROWS*COLS*sizeof(a[0][0]));
}
//打印棋盘,显示全部
void display_all(char a[ROWS][COLS])
{
int i = 0;
int j = 0;
//输出列号
printf(" ");
for(i=1;i<COLS-1;i++)
{
if(i<=9)
printf("%d ",i);
else
printf("%d ",i);
}
printf("\n");
//11*11的数组只打印中间9*9的棋盘
//数组下标是1~9,ROWS和COLS都是11
for(i=1;i<ROWS-1;i++)
{
//打印行号
if(i<=9)
printf("%d ",i);
else
printf("%d",i);
//打印一行数组
for(j=1;j<COLS-1;j++)
{
if(j<COLS-2)
printf(" %c |",a[i][j]);
else
printf(" %c\n",a[i][j]);//行末回车
}
//一行下面的横线
if(i!=ROWS-2)
{
printf(" ");
for(j=1;j<COLS-1;j++)
printf("----");
if(j==COLS-1)
printf("\n");
}
}
}
//打印棋盘,不显示雷
void display(char a[ROWS][COLS])
{
int i = 0;
int j = 0;
//输出列号
printf(" ");
for(i=1;i<COLS-1;i++)
{
if(i<=9)
printf("%d ",i);
else
printf("%d ",i);
}
printf("\n");
//11*11的数组只打印中间9*9的棋盘
//数组下标是1~9,ROWS和COLS都是11
for(i=1;i<ROWS-1;i++)
{
//打印行号
if(i<=9)
printf("%d ",i);
else
printf("%d",i);
//打印一行数组
for(j=1;j<COLS-1;j++)
{
//打印不显示雷的行内字符
if (j<COLS-2)
{
if (a[i][j]!='x')
{
printf(" %c |",a[i][j]);
}
else
{
printf(" |");
}
}
//打印不显示雷的行末字符和\n
else
{
if (a[i][j]!='x')
{
printf(" %c\n",a[i][j]);//行末回车
}
else
{
printf(" |\n");
}
}
}
//一行下面的横线
if(i!=ROWS-2)
{
printf(" ");
for(j=1;j<COLS-1;j++)
printf("----");
if(j==COLS-1)
printf("\n");
}
}
}
//设置雷
void set_mine(char a[ROWS][COLS])
{
int count = 0;
//已经生成雷的位置不能再放雷
while (count != MINE_MAX)
{
//x,y范围1~9 ROWS和COLS都是11时
int x = rand()%(ROWS-2)+1;
int y = rand()%(COLS-2)+1;
if (a[x][y] == ' ')
{
a[x][y] = 'x';
count++;
}
}
}
//判断棋盘是否满了(胜利条件)
int is_full(char a[ROWS][COLS])
{
int i = 0;
int j = 0;
for(i=1;i<ROWS-1;i++)
{
for(j=1;j<COLS-1;j++)
{
if(a[i][j]==' ')
{
return 0; //没满返回0
}
}
}
return 1;//棋盘满了返回1
}
//计算某位置周围雷的个数
char judge(char a[ROWS][COLS], int x, int y)
{
char count = '0';
if (a[x-1][y-1] == 'x')
count++;
if (a[x-1][y] == 'x')
count++;
if (a[x-1][y+1] == 'x')
count++;
if (a[x][y-1] == 'x')
count++;
if (a[x][y+1] == 'x')
count++;
if (a[x+1][y-1] == 'x')
count++;
if (a[x+1][y] == 'x')
count++;
if (a[x+1][y+1] == 'x')
count++;
return count;
}
//打开雷数为0位置的8方向,如果是空位置,则判断该位置雷的个数
void open(char a[ROWS][COLS], int x, int y)
{
if (a[x-1][y-1] == ' ')
a[x-1][y-1] = judge(a,x-1,y-1);
if (a[x-1][y] == ' ')
a[x-1][y] = judge(a,x-1,y);
if (a[x-1][y+1] == ' ')
a[x-1][y+1] = judge(a,x-1,y+1);
if (a[x][y-1] == ' ')
a[x][y-1] = judge(a,x,y-1);
if (a[x][y+1] == ' ')
a[x][y+1] = judge(a,x,y+1);
if (a[x+1][y-1] == ' ')
a[x+1][y-1] = judge(a,x+1,y-1);
if (a[x+1][y] == ' ')
a[x+1][y] = judge(a,x+1,y);
if (a[x+1][y+1] == ' ')
a[x+1][y+1] = judge(a,x+1,y+1);
}
//遍历数组许多遍,如果该次能找到0,则打开0,并把它变成*,然后继续遍历,直到没有相邻的0
void open_s(char a[ROWS][COLS])
{
int i = 0;
int j = 0;
int flag = 0;
do
{
flag = 0;
for (i=1;i<ROWS-1;i++)
{
for (j=1;j<COLS-1;j++)
{
if (a[i][j] == '0')
{
open(a,i,j);
a[i][j] = '*';
flag = 1;
}
}
}
}while (flag == 1);
}
void game()
{
char a[ROWS][COLS]={0};
int x = 0;
int y = 0;
int flag = 0;
init(a);
display_all(a);
while(is_full(a) != 1) //如果棋盘没满则一直扫雷
{
printf("输入要排查的坐标:\n");
scanf("%d %d",&x,&y);
if ((x >= 1) && (x <= ROWS-2) && (y >= 1) && (y <= COLS))
{
//保证第一步不是雷(先输入一个位置,然后生成雷,再判断该位置周围有多少雷并显示)
if(flag == 0)
{
a[x][y] = 'p'; //把这个位置随便写个字符,让下面生成雷的时候跳过该位置
set_mine(a);
a[x][y] = judge(a,x,y);
if (a[x][y] == '0')
{
open_s(a);//如果该位置是0,则显示与之相连的所有0的位置
}
display_all(a);
flag = 1;
continue;
}
if(a[x][y] == 'x')
{
a[x][y] = '+';
printf("你被炸死了\n");//如果是雷,则游戏结束
break;
}
else if(a[x][y] != ' ')
{
printf("该位置已探索\n\n");
}
else
{
a[x][y] = judge(a,x,y); //判断该位置周围雷的个数
if (a[x][y] == '0')
{
open_s(a);//如果该位置是0,则显示与之相连的所有0的位置
}
display(a);
}
}
else
{
printf("输入的位置超出边界\n\n");
}
}
if (is_full(a) == 1)
{
printf("胜利\n");
}
display_all(a);
}