当前位置: 首页 > news >正文

C语言第十一课(下):优化扫雷游戏

目录

前言:

一、功能优化:

1.清理展开优化:

2.估测地雷标记:

3.剩余雷量显示:

4.胜利条件更新:

二、界面优化:

三、终极优化后最终全部代码:

1.game.h:

2.game.c:

3.test.c:

四、总结:


前言:

        在上一篇文章中,我和各位小伙伴们一起,成功编写出了一个基础版扫雷游戏。但作为基础版的它依旧存在着一些缺陷,而在本文中,我们将要对基础版扫雷游戏进行功能、界面两个方面的优化。

一、功能优化:

1.清理展开优化:

        我们上次说到,在我们进行扫雷时,当我们对某坐标进行排雷时,只能排除该坐标,而不能像真正的扫雷游戏一样,在排除一个坐标时,选中一次就可以展开相邻的一大片安全位置。我们现在就来增加并优化这个功能。

        我们该怎么优化这个功能呢?首先,我们执行该功能的前提是该位置是安全的。则我们将该功能写成一个函数,并将其添加在我们之前就写好的,判断该位置没有“地雷”、已经判断安全的位置上:

else
{
	int n = get_mine_count(mine, x, y);
	show[x][y] = n + '0';
	
    //清除展开函数:
    Cls(mine, show, row, col, x, y);

	DisplayBoard(show, ROW, COL);
	win++;
	break;
}

        接下来就是这个函数功能的实现了,首先当前选中位置已经确定为安全了,则将数组与该位置坐标全部传入函数中,若该位置存放的位置为' 0 ',则说明该以位置为中心的九宫格内均不是“地雷”,则将该位置替换为空格符'  '并放置在展示数组中,在每一次清除展开处理结束后打印展示给玩家:

void Cls(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int x, int y)
{
	if (show[x][y] == '0')
	//若此元素已经为'0',则进入此函数
	{
		show[x][y] = ' ';
	}
}

        当然,仅仅只处理选中坐标是远远不够的,我们的目标是一次性处理大片的坐标。我们的处理方法是,通过遍历来对以该坐标为中心的九宫格内其他坐标进行相同的操作:

void Cls(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int x, int y)
{
	if (show[x][y] == '0')
	//若此坐标内元素为'0',则进入此函数
	{
		show[x][y] = ' ';
		int i = x - 1;
		for (; i <= x + 1; i++)
		{
			int j = y - 1;
			for (; j <= y + 1; j++)
			{
				if (i >= 1 && i <= row && j >= 1 && j <= col)
                //检查坐标越界
				{
					int ret = get_mine_count(mine, i, j);
					show[i][j] = '0' + ret;
				}
			}
		}
	}
}

        同时,在对周围坐标进行处理前,若周围坐标已经在之前的处理中被替换为了空格符,则不再进行接下来的替换操作,进行下一个坐标的判断与操作:

void Cls(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int x, int y)
{
	if (show[x][y] == '0')
	//若此坐标内元素为'0',则进入此函数
	{
		show[x][y] = ' ';
		int i = x - 1;
		for (; i <= x + 1; i++)
		{
			int j = y - 1;
			for (; j <= y + 1; j++)
			{
				if (show[i][j] == ' ')
				{
					continue;
				}
				if (i >= 1 && i <= row && j >= 1 && j <= col)
				//检查坐标越界
				{
					int ret = get_mine_count(mine, i, j);
					show[i][j] = '0' + ret;
					Cls(mine, show, row, col, i, j);
					//不断迭代,直到不再出现0或数字为止
				}

			}
		}
	}
}

        同时我们还要注意之前进行过周围计数处理,并且需要在屏幕上打印出周围“地雷”数量的坐标,我们也要将其跳过,不能进行重复处理:

void Cls(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int x, int y)
{
	if (show[x][y] == '0')
	//若此坐标内元素为'0',则进入此函数
	{
		show[x][y] = ' ';
		int i = x - 1;
		for (; i <= x + 1; i++)
		{
			int j = y - 1;
			for (; j <= y + 1; j++)
			{
				if (show[i][j] == ' ')
				{
					continue;
				}
				if (i >= 1 && i <= row && j >= 1 && j <= col)
				//检查坐标越界
				{
					if (show[i][j] != '*')
					//如果该元素不是'*',即已经被赋值,则无需进行下面的操作
					{
						continue;
					}
					int ret = get_mine_count(mine, i, j);
					show[i][j] = '0' + ret;
				}
			}
		}
	}
}

        最后,我们通过使用迭代处理,对最初的坐标周围九宫格内的坐标进行相同的上述操作,清除展开功能实现:

void Cls(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int x, int y)
{
	if (show[x][y] == '0')
	//若此坐标内元素为'0',则进入此函数
	{
		show[x][y] = ' ';
		int i = x - 1;
		for (; i <= x + 1; i++)
		{
			int j = y - 1;
			for (; j <= y + 1; j++)
			{
				if (show[i][j] == ' ')
				{
					continue;
				}
				if (i >= 1 && i <= row && j >= 1 && j <= col)
				//检查坐标越界
				{
					if (show[i][j] != '*')
					//如果该元素不是'*',即已经被赋值,则无需进行下面的操作
					{
						continue;
					}
					int ret = get_mine_count(mine, i, j);
					show[i][j] = '0' + ret;
					Cls(mine, show, row, col, i, j);
					//不断迭代,直到不再出现0或数字为止
				}
			}
		}
	}
}

2.估测地雷标记:

        为了方便玩家更好的进行排雷,我们还可以在每次排雷前向玩家提供一个标记地雷的功能,来帮助玩家对排雷推理的展示更加清晰,使玩家的游戏过程更加轻松:

void PlayerJudge(char show[ROWS][COLS], int row, int col)
{
	int m = 0;
	do
	{
		printf("请问您是否想要标记某位置?\n");
		printf("是:1 否:0:");
		scanf("%d", &m);
		switch (m)
		{
		case 1:
			Judge(show, row, col);
			break;
		case 0:
			break;
		default:
			printf("输入有误,请重新输入:\n");
			break;
		}
	} while (m);
}

        实现原理类似于菜单函数的处理,通过do-while语句switch语句的结合使用来达到我们的目的。

        而该功能的重点依旧是标记功能函数Judge的实现定义:

void Judge(char show[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	while (1)
	{
		int a = 0;
		int b = 0;
		printf("请输入你想标记的坐标行号:");
		scanf("%d", &a);
		printf("请输入你想标记的坐标列号:");
		scanf("%d", &b);
		if (a >= 1 && a <= row && b >= 1 && b <= col)
		{
			x = a;
			y = b;
			break;
		}
		else
		{
			printf("您选择的坐标有误,请重新选择!\n");
		}
	}
	while (1)
	{
		printf("1 - 不确定是否为雷\n");
		printf("2 - 确定是雷\n");
		printf("3 - 取消标记\n");
		printf("4 - 取消操作\n");
		printf("请输入你想对该坐标进行的操作:");
		int c = 0;
		scanf("%d", &c);
		if (show[x][y] == '*')
		{
			if (c == 1)
			{
				c = 63;
				//符号?对应的ASCII码值为63
			}
			if (c == 2)
			{
				c = 35;
				//符号#对应的ASCII码值为35
			}
			if (c == 4)
			{
				printf("操作已取消,请重新选择!\n");
				DisplayBoard(show, row, col);
				break;
			}
			char ch = c;
			show[x][y] = ch;
			printf("标记成功!\n");
			DisplayBoard(show, row, col);
			break;
		}
		else if (show[x][y] == '?' || show[x][y] == '#' && c == 3)
		//如果输入3还要判断该元素是否已经被标记
		{
			show[x][y] = '*';
			printf("取消成功!\n");
			DisplayBoard(show, row, col);
			break;
		}
		if (c == 4)
		{
			printf("操作已取消,请重新选择!\n");
			break;
		}
		else
		{
			printf("输入位置不合法,请重新输入\n");
		}
	}
}

        首先,我们让玩家按照一定格式输入想要进行标记的坐标,并对该坐标进行合理性确认。接着我们定义出一个整型变量C,用于接收玩家的标记操作输入选择,这个时候我们需要对玩家输入的操作选项C进行分类操作,确保进行正确的对应操作,同时对玩家的标记操作选择合理性也应当进行检查。

        这里我们需要注意,当我们进行取消操作时,会出现两种情况,即该位置上的符号可能为' # ',也可能不为' # ',所以我们在对选项4进行处理时,应当对各种情况均考虑到位

3.剩余雷量显示:

        在上面的游戏中,我们便可以进行排雷和标记,则我们可以再度添加一个剩余雷量显示来辅助玩家进行游戏:

else
{
	int n = get_mine_count(mine, x, y);
	show[x][y] = n + '0';
	Cls(mine, show, row, col, x, y);

	int res = LeaveMine(show, row, col);
	printf("剩余雷量:%d\n", EASY_COUNT - res);

	DisplayBoard(show, ROW, COL);
	win++;
	break;
}

        剩余雷量的计算则十分简单了,它的计算不是去计算真实的雷量,我们只需要采用遍历思想,计算展示数组show中被我们标记为“地雷”的表示符号' # '即可:

int LeaveMine(char show[ROWS][COLS], int row, int col)
{
	int i = 1;
	int num = 0;
	for (i = 1; i <= row; i++)
	{
		int j = 1;
		for (j = 1; j <= col; j++)
		{
			if (show[i][j] == '#')
			{
				num++;
			}
		}
	}
	return num;
}

4.胜利条件更新:

        细心的小伙伴们应该已经发现了,在我们进行清除展开时,在函数中同时处理了大量的坐标,而在这些坐标被操作时并没有被计算,最终导致原有的胜利条件无法进行计算,于是我们就需要一个新的胜利判断函数来帮助我们进行胜利条件判断。

        那么我们应该怎么进行判断呢?这里使用的方法是,在执行完每次循环中每个坐标操作后,进行胜利条件判断,死亡或胜利则破坏循环条件,终止循环,在终止循环时再对死亡或胜利进行区别处理即可:

void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	printf("请输入您想要排查的坐标:\n");
	int x = 0;
	int y = 0;
	int win = 1;
	while (win)
	{
		PlayerJudge(show, row, col);
		printf("您想排查哪一行:");
		scanf("%d", &x);
		if (x >= 1 && x <= row)
		{
			while (1)
			{
				printf("您想排查哪一列:");
				scanf("%d", &y);
				if (y >= 1 && y <= col)
				{
					if (show[x][y] != '*')
					{
						printf("该坐标已被排查过!\n");
						DisplayBoard(show, ROW, COL);
						break;
					}
					if (mine[x][y] == '1')
					{
						DisplayBoard(mine, ROW, COL);
						printf("很遗憾,您死了!\n");
						win = 0;
						break;
					}
					else
					{
						int n = get_mine_count(mine, x, y);
						show[x][y] = n + '0';
						Cls(mine, show, row, col, x, y, &win);
						int res = LeaveMine(show, row, col);
						printf("剩余雷量:%d\n", EASY_COUNT - res);
						Really_win(show, row, col, &win);
						DisplayBoard(show, ROW, COL);
						break;
					}
				}
				else
				{
					printf("您输入的列数有误,请重新输入!\n");
				}
			}
		}
		else
		{
			printf("您输入的行数有误,请重新输入!\n");
		}
	}
}

        我们对这个胜利判断函数进行定义,当我们排出的“地雷”的数量等于设置的“地雷”数量时,且没有空余格子时,破坏判断条件:

void Really_win(char show[ROWS][COLS], int row, int col, int* win)
{
	int count1 = 0;
	int count2 = 0;
	int i = 0;
	for (i = 1; i <= row; i++)
	{
		int j = 0;
		for (j = 1; j <= col; j++)
		{
			if (show[i][j] == '#')
			{
				count1++;
			}
			if (show[i][j] == '*')
			{
				count2++;
			}
		}
	}
	if (count1 == EASY_COUNT && count2 == 0)
	{
		*win = 0;
	}
}

        接着我们最后再添加一个变量really_win,并在判断为胜利后改变其取值,再根据其取值来区别于游戏失败,反馈玩家胜利

        定义并初始化变量really_win:

int really_win = 0;

        传入函数进行操作: 

Really_win(show, row, col, &win, &really_win);

        函数进行操作

void Really_win(char show[ROWS][COLS], int row, int col, int* win, int* really_win)
{
	int count1 = 0;
	int count2 = 0;
	int i = 0;
	for (i = 1; i <= row; i++)
	{
		int j = 0;
		for (j = 1; j <= col; j++)
		{
			if (show[i][j] == '#')
			{
				count1++;
			}
			if (show[i][j] == '*')
			{
				count2++;
			}
		}
	}
	if (count1 == EASY_COUNT && count2 == 0)
	{
		*win = 0;
		*really_win = 1;
	}
}

        最后在排雷步骤最后根据really_win的取值反馈给玩家:

if (really_win == 1)
{
	printf("恭喜您,扫雷成功!\n");
}

        将其组合起来即为完整的功能实现:

void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	printf("请输入您想要排查的坐标:\n");
	int x = 0;
	int y = 0;
	int win = 1;
	int really_win = 0;
	while (win)
	{
		PlayerJudge(show, row, col);
		printf("您想排查哪一行:");
		scanf("%d", &x);
		if (x >= 1 && x <= row)
		{
			while (1)
			{
				printf("您想排查哪一列:");
				scanf("%d", &y);
				if (y >= 1 && y <= col)
				{
					if (show[x][y] != '*')
					{
						printf("该坐标已被排查过!\n");
						DisplayBoard(show, ROW, COL);
						break;
					}
					if (mine[x][y] == '1')
					{
						DisplayBoard(mine, ROW, COL);
						printf("很遗憾,您死了!\n");
						win = 0;
						break;
					}
					else
					{
						int n = get_mine_count(mine, x, y);
						show[x][y] = n + '0';
						Cls(mine, show, row, col, x, y, &win);
						int res = LeaveMine(show, row, col);
						printf("剩余雷量:%d\n", EASY_COUNT - res);
						Really_win(show, row, col, &win, &really_win);
						DisplayBoard(show, ROW, COL);
						break;
					}
				}
				else
				{
					printf("您输入的列数有误,请重新输入!\n");
				}
			}
		}
		else
		{
			printf("您输入的行数有误,请重新输入!\n");
		}
	}
	if (really_win == 1)
	{
		printf("恭喜您,扫雷成功!\n");
	}
}

二、界面优化:

        同井字棋的界面优化一样,我们也使用同样的方式对扫雷游戏进行优化,使用的函数、头文件与井字棋游戏的界面优化完全一致,这里便不再作过多阐述。

三、终极优化后最终全部代码:

1.game.h:

#pragma once

#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS ROW+2
#define EASY_COUNT 10

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

void menu();
void game();
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 mine[ROWS][ROWS], int row, int col);
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
int get_mine_count(char mine[ROWS][COLS], int x, int y);
void Cls(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int x, int y, int* win);
void Judge(char show[ROWS][COLS], int row, int col);
void PlayerJudge(char show[ROWS][COLS], int row, int col);
int LeaveMine(char show[ROWS][COLS], int row, int col);
void Really_win(char show[ROWS][COLS], int row, int col, int* win, int* really_win);

2.game.c:

#define _CRT_SECURE_NO_WARNINGS 1

#include"game.h"

//打印菜单:
void menu()
{
	printf("******************************\n");
	printf("******************************\n");
	printf("*****  欢迎来到扫雷游戏  *****\n");
	printf("*****       1.play       *****\n");
	printf("*****       0.exit       *****\n");
	printf("******************************\n");
	printf("******************************\n");
}

//初始化棋盘:
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{
	int i = 0;
	for (i = 0; i < rows; i++)
	{
		int j = 0;
		for (j = 0; j < cols; j++)
		{
			board[i][j] = set;
		}
	}
}

//打印棋盘:
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
	printf("  --------扫雷--------\n");
	int i = 0;
	printf("| \\ 1 2 3 4 5 6 7 8 9 |\n");
	for (i = 1; i <= row; i++)
	{
		int j = 0;
		printf("| %d ", i);
		for (j = 1; j <= col; j++)
		{
			printf("%c ", board[i][j]);
		}
		printf("|\n");
	}
	printf("  --------扫雷--------\n");
}

//布置雷:
void SetMine(char mine[ROWS][ROWS], int row, int col)
{
	int count = EASY_COUNT;
	while (count)
	{
		//生成随机下标:
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		//布置雷:
		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';
			count--;
		}
	}
}

//统计雷:
int get_mine_count(char mine[ROWS][COLS], int x, int y)
{
	return (mine[x - 1][y - 1] + mine[x][y - 1] + mine[x + 1][y - 1] + mine[x - 1][y] + mine[x + 1][y] + mine[x - 1][y + 1] + mine[x][y + 1] + mine[x + 1][y + 1] - 8 * '0');
}

//清理展开:
void Cls(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int x, int y, int* win)
	{
	if (show[x][y] == '0')
	//若此坐标内元素为'0',则进入此函数
	{
		show[x][y] = ' ';
		int i = x - 1;
		for (; i <= x + 1; i++)
		{
			int j = y - 1;
			for (; j <= y + 1; j++)
			{
				if (show[i][j] == ' ')
				{
					continue;
				}
				if (i >= 1 && i <= row && j >= 1 && j <= col)
				//检查坐标越界
				{
					if (show[i][j] != '*')
					//如果该元素不是'*',即已经被赋值,则无需进行下面的操作
					{
						continue;
					}
					int ret = get_mine_count(mine, i, j);
					show[i][j] = '0' + ret;
					*win++;
					Cls(mine, show, row, col, i, j, &win);
					//不断迭代,直到不再出现0或数字为止
				}
			}
		}
	}
}

//标记坐标:
void Judge(char show[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	while (1)
	{
		int a = 0;
		int b = 0;
		printf("请输入你想标记的坐标行号:");
		scanf("%d", &a);
		printf("请输入你想标记的坐标列号:");
		scanf("%d", &b);
		if (a >= 1 && a <= row && b >= 1 && b <= col)
		{
			x = a;
			y = b;
			Sleep(500);
			break;
		}
		else
		{
			system("cls");
			printf("您选择的坐标有误,请重新选择!\n");
			Sleep(1000);
			system("cls");
			DisplayBoard(show, row, col);
		}
	}
	while (1)
	{
		system("cls");
		DisplayBoard(show, row, col);
		printf("1 - 不确定是否为雷\n");
		printf("2 - 确定是雷\n");
		printf("3 - 取消标记\n");
		printf("4 - 取消操作\n");
		printf("请输入你想对该坐标进行的操作:");
		int c = 0;
		scanf("%d", &c);
		Sleep(500);
		system("cls");
		if (show[x][y] == '*')
		{
			if (c == 1)
			{
				c = 63;
				//符号?对应的ASCII码值为63
			}
			if (c == 2)
			{
				c = 35;
				//符号#对应的ASCII码值为35
			}
			if (c == 4)
			{
				printf("操作已取消,请重新选择!\n");
				DisplayBoard(show, row, col);
				break;
			}
			char ch = c;
			show[x][y] = ch;
			printf("标记成功!\n");
			DisplayBoard(show, row, col);
			break;
		}
		else if (show[x][y] == '?' || show[x][y] == '#' && c == 3)
		//如果输入3还要判断该元素是否已经被标记
		{
			show[x][y] = '*';
			printf("取消成功!\n");
			DisplayBoard(show, row, col);
			break;
		}
		else if (c == 4)
		{
			printf("操作已取消,请重新选择!\n");
			Sleep(1000);
			system("cls");
			DisplayBoard(show, row, col);
			break;
		}
		else
		{
			printf("输入位置不合法,请重新输入\n");
		}
	}
}

//标记确认:
void PlayerJudge(char show[ROWS][COLS], int row, int col)
{
	int m = 0;
	do
	{
		printf("请问您是否想要标记某位置?\n");
		printf("是:1 否:0:");
		scanf("%d", &m);
		switch (m)
		{
		case 1:
			Sleep(500);
			system("cls");
			DisplayBoard(show, ROW, COL);
			Judge(show, row, col);
			break;
		case 0:
			Sleep(1000);
			system("cls");
			DisplayBoard(show, ROW, COL);
			break;
		default:
			system("cls");
			printf("输入有误,请重新输入:\n");
			Sleep(1000);
			system("cls");
			DisplayBoard(show, ROW, COL);
			break;
		}
	} while (m);
}

//剩余雷量计算:
int LeaveMine(char show[ROWS][COLS], int row, int col)
{
	int i = 1;
	int num = 0;
	for (i = 1; i <= row; i++)
	{
		int j = 1;
		for (j = 1; j <= col; j++)
		{
			if (show[i][j] == '#')
			{
				num++;
			}
		}
	}
	return num;
}

//胜利判定:
void Really_win(char show[ROWS][COLS], int row, int col, int* win, int* really_win)
{
	int count1 = 0;
	int count2 = 0;
	int i = 0;
	for (i = 1; i <= row; i++)
	{
		int j = 0;
		for (j = 1; j <= col; j++)
		{
			if (show[i][j] == '#')
			{
				count1++;
			}
			if (show[i][j] == '*')
			{
				count2++;
			}
		}
	}
	if (count1 == EASY_COUNT && count2 == 0)
	{
		*win = 0;
		*really_win = 1;
	}
}

//排雷:
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	printf("请输入您想要排查的坐标:\n");
	int x = 0;
	int y = 0;
	int win = 1;
	int really_win = 0;
	while (win)
	{
		PlayerJudge(show, row, col);
		printf("您想排查哪一行:");
		scanf("%d", &x);
		if (x >= 1 && x <= row)
		{
			while (1)
			{
				printf("您想排查哪一列:");
				scanf("%d", &y);
				if (y >= 1 && y <= col)
				{
					if (show[x][y] != '*')
					{
						system("cls");
						printf("该坐标已被排查过!\n");
						Sleep(1000);
						system("cls");
						DisplayBoard(show, ROW, COL);
						break;
					}
					if (mine[x][y] == '1')
					{
						system("cls");
						DisplayBoard(mine, ROW, COL);
						printf("很遗憾,您死了!\n");
						win = 0;
						Sleep(1000);
						system("cls");
						break;
					}
					else
					{
						int n = get_mine_count(mine, x, y);
						show[x][y] = n + '0';
						Cls(mine, show, row, col, x, y, &win);
						int res = LeaveMine(show, row, col);
						printf("剩余雷量:%d\n", EASY_COUNT - res);
						Sleep(1000);
						system("cls");
						Really_win(show, row, col, &win, &really_win);
						DisplayBoard(show, ROW, COL);
						break;
					}
				}
				else
				{
					printf("您输入的列数有误,请重新输入!\n");
				}
			}
		}
		else
		{
			printf("您输入的行数有误,请重新输入!\n");
		}
	}
	if (really_win == 1)
	{
		system("cls");
		printf("恭喜您,扫雷成功!\n");
		Sleep(1000);
		system("cls");
	}
}

3.test.c:

#define _CRT_SECURE_NO_WARNINGS 1

#include"game.h"

//游戏逻辑:
void game()
{
	char mine[ROWS][COLS] = { 0 };
	//存放布置的雷的信息
	char show[ROWS][COLS] = { 0 };
	//存放查出的雷的信息
	//初始化棋盘
	InitBoard(mine, ROWS, COLS, '0');
	InitBoard(show, ROWS, COLS, '*');
	//打印棋盘
	DisplayBoard(show, ROW, COL);
	//布置雷
	SetMine(mine, ROW, COL);
	//扫雷
	FindMine(mine, show, ROW, COL);
}

void test()
{
	srand((unsigned int)time(NULL));
	int input = 0;
	do
	{
		menu();
		printf("请选择:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			Sleep(500);
			system("cls");
			game();
			break;
		case 0:
			printf("退出游戏...\n");
			Sleep(1000);
			break;
		default:
			system("cls");
			printf("输入错误,请重新选择!\n");
			Sleep(1000);
			system("cls");
			break;
		}
	} while (input);
}

int main()
{
	test();

	return 0;
}

四、总结:

        当我们完成以上优化后,一个扫雷游戏程序的雏形就基本完成了,我们对其功能和界面都进行了相当程度的优化。但是对于一个程序的全部优化过程来说,可远远不止如此,在以后的学习过程中,我们会学到更多知识,到时候我们还可以使用更高深的知识来对我们的游戏程序进行更深层次的优化

        到这里我们对扫雷游戏的优化就宣告结束啦,能熟练灵活的掌握、运用我们学过的知识,才是我们的最终目的。懒惰不会让你一下子跌倒,但会在不知不觉中减少你的收获;勤奋也不会让你一夜成功,但会在不知不觉中积累你的成果!

        新人初来乍到,辛苦各位小伙伴们动动小手,三连走一走 ~ ~ ~  最后,本文仍有许多不足之处,欢迎各位看官老爷随时私信批评指正!

相关文章:

  • MySQL之优化SELECT语句
  • IPv6与VoIP——ipv6接口标识与VoIP概述
  • 性能测试_JMeter_connection timed out :connect
  • SpringCloud 相关
  • 精华推荐 | 【深入浅出RocketMQ原理及实战】「底层原理挖掘系列」透彻剖析贯穿RocketMQ的存储系统的实现原理和持久化机制
  • 基于JAVA的会议管理系统参考【数据库设计、源码、开题报告】
  • 爬虫基础知识
  • LeetCode 0525. 连续数组:哈希表 + 前缀和
  • 隐私计算 FATE - 多分类神经网络算法测试
  • 【蓝桥杯Web】第十四届蓝桥杯(Web 应用开发)模拟赛 2 期 | 精品题解
  • 【web渗透思路】敏感信息泄露(网站+用户+服务器)
  • vue.js毕业设计,基于vue.js前后端分离教室预约小程序系统设计与实现
  • 2022第8届中国大学生程序设计竞赛CCPC威海站, 签到题7题
  • 微信小程序|搭建一个博客小程序
  • Spring:AOP通知获取数据(13)
  • 【跃迁之路】【699天】程序员高效学习方法论探索系列(实验阶段456-2019.1.19)...
  • chrome扩展demo1-小时钟
  • const let
  • Django 博客开发教程 16 - 统计文章阅读量
  • Fastjson的基本使用方法大全
  • JSDuck 与 AngularJS 融合技巧
  • js递归,无限分级树形折叠菜单
  • MyEclipse 8.0 GA 搭建 Struts2 + Spring2 + Hibernate3 (测试)
  • Netty源码解析1-Buffer
  • PaddlePaddle-GitHub的正确打开姿势
  • php的插入排序,通过双层for循环
  • Redis学习笔记 - pipline(流水线、管道)
  • vue+element后台管理系统,从后端获取路由表,并正常渲染
  • vue-loader 源码解析系列之 selector
  • 二维平面内的碰撞检测【一】
  • 关于字符编码你应该知道的事情
  • 使用parted解决大于2T的磁盘分区
  • 用Canvas画一棵二叉树
  • Play Store发现SimBad恶意软件,1.5亿Android用户成受害者 ...
  • Redis4.x新特性 -- 萌萌的MEMORY DOCTOR
  • ​3ds Max插件CG MAGIC图形板块为您提升线条效率!
  • (草履虫都可以看懂的)PyQt子窗口向主窗口传递参数,主窗口接收子窗口信号、参数。
  • (二十四)Flask之flask-session组件
  • (附源码)springboot猪场管理系统 毕业设计 160901
  • (附源码)ssm基于jsp的在线点餐系统 毕业设计 111016
  • (六)Hibernate的二级缓存
  • (十二)springboot实战——SSE服务推送事件案例实现
  • (一)ClickHouse 中的 `MaterializedMySQL` 数据库引擎的使用方法、设置、特性和限制。
  • (转)ABI是什么
  • .NET Core中Emit的使用
  • .net Signalr 使用笔记
  • .net 程序发生了一个不可捕获的异常
  • .NET简谈互操作(五:基础知识之Dynamic平台调用)
  • .NET业务框架的构建
  • .NET应用架构设计:原则、模式与实践 目录预览
  • .pub是什么文件_Rust 模块和文件 - 「译」
  • .set 数据导入matlab,设置变量导入选项 - MATLAB setvaropts - MathWorks 中国
  • [ C++ ] template 模板进阶 (特化,分离编译)
  • [.NET 即时通信SignalR] 认识SignalR (一)
  • [2023年]-hadoop面试真题(一)