C语言学习之扫雷小游戏

以下内容是小编整理的近期学习的C语言变成实现简单版本的扫雷游戏,与之前整理的三子棋游戏相似,这个小项目的目的也是为了锻炼、提升对于C语言数组、循环以及函数的应用能力。

1. 实现一次扫雷游戏的流程

上图是一次游戏的简易流程图,在每次进入游戏后,需要玩家键入需要排查的位置,若位置正确,则判断该位置是否为雷区;当该位置不是雷区时,进行count--(count表示非雷区位置的个数),然后循环排查;当count==0时,即当前界面只剩下雷区,玩家胜利!!

2. 编程实现游戏功能需要注意的几个点

将显示界面与雷区分布保存为两个数组

玩过扫雷游戏的朋友都知道,我们实际在玩游戏的过程中,看到的界面只是一个个的白色小方格,也不知道小方格下面是雷区还是安全区。因此在功能实现的过程中,我们需要定义两个数组,一个用来显示界面,另一个用来存储雷区的分布情况,在以下小编提供的代码中,分别定义两个数组board和mine为显示界面和存储雷区分布。

②定义数组需要 “padding”

“padding”这个词是深度学习中的专业术语,意思是在进行卷积时是否给待处理的数组向外加一圈‘0’值,目的是为了使边缘的像素值得到处理。在我们这个游戏的实现过程中,我们前面说了需要定义两个数组board和mine,mine是用来存储雷区的分布情况的,由于我们希望在每次排查之后,将显示面板上对应的位置的内容替换为当前位置周围雷的书目,在统计边界的时候我们需要给数组向外增加一圈‘0’值,来协助统计。当然,此处的处理方式与深度学习中的“padding”在处理过程中不相同,在这里直接采取定义(n+2)*(n+2)数组的方式。如下图所示,假设游戏的界面为4*4,蓝色为玩家键入的排查区域,按照设计,如果此处不是雷区,我们将显示显示出该位置周围雷的个数,则需要统计图中的紫色区域,为了使编程过程简洁化(即用一个模板统计所有的区域),在定义数组时定义为(n+2)*(n+2)。

③GetNum()函数返回值的小细节

GetNum()函数用于统计当前排查位置周围雷的个数,得到的雷的个数为int型,而函数的返回值为char类型(board和mine中的元素均为char型),怎样将统计得到的整型转化为字符型时此处的一个小细节,在C语言中,有以下转化方式:

‘1’ = ‘0’ + 1;      2’ = ‘0’  + 2;  

因此在返回参数时语句为:return ‘0’ + index;

3. 扫雷小游戏代码

//mine.h

#ifndef _MINE_H_
#define _MINE_H_

#include <stdio.h>
#include <windows.h>
#include <stdlib.h>
#include <time.h>

#pragma warning(disable:4996)

#define ROW 12
#define COL 12
#define NUM 20


void Game();
void InitBoard(char board[][COL],int row,int col, char elem);
void SetMine(char mine[][COL], int row, int col);
void ShowBoard(char board[][COL], int row, int col);
char GetNum(char mine[][COL], int x, int y);


#endif
//main.c

#include "mine.h"

static void Menue()
{
	printf("#################################\n");
	printf("##       欢迎来到扫雷游戏      ##\n");
	printf("#################################\n");
	printf("## 1.开始               2.退出 ##\n");
	printf("#################################\n");
	printf("请选择=># ");
}


int main()
{
	int quit = 0;
	do{
		int select;
		Menue();
		scanf("%d", &select);
		switch (select){
		case 1:
			Game();
			printf("游戏结束...再来一把?\n");
			break;
		case 2:
			quit = 1;
			printf("再见...下次来玩!\n");
			break;
		default:
			printf("输入有误,请重新输入!\n");
			break;
		}

	} while (!quit);

	system("pause");
	return 0;
}
//mine.c

#include "mine.h"

//初始化显示界面上各位置为‘*’
void InitBoard(char board[][COL], int row, int col, char elem)
{
	int i = 0;
	for (; i < row; i++){
		int j = 0;
		for (; j < col; j++){
			board[i][j] = elem;
		}
	}
}

//利用随机数设置雷区
void SetMine(char mine[][COL], int row, int col)
{
	int n = NUM;
	while (n){
		int x = rand() % (row - 2) + 1;
		int y = rand() % (col - 2) + 1;
		if (mine[x][y] == '1'){
			continue;         //避免同一位置重复布雷
		}

		mine[x][y] = '1';
		n--;
	}
}


//初始化显示界面,使界面呈现棋盘状
void ShowBoard(char board[][COL], int row, int col)
{
	int i = 1;
	printf("   ");
	for (; i <= col - 2; i++){
		printf(" %-2d|", i);
	}
	printf("\n");
	for (i = 1; i <= col - 2; i++){
		printf("%3s", "----");
	}
	printf("---\n");

	for (i = 1; i <= row - 2; i++){
		printf("%2d|", i);
		int j = 1;
		for (; j <= col - 2; j++){
			printf(" %-2c|", board[i][j]);
		}
		printf("\n");
		for (j = 1; j <= col - 2; j++){
			printf("%3s", "----");
		}
		printf("---\n");
	}
}

//统计当前位置周围八个位置雷的个数
char GetNum(char mine[][COL], int x, int y)
{
	int i = x - 1;
	int index = 0;
	
	for (; i <= x + 1; i++){
		int j = y - 1;
		for (; j <= y + 1; j++){
			if (mine[i][j] == '1'){
				index++;
			}
		}
	}
	return '0' + index;
}




void Game()
{
	srand((unsigned long)time(NULL));   //种随机数种子,之后需要利用随机数进行雷区的设置

	char board[ROW][COL];   //玩家所看到的界面
	char mine[ROW][COL];    //用来存储雷区分布情况

	InitBoard(board, ROW, COL, '*');
	InitBoard(mine, ROW, COL, '0');

	SetMine(mine, ROW, COL);   //设置雷区
	int count = (ROW - 2)*(COL - 2) - NUM;    //非雷区位置的个数
	do{
		system("cls");          //实现清屏功能
		int x = 0;
		int y = 0;
		ShowBoard(board, ROW, COL);
		printf("请输入要扫的位置=> ");
		scanf("%d %d", &x, &y);
		if (x<1 || x>10 || y<1 || y>10){
			printf("你输入的位置有误,请重新输入..\n");
			Sleep(1000);
			continue;
		}
		if (board[x][y] != '*'){
			printf("你输入的位置已经扫过了,请重新输入...\n");
			Sleep(1000);
			continue;
		}
		if (mine[x][y] == '0'){
			count--;
			char num = GetNum(mine, x, y);   //统计当前位置周围八个位置雷的个数
			board[x][y] = num;
			Sleep(1000);
		}
		else{
			printf("你输入的位置(%d, %d)有雷! \n", x, y);
			break;
		}

	}while(count > 0);

	char *result = NULL;
	if (count > 0){
		result = "## BOOM...游戏结束 :< ##\n";
	}
	else{
		result = "## WIN....游戏结束 :> ##\n";
	}

	printf("#############################\n");
	printf("%s", result);
	printf("#############################\n");
	ShowBoard(mine, ROW, COL);       //显示游戏中雷的分布情况
	return 0;


}
原创文章 5 获赞 1 访问量 184

猜你喜欢

转载自blog.csdn.net/qq_44408326/article/details/105801822