关闭

C语言简单实现扫雷小游戏~~~

标签: c语言扫雷游戏算法
334人阅读 评论(0) 收藏 举报
分类:

C语言实现扫雷

C语言编写小游戏扫雷,因为目前个人技术问题,外观界面不能做出来,最终呈现的效果还是在命令里进行,但是总体来说还是完成了扫雷的基本功能。
不过,标记的函数,没有写的完美,每次都要进行标记,比较麻烦,所以在代码中我将其注释了,若有人能够有好的算法的话,还请不吝赐教。
代码见下:
#define _CRT_SECURE_NO_WARNINGS 1

#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 10
#define HARD 80

void Init_Array(char Array[ROWS][COLS], int row, int col, char set); //初始化数组
void Display(char Array[ROWS][COLS], int row, int col);  //打印数组
void Set_Mine(char Array[ROWS][COLS], int MINE);  //布雷
void Sweep_Mine(char Array[ROWS][COLS], char show[ROWS][COLS], int row, int col, int MINE);  //扫雷
void Move_mine(char Array[ROWS][COLS], int x, int y);  //移雷
void Get_Mine_Count(char Array[ROWS][COLS], char show[ROWS][COLS], int x, int y);  //区域展开

#endif //__GAME_H__ 


void game()  //游戏函数
{
	int input = 0;
	int MINE = 0;
	char mine[ROWS][COLS]; 
	char show[ROWS][COLS];
	Init_Array(mine, ROWS, COLS, '0');
	Init_Array(show, ROWS, COLS, '*');
	printf("***********  1.EASY    2.HARD  ***********\n");
	printf("\n请输入选择的难度:< ");
	scanf("%d", &input);

	switch (input)
	{
	case 1:
		MINE = EASY;
		break;
	case 2:
		MINE = HARD;
		break;
	default:printf("您的输入有误!\n");
	}

	printf("\n这个棋盘有%d处雷,小心咯!!!\n\n", MINE);
	Set_Mine(mine, MINE);
	Display(show, ROW, COL);
	Sweep_Mine(mine, show, ROW, COL, MINE);
}

void menu()
{
	printf("******************************************\n");
	printf("***********    欢迎来到扫雷    ***********\n");
	printf("***********  1.PLAY    0.EXIT  ***********\n");
	printf("******************************************\n");
}

void test()
{
	int input;

	do
	{
		srand((unsigned int)rand(NULL));
		menu();
		printf("\n请选择:< ");
		scanf("%d", &input);
		printf("\n");
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("您已退出游戏,谢谢!\n");
			break;
		default:
			printf("输入不合法,请重新输入!\n");
			break;
		}
	} while (input);
}

int main()
{
	test();
	system("pause");
	return 0;
}


void Init_Array(char Array[ROWS][COLS], int row, int col, char set)
{
	memset(Array, set, (row*col*sizeof(Array[0][0])));  //初始化数组内容为0与*
}

