五一假期我竟然做出来了这个程序———— 扫雷 (功能完全版)

初级版扫雷(功能无阉割)

  • 1. 扫雷整体思路分析
  • 2. 初始化数据与雷的放置
  • 3. 打印游戏信息
  • 4. 排查雷与标记雷
  • 5. 排查后附近格子的自动展开
  • 6. 判断输赢
  • 7. 细节优化
  • 8. 各个文件中的原码

1. 扫雷整体思路分析

  1. 扫雷算是一个代码量比较大的程序,需要用到大量我们自定义的函数,故需要不同的文件去声明与实现函数。
  2. 设置两个二维数组,一个用来储存雷的信息,另一个打印出游戏的信息。
  3. 各种函数来实现功能。
文件 功能
test.c 程序main函数的运行文件
game.c 实现函数的功能
game.h 声明函数和引用各种头文件

2. 初始化数据与雷的放置

  1. 数组stormir存放雷
  2. 数组showmir展示游戏信息
  3. 根据游戏功能,后面排查雷时需要遍历其周围的八个格子,故将数组大小扩大到行:11、列:11。(实际操作数组还是行9列9)
  4. 用rand()函数随机布置雷
#define ROWS 11
#define COLS 11
#define ROW 9
#define COL 9
    char stormir[ROWS][COLS] = {
      0 };
	char showmir[ROWS][COLS] = {
      0 };
	initboard(stormir,ROWS,COLS,' ');   //初始化
	initboard(showmir, ROWS,COLS,' ');
	setmire(stormir, ROW, COL);        //放置雷
	//函数功能实现
	void initboard(char stormir[][COLS], int rows, int cols, char ch)
{
     
	int i = 0;
	int j = 0;
	for (i = 0; i < rows; i++)
	{
     
		for (j = 0; j < cols; j++)
		{
     
			stormir[i][j] = ch;
		}
	}
}
void setmire(char stormir[ROWS][COLS], int row, int col)
{
     
	int count = 0;
	int i = 0, j = 0;
	while (count !=10)
	{
     
		i = rand() % row + 1;
		j = rand() % col + 1;
		if (stormir[i][j] != '*')
		{
     
			stormir[i][j] = '*';
			count++;
		}
	}
}

3. 打印游戏信息

void disaplayboard(char showmir[][COLS], int row, int col)
{
     
	int i = 0, j = 0;
	printf("\n");
	for (i = 1; i <= row; i++)
	{
     
		if (i == 1)
		{
     
			printf("    ");
			for (j = 0; j < col; j++)//打印每一列的数字
			{
     
				printf(" %d ", j + 1);
				printf(" ");
			}
			printf("\n");
		}
		printf(" %2d ", i);//打印每一行的数字
		for (j = 1; j <= col; j++)//打印| 信息 |
		{
     
			printf(" %c ", showmir[i][j]);
			if (j != col)
			{
     
				printf("|");
			}
		}
		printf("\n");
		for (j = 0; j < col; j++)//打印|--|分割用
		{
     
			if (j == 0)
				printf("    ");
			printf("---");
			if (j != col - 1)
			{
     
				printf("|");
			}
		}
		printf("\n");
	}
}
  1. 存放雷的数组的打印五一假期我竟然做出来了这个程序———— 扫雷 (功能完全版)_第1张图片
  2. 游戏信息的打印五一假期我竟然做出来了这个程序———— 扫雷 (功能完全版)_第2张图片

4. 排查雷与标记雷

  1. 排查当前格子附近八个格子雷的个数,并把数目赋值给该格子
  2. 标记符号用“?”来标记。
//排查雷
            printf("请输入排查雷的坐标:>\n");
			printf("行:"); scanf("%d", &i);
			printf("\n");
			printf("列:"); scanf("%d", &j);
			if (i > 0 && i<ROW+1 && j>0 && j < COL+1)//判断排查坐标的合法性
			{
     
				if (stormir[i][j] == '*')
				{
     
					Sleep(1000);
					printf("很遗憾,你被炸死了\n");
					disaplayboard(stormir, ROW, COL);//打印雷
					break;
				}
				else
				{
     
					countmir(stormir, showmir, i, j);//对周围雷的个数计数
					disaplayboard(showmir, ROW, COL);
				}

void countmir(char stormir[][COLS], char showmir[][COLS], int x, int y)
{
     
	int count = 0;
	count = stormir[x - 1][y - 1] % 32 + stormir[x][y - 1] % 32 + stormir[x + 1][y - 1] % 32 + stormir[x - 1][y] % 32 + stormir[x + 1][y] % 32 + stormir[x - 1][y + 1] % 32 + stormir[x][y + 1] % 32 + stormir[x + 1][y + 1] % 32;
	showmir[x][y] = count / 10 + 48;//转换成字符‘\1’的形式赋给char类型的数组
}
//标记雷
            printf("请选择标记雷的位置:>\n");
			printf("行:"); scanf("%d", &x);
			printf("\n");
			printf("列:"); scanf("%d", &y);
			if (x > 0 && x<ROW+1 && y>0 && y < COL+1&&showmir[x][y]==' ')     
			{
     
				markmir(showmir,ROW,COL,x,y);
				disaplayboard(showmir, ROW, COL);
			}
			else
			{
     
				printf("输入非法,请重新输入:>");
			}
void markmir(char showmir[][COLS], int row, int col, int x, int y)
 {
     
	showmir[x][y] = '?';
 }
  1. 排查雷
    五一假期我竟然做出来了这个程序———— 扫雷 (功能完全版)_第3张图片
  2. 标记雷
    五一假期我竟然做出来了这个程序———— 扫雷 (功能完全版)_第4张图片

5. 排查后附近格子的自动展开

  1. 一个一个排查太麻烦,根据游戏功能,可以实现自动展开
  2. 八个方向展开,碰到0则继续展开,碰到不为0的则停止
  3. 注意不越界
void if_extern(char stormir[][COLS], char showmir[][COLS], int x, int y)
{
     
	if (countmir(stormir,showmir,x,y) == '0')//此时将countmir函数的返回类型由void改为char
	{
     
		if (x - 1 > 0&&showmir[x-1][y]==' ')
			if_extern(stormir, showmir, x - 1, y);
		 if (x + 1 <= ROW&&showmir[x+1][y]==' ')
			if_extern(stormir, showmir, x + 1, y);
		 if (y-1>0&&showmir[x][y-1]==' ')
			if_extern(stormir, showmir, x , y-1);
		 if (y+1<=COL&&showmir[x][y+1]==' ')
			if_extern(stormir, showmir, x, y+1);
		 if (x-1>0&&y-1>0&&showmir[x-1][y-1]==' ')
			if_extern(stormir, showmir, x - 1, y-1);
		 if (x-1>0&&y+1<=COL&&showmir[x-1][y+1]==' ')
			if_extern(stormir, showmir, x - 1, y+1);
		 if(x+1<=ROW&&y-1>0&&showmir[x+1][y-1]==' ')
			if_extern(stormir, showmir, x + 1, y-1);
		 if (x+1<=ROW&&y+1<=COL&&showmir[x+1][y+1]==' ')
			if_extern(stormir, showmir, x + 1, y+1);
	}
}

五一假期我竟然做出来了这个程序———— 扫雷 (功能完全版)_第5张图片

6. 判断输赢

 当showmir数组中出现了71个数字时,即剩下10个格子全为雷。
int if_win(char showmir[][COLS], int row, int col)
{
     
	int i = 0, j = 0;
	int count = 0;
	for (i = 1; i <= row; i++)
	{
     
		for (j = 1; j <= col; j++)
		{
     
			if (showmir[i][j] != ' '||showmir[i][j]!='?')
				count++;
		}
	}
	return count;//count71时,即排雷成功。
}

7. 细节优化

  1. 添加选择项,是排雷还是标记雷
  2. 当要显示雷的信息时,添加exchangmir函数来交换雷的信息(当被炸死时可以只用showmir显示游戏信息与雷的信息)
  3. 进入游戏界面时,采用do while循环保证进入while循环一次,而后根据玩家所选择再判断while循环是否继续
  4. 游戏菜单与界面优化
void exchangmire(char stormir[][COLS], char showmir[][COLS], int row, int col)
{
     
	char tmp = ' ';
	int i = 1, j = 1;
	for (i = 1; i <= row; i++)
	{
     
		for (j = 1; j <= col; j++)
		{
     
			if (stormir[i][j] == '*'&&showmir[i][j]==' ')
			{
     
				tmp = stormir[i][j];
				showmir[i][j] = tmp;
			}
		}
	}
}
//功能选项
void selct_menu()
{
     
	printf("|————————————————————————————————|\n");
	printf("|                                |\n");
	printf("|      1.查雷      2.标记雷       |\n");
	printf("|                                |\n");
	printf("|————————————————————————————————|\n");
}
//游戏菜单选项
void game_menu()
{
     
	printf("|————————————————————————————————|\n");
	printf("|                                |\n");
	printf("|      1.paly      0.exit        |\n");
	printf("|                                |\n");
	printf("|————————————————————————————————|\n");
}
	int input = 0;
	do
	{
     
		game_menu();
		printf("请选择:>\n");
		scanf("%d", &input);
		switch (input)
		{
     
		case 1:
			game();
			break;
		default:
			break;
		}

	} while (input);
}

8. 各个文件中的原码

//   game.h
#include 
#include 
#include 
#include 
#define ROWS 11
#define COLS 11
#define ROW 9
#define COL 9
void initboard(char stormir[][COLS],int rows,int cols, char ch);
void setmire(char stormir[][COLS], int row, int col);
void disaplayboard(char showmir[][COLS], int row, int col);
char countmir(char stormir[][COLS], char showmir[][COLS], int x, int y);
void exchangmire(char stormir[][COLS],char showmir[][COLS],int row,int col);
void if_extern(char stormir[][COLS], char showmir[][COLS], int x, int y);
int if_win(char showmir[][COLS], int row, int col);
void selct_menu();
void markmir(char showmir[][COLS], int row, int col, int x, int y);
//    test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void game()
{
     
	char stormir[ROWS][COLS] = {
      0 };
	char showmir[ROWS][COLS] = {
      0 };
	initboard(stormir,ROWS,COLS,' ');
	initboard(showmir, ROWS,COLS,' ');
	setmire(stormir, ROW, COL);
	disaplayboard(showmir,ROW,COL);
	while (1)
	{
     
		int i = 0, j = 0, k = 0, x = 0, y = 0;
		char count = '0';
		selct_menu();
		printf("请选择要执行的选项:>\n");
		scanf("%d", &k);
		if (k == 1)
		{
     
			printf("请输入排查雷的坐标:>\n");
			printf("行:"); scanf("%d", &i);
			printf("\n");
			printf("列:"); scanf("%d", &j);
			if (i > 0 && i<ROW+1 && j>0 && j < COL+1)
			{
     
				if (stormir[i][j] == '*')
				{
     
					Sleep(1000);
					printf("很遗憾,你被炸死了\n");
					exchangmire(stormir, showmir, ROW, COL);
					Sleep(1000);
					disaplayboard(showmir, ROW, COL);
					break;
				}
				else
				{
     
					countmir(stormir, showmir, i, j);
					if_extern(stormir, showmir, i, j);
					disaplayboard(showmir, ROW, COL);
					if (if_win(showmir, ROW, COL) == ROW*COL - 10)
					{
     
						Sleep(1000);
						printf("恭喜你,排雷成功!\n");
						exchangmire(stormir, showmir, ROW, COL);
						disaplayboard(showmir, ROW, COL);
						break;
					}

				}
			}
			else
			{
     
				printf("输入非法,请重新输入:>");
			}
		}
		else if (k == 2)
		{
     
			printf("请选择标记雷的位置:>\n");
			printf("行:"); scanf("%d", &x);
			printf("\n");
			printf("列:"); scanf("%d", &y);
			if (x > 0 && x<ROW+1 && y>0 && y < COL+1&&showmir[x][y]==' ')
			{
     
				markmir(showmir,ROW,COL,x,y);
				disaplayboard(showmir, ROW, COL);
			}
			else
			{
     
				printf("输入非法,请重新输入:>");
			}
		}
		else
		{
     
			printf("选择错误,请重新选择:>\n");
		}

	}
}

void game_menu()
{
     
	printf("|————————————————————————————————|\n");
	printf("|                                |\n");
	printf("|      1.paly      0.exit        |\n");
	printf("|                                |\n");
	printf("|————————————————————————————————|\n");
}
int main()
{
     
	srand((unsigned int)time(NULL));
	int input = 0;
	do
	{
     
		game_menu();
		printf("请选择:>\n");
		scanf("%d", &input);
		switch (input)
		{
     
		case 1:
			game();
			break;
		default:
			break;
		}

	} while (input);
	return 0;
}
 game.c中只作为函数功能的实现,上述已经将函数功能实现的原码贴出,故不再贴game.c的原码。

你可能感兴趣的:(实战小程序,游戏,c语言,算法,数组,游戏开发)