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

Posted 赏一杯茶:

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了五一假期我竟然做出来了这个程序———— 扫雷 (功能完全版)相关的知识,希望对你有一定的参考价值。

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. 存放雷的数组的打印这里是引用
  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. 排查雷
    在这里插入图片描述
  2. 标记雷
    在这里插入图片描述

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);
	}
}

在这里插入图片描述

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 <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>
#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(sh

以上是关于五一假期我竟然做出来了这个程序———— 扫雷 (功能完全版)的主要内容,如果未能解决你的问题,请参考以下文章

程序员用代码求救 同事“秒懂”

利用五一假期, 我开发了一个程序员专属网址导航

1秒内通关扫雷?他创造属于自己的世界记录!Python实现自动扫雷

五一假期的惬意生活~

LDU-五一假期专练(5.1)

程序员网址导航V1.0还没使用的,已经推出2.0了