void Display(char Array[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;
	printf("      ");

	for (i = 1; i <= row; i++)
		printf(" %d  ", i);
	printf("\n      -----------------------------------\n");

	for (i = 1; i <= col; i++)   //因涉及周围展开,故数组从1开始打印
	{
		printf("   %d |", i);
		for (j = 1; j <= col; j++)
		{
			printf(" %c |", Array[i][j]);
		}
		printf("\n     |---|---|---|---|---|---|---|---|---|\n");
	}
	printf("\n");
}

void Set_Mine(char Array[ROWS][COLS], int MINE)  //布雷
{
	int count = MINE;
	int x = 0;
	int y = 0;

	while (count)
	{
		x = rand() % ROW + 1;
		y = rand() % COL + 1;

		if (Array[x][y] == '0')
		{
			Array[x][y] = '1';
			count--;
		}
	}
}

//若输入的坐标无雷,则要遍历周围,统计雷数
//若周围无雷,则递归遍历,统计周围雷数
void Get_Mine_Count(char Array[ROWS][COLS], char show[ROWS][COLS], int x, int y) 
{                                                                                 
		if ((Array[x][y] == '0'))
		{
			int count = 0;

			if (Array[x - 1][y - 1] == '1')
				count++;

			if (Array[x - 1][y] == '1')
				count++;

			if (Array[x - 1][y + 1] == '1')
				count++;

			if (Array[x][y - 1] == '1')
				count++;

			if (Array[x][y + 1] == '1')
				count++;
			if (Array[x + 1][y - 1] == '1')
				count++;

			if (Array[x + 1][y] == '1')
				count++;

			if (Array[x + 1][y + 1] == '1')
				count++;

			show[x][y] = (count + '0');
		}

		if (show[x][y] == '0')
		{
			if (show[x - 1][y - 1] == '*')
				Get_Mine_Count(Array, show, x - 1, y - 1);

			if (show[x - 1][y] == '*')
				Get_Mine_Count(Array, show, x - 1, y);

			if (show[x - 1][y + 1] == '*')
				Get_Mine_Count(Array, show, x - 1, y + 1);

			if (show[x][y - 1] == '*')
				Get_Mine_Count(Array, show, x, y - 1);

			if (show[x][y + 1] == '*')
				Get_Mine_Count(Array, show, x, y + 1);

			if (show[x + 1][y - 1] == '*')
				Get_Mine_Count(Array, show, x + 1, y - 1);

			if (show[x + 1][y] == '*')
				Get_Mine_Count(Array, show, x + 1, y);

			if (show[x + 1][y + 1] == '*')
				Get_Mine_Count(Array, show, x + 1, y + 1);
		}
}

//为提高游戏体验,设置玩家第一次无论如何都不会被炸死
void Move_mine(char Array[ROWS][COLS], int x, int y)   
{
	int ret = 1;
	do
	{
		Array[x][y] = '0';
		while (ret)
		{
			x = rand() % ROW + 1;
			y = rand() % COL + 1;
			if (Array[x][y] == '0')
			{
				Array[x][y] = '1';
			}
			ret--;
		}
	} while (ret);
}

//玩家对以确定的雷的位置,可以进行标记
//void Mark_Mine(char show[ROWS][COLS])   
//{
//	int x = 0;
//	int y = 0;
//	printf("请输入您要标记的位置(不标记请输入0,0):<");
//	scanf("%d%d", &x, &y);
//	printf("\n");
//	if (x == 0 && y == 0)
//		return 0;
//	else
//		show[x][y] = '$';
//}


void Sweep_Mine(char Array[ROWS][COLS], char show[ROWS][COLS], int row, int col, int MINE)
{
	int x = 0;
	int y = 0;
	int count = 0;
	int temp = 0;
	int win = 0;

	while (win<(row*col - MINE))
	{
		printf("请输入您要扫雷的坐标:<");
		scanf("%d%d", &x, &y);
		temp++;

		if (((x >= 1) && (x <= row)) && (y >= 1) && (y <= col))
		{
			while ((Array[x][y] == '1') && (temp == 1))
			{
				Move_mine(Array, x, y);    //保证玩家第一次不会被炸死,移走雷
				Get_Mine_Count(Array, show, x, y);  //对周围的雷数进行遍历
			}

			if (Array[x][y] == '1')
			{
				printf("\n哈哈,你被炸死啦!\n\n");
				Display(Array, ROW, COL);
				break;
			}
			else
			{
				Get_Mine_Count(Array, show, x, y);
				printf("\n\n");
				win++;
			}
			Display(show, ROW, COL);
			//Mark_Mine(show);
		}
		else
		{
			printf("坐标输入有误,请重新输入!\n");
		}
	}

	if (win == (row*col - MINE))
		printf("恭喜你,排完了所有的雷!\n");
}
运行结果如下:                                                                                                                          



0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:3285次
    • 积分:318
    • 等级:
    • 排名:千里之外
    • 原创:30篇
    • 转载:0篇
    • 译文:0篇
    • 评论:0条