C语言小游戏:扫雷

这个小游戏也分为三个部分的代码,分别是头文件,测试代码和游戏代码。

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] = '!';//标记
}

结果展示:



猜你喜欢

转载自blog.csdn.net/baidu_40931662/article/details/80531156