这个小游戏也分为三个部分的代码,分别是头文件,测试代码和游戏代码。
1.注意初始化以及使用GetWinCount函数的时候字符1和字符0的使用。
2.为了玩家的体验,第一步不可以被炸死。
3.要扩展,这时会用到递归,注意递归的使用。
4.可以添加标记,优化游戏。
头文件:game.h
#ifndef __GAME_H__
#define __GAME_H__
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<String.h>
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define EASY_COUNT 10
#define MID_COUNT 30
#define HARD_COUNT 60
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);
void DisplayBoard(char board[ROWS][COLS], int row, int col);
void SetMine(char board[ROWS][COLS], int row, int col);
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
void MoveMine(char mine[ROWS][COLS], int i, int j);
void GetMineCount(char mine[ROWS][COLS],char show[ROWS][COLS], int i, int j);
void Mark(char show[ROWS][COLS]);
#endif //__GAME_H__
测试代码:test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void menu()
{
printf("************************\n");
printf("*** 1. play 2. exit ***\n");
printf("************************\n");
}
void game()
{
int input = 0;
int DIF = 0;//游戏的难度
char mine[ROWS][COLS] = {0};//布雷的棋盘
char show[ROWS][COLS] = {0};//要打印的棋盘
InitBoard(mine, ROWS, COLS, '0');
InitBoard(show, ROWS, COLS, '*');//初始化
printf("**********************************\n");
printf("***** 1.EASY 2.MIDIUM 3.HARD *****\n");
printf("**********************************\n");
printf("请选择相关难度:>");
scanf("%d",&input);
switch(input){
case 1:
DIF = EASY_COUNT;
break;
case 2:
DIF = MID_COUNT;
break;
case 3:
DIF = HARD_COUNT;
break;
default:printf("选择错误!\n");
}
printf("这个棋盘有%d处雷!\n",DIF);
SetMine(mine, ROW, COL, DIF);//设置雷
//DisplayBoard(mine, ROW, COL);
DisplayBoard(show, ROW, COL);//输出
FindMine(mine, show, ROW, COL, DIF);//扫雷
}
void test()
{
int input = 0;
srand((unsigned int)time(NULL));
do{
menu();
printf("请输入:>");
scanf("%d",&input);
switch(input)
{
case 1:
game();
break;
case 0:
printf("退出游戏!\n");
break;
default:
printf("选择错误!\n");
break;
}
}while(input);
}
int main()
{
test();
return 0;
}
游戏代码:game.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{
memset(board,set,rows*cols*sizeof(board[0][0]));//初始化棋盘
}
void DisplayBoard(char board[ROWS][COLS], int row, int col)//打印棋盘
{
int i = 0;
int j = 0;
for(i=0; i<=col; i++)
{
printf("%d ",i);//添加列号,从0开始
}
printf("\n");
for(i=1; i<=row; i++)
{
printf("%d ",i);//添加行号
for(j=1; j<=col; j++)
{
printf("%c ",board[i][j]);
}
printf("\n");
}
printf("\n");
}
void SetMine(char board[ROWS][COLS], int row, int col ,int DIF)//设置雷
{
int i = 0;
int j = 0;
while(DIF)
{
i = rand()%9+1;
j = rand()%9+1;
if(board[i][j] = '0')
{
board[i][j] = '1';//‘1’代表有雷
DIF--;
}
}
}
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col , int DIF)//扫雷
{
int i = 0;
int j = 0;
int tmp = 0;//表示扫雷的次数
int n = 0;//输入的坐标总数
while(n<(row*col-DIF))
{
Mark(show);//标记
DisplayBoard(show, ROW, COL);
printf("请输入要排查的坐标:>");
scanf("%d %d",&i,&j);
tmp++;
if(i>=1 && i<=row && j>=1 && j<=col)
{
if(tmp == 1 && mine[i][j] == '1')//如果第一次输入坐标有雷,就移走它,保证玩家第一次不会被炸死
{
MoveMine(mine, i, j);//移雷
}
if(mine[i][j] == '1')
{
printf("很不幸,你被炸死了!\n");
DisplayBoard(mine, row, col);
break;
}
else
{
GetMineCount(mine,show, i, j);//获取雷的个数
DisplayBoard(show, row, col);
}
}
else
{
printf("坐标非法!\n");
}
}
if(n == (row*col-DIF))
{
printf("恭喜你,排雷成功!\n");
}
}
void GetMineCount(char mine[ROWS][COLS],char show[ROWS][COLS], int i, int j)
{
if ((mine[i][j] == '0'))
{
int count = 0;
if (mine[i-1][j] == '1')
count++;
if (mine[i-1][j-1] == '1')
count++;
if (mine[i][j-1] == '1')
count++;
if (mine[i+1][j-1] == '1')
count++;
if (mine[i+1][j] == '1')
count++;
if (mine[i+1][j+1] == '1')
count++;
if (mine[i][j+1] == '1')
count++;
if (mine[i-1][j+1] == '1')
count++; //排查输入坐标周围是否有雷
show[i][j] = (count + '0');//数字+‘0’=‘该数字’
}
if(show[i][j] == '0')//如果输入的坐标没有雷,就扩展
{
if(show[i-1][j] == '*')
GetMineCount(mine, show, i-1,j);
if(show[i-1][j-1] == '*')
GetMineCount(mine, show, i-1, j-1);
if(show[i][j-1] == '*')
GetMineCount(mine, show, i, j-1);
if(show[i+1][j-1] == '*')
GetMineCount(mine, show, i+1, j-1);
if(show[i+1][j] == '*')
GetMineCount(mine, show, i+1, j);
if(show[i+1][j+1] == '*')
GetMineCount(mine, show, i+1, j+1);
if(show[i][j+1] == '*')
GetMineCount(mine, show, i, j+1);
if(show[i-1][j+1] == '*')
GetMineCount(mine, show, i-1, j+1);//递归
}
}
void MoveMine(char mine[ROWS][COLS], int i, int j, int DIF)//移雷
{
mine[i][j] = '0';
i = rand()%9+1;
j = rand()%9+1;
if(mine[i][j] == '0')
{
mine[i][j] = '1';
}//只移走第一次输入有雷的那个雷
}
void Mark(char show[ROWS][COLS])//标记
{
int i = 0;
int j = 0;
printf("请输入你要标记的位置(若不想标记,请输入0 0):>");
scanf("%d %d",&i,&j);
if(i==0 && j==0)
{
return 0;//不标记,返回
}
else
show[i][j] = '!';//标记
}
结果展示: