扫雷游戏——C语言

速度款

文件----sao_lei.c 

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include"add.h"
void menu()
{
	printf("--------------\n");
	printf("----1.play----\n");
	printf("----0.exit----\n");
	printf("--------------\n");
}

void game()
{
	char mine[ROWS][COLS] = { 0 };//这是存放布置好雷了的信息
	char show[ROWS][COLS] = { 0 };//存放排查出的雷的信息,用于显示
	//初始化棋盘
	InitBoard(mine, ROWS, COLS, '0');//都是0
	InitBoard(show, ROWS, COLS, '*');//都是*
	//打印棋盘
	//Display(show, ROW, COL);
	//Display(mine, ROW, COL);//先打印看看有没有问题,检查完后,这行代码不需打印,将其注释掉
	//布置雷
	setmine(mine, ROW, COL);
	Display(show, ROW, COL);
	//Display(mine, ROW, COL);//先打印看看有没有问题,检查完后,这行代码不需打印,将其注释掉
	//排查雷
	Findmine(mine, show, ROW, COL);
}
int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		menu();//我们想玩完一把,再玩一把,可以用do-while循环,先打印菜单,在进行对游戏开始的选择。
		printf("请选择:");
		scanf("%d", &input);
		switch(input)
		{
		case 1:
			//printf("扫雷\n");//我们就需要在这里进行游戏,所以我在这自定义了一个函数---game()
			game();
			break;
		case 0:
			printf("结束游戏\n");
			break;
		default:
			printf("选择错误,请重新选择\n");
			break;
		}
	} while (input);//因为0为假,非0为真,所以在想退出游戏时,输入0,即input=0,为假,就结束循环了
	return 0;
}

文件----add.c 

#include"add.h"
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 Display(char Board[ROWS][COLS], int row, int col)
{
	printf("------来扫雷吧-----\n");
	int i = 0;
	//打印列号
	for (i = 0; i <= row; i++)
	{
		printf("%d ", i);
	}
	printf("\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");
	}
}
//
void setmine(char Board[ROWS][COLS], int row, int col)
{
	int count = COUNT;
	while (count)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (Board[x][y] == '0')
		{
			Board[x][y] = '1';
			count--;
		}
	}
}
//
int GETCOUNT(char mine[ROWS][COLS], int x, int y)
{
	return mine[x - 1][y] +
		mine[x - 1][y - 1] +
		mine[x - 1][y + 1] +
		mine[x][y - 1] +
		mine[x][y + 1] +
		mine[x - 1][y - 1] +
		mine[x + 1][y] +
		mine[x + 1][y - 1] +
		mine[x + 1][y + 1] - 8 * '0';
}
void Findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int win = 0;
	while (1)
	{
		printf("请输入你要排查的位置:\n");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (mine[x][y] == '1')
			{
				printf("完蛋,炸了\n");
				Display(mine, ROW, COL);//让你知道,怎么炸的
				break;
			}
			else
			{
				int count = GETCOUNT(mine, x, y);
				show[x][y] = count;
				system("cls");//用于清理屏幕
				Display(show, ROW, COL);//打印出来
				win++;
			}
		}
		else
		{
			printf("输入的位置非法,请重新输入:\n");
		}
	}
	if (win == row * col - COUNT)
	{
		printf("厉害哦,排查完毕\n");
		Display(mine, ROW, COL);
	}
}

文件----add.h

#pragma once
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
//为了可以随时改变方阵的难度,定义了下列符号
#define ROW 9
#define COL 9
#define ROWS 11
#define COLS 11
#define COUNT 10
//初始化棋盘
//声明
void InitBoard(char Board[ROWS][COLS], int rows, int cols, char set);//这里用小写的rows,cols是因为大写的被定义了,防止冲突
//打印棋盘
//声明
void Display(char Board[ROWS][COLS], int row, int col);//传过来的是整个数组,即11*11,在打印9*9
//布置雷
//声明
void setmine(char Board[ROWS][COLS], int row, int col);
//排查雷
//声明
void Findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);

 下面是解释哦

一.创建代码的基本逻辑 

在写这种代码时,我们需要构建一个基本的运行框架 

#include<stdio.h>
void menu()
{
	printf("--------------\n");
	printf("----1.play----\n");
	printf("----0.exit----\n");
	printf("--------------\n");
}
int main()
{
	int input = 0;
	do
	{
		menu();//我们想玩完一把,再玩一把,可以用do-while循环,先打印菜单,在进行对游戏开始的选择。
		printf("请选择:");
		scanf("%d", &input);
		switch(input)
		{
		case 1:
			//printf("扫雷\n");//我们就需要在这里进行游戏,所以我在这自定义了一个函数---game()
			game();
			break;
		case 0:
			printf("结束游戏\n");
			break;
		default:
			printf("选择错误,请重新选择\n");
			break;
		}
	} while (input);//因为0为假,非0为真,所以在想退出游戏时,输入0,即input=0,为假,就结束循环了
	return 0;
}
(1)代码的条理性 

为了代码的条理性,我们将代码分为三个文件进行运行,其中,两个源文件,一个用于创建基本路线,一个用于存放相关函数代码,还有一个头文件用与存放库函数,声明自定义函数 。

 (2)扫雷的本质----二维数组

接下来,我们应该将复杂的文字简单化,也就是说,扫雷可以简单理解为二维数组,我们就可以在game()函数里先搞二维数组,我们可以搞两个:

void game()
{
	char mine[ROWS][COLS] = { 0 };//这是存放布置好雷了的信息
	char show[ROWS][COLS] = { 0 };//存放排查出的雷的信息,用于显示
}
(3)分解

一个程序,当然有他的运行思维,在我们搞了两个二维数组后,就真正的开始对扫雷游戏进行解剖分析了,接下来,我们需要对数组进行初始化棋盘布置雷排查雷,再打印棋盘为了防止问题太晚发现(如果某处出错的话),我们将打印棋盘这个步骤放前些,放在初始化棋盘后

 

二.分解步骤

为了方便待会的解释,我先把已经声明和定义的头文件放在这了

文件----add.h---其中有对未提及的代码进行解释————eg:#include

#pragma once
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
//为了可以随时改变方阵的难度,定义了下列符号
#define ROW 9
#define COL 9
#define ROWS 11
#define COLS 11
#define COUNT 10
//初始化棋盘
//声明
void InitBoard(char Board[ROWS][COLS], int rows, int cols, char set);//这里用小写的rows,cols是因为大写的被定义了,防止冲突
//打印棋盘
//声明
void Display(char Board[ROWS][COLS], int row, int col);//传过来的是整个数组,即11*11,在打印9*9
//布置雷
//声明
void setmine(char Board[ROWS][COLS], int row, int col);
//排查雷
//声明
void Findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);

所以,在另外的两个源文件中要包含此头文件哦哦哦哦哦哦哦哦哦

(1)初始化棋盘

在此步骤,我们先定义一个函数:InitBoard 

在我们创建的有关函数的源文件中:


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

(2)打印棋盘 

在此步骤,我们先定义一个函数:Display 

在我们创建的有关函数的源文件中:

void Display(char Board[ROWS][COLS], int row, int col)
{
	printf("------来扫雷吧-----\n");
	int i = 0;
	//打印列号
	for (i = 0; i <= row; i++)
	{
		printf("%d ", i);
	}
	printf("\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");
	}
}

有了这个我们就可以早做准备----检查到此有无错误

注意,下面这一张是另外那个基本结构的源文件 

#include<stdio.h>
#include"add.h"
void menu()
{
	printf("--------------\n");
	printf("----1.play----\n");
	printf("----0.exit----\n");
	printf("--------------\n");
}

void game()
{
	char mine[ROWS][COLS] = { 0 };//这是存放布置好雷了的信息
	char show[ROWS][COLS] = { 0 };//存放排查出的雷的信息,用于显示
	//初始化棋盘
	InitBoard(mine, ROWS, COLS, '0');//都是0
	InitBoard(show, ROWS, COLS, '*');//都是*
	//打印棋盘
	Display(show, ROW, COL);
	Display(mine, ROW, COL);//先打印看看有没有问题,检查完后,这行代码不需打印,将其注释掉
}
int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		menu();//我们想玩完一把,再玩一把,可以用do-while循环,先打印菜单,在进行对游戏开始的选择。
		printf("请选择:");
		scanf("%d", &input);
		switch(input)
		{
		case 1:
			//printf("扫雷\n");//我们就需要在这里进行游戏,所以我在这自定义了一个函数---game()
			game();
			break;
		case 0:
			printf("结束游戏\n");
			break;
		default:
			printf("选择错误,请重新选择\n");
			break;
		}
	} while (input);//因为0为假,非0为真,所以在想退出游戏时,输入0,即input=0,为假,就结束循环了
	return 0;
}

 看,没问题吧,那我们就紧接着下一步吧。

(3)布置雷

在此步骤,我们先定义一个函数:setmine 

在我们创建的有关函数的源文件中:

void setmine(char Board[ROWS][COLS], int row, int col)
{
	int count = COUNT;
	while (count)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (Board[x][y] == '0')
		{
			Board[x][y] = '1';
			count--;
		}
	}
}

我们也可以打印出来看看

 是的,又没问题,下一个!!!

(4)排查雷

在此步骤,我们先定义一个函数:Findmine 

在我们创建的有关函数的源文件中:

但在此,我们思考一个问题:排雷中,如果没搞到雷,那么,此处的周为有几个雷,此处是要显示的,所以我们要再搞一个int型函数----GETCOUNT,用于计算周围雷的个数

int GETCOUNT(char mine[ROWS][COLS], int x, int y)
{
	return mine[x - 1][y] +
		mine[x - 1][y - 1] +
		mine[x - 1][y + 1] +
		mine[x][y - 1] +
		mine[x][y + 1] +
		mine[x - 1][y - 1] +
		mine[x + 1][y] +
		mine[x + 1][y - 1] +
		mine[x + 1][y + 1] - 8 * '0';//字符0的ASCII码值是48,1为49,2为50.。。。。。。
}

再就有:

void Findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int win = 0;
	while (1)
	{
		printf("请输入你要排查的位置:\n");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (mine[x][y] == '1')
			{
				printf("完蛋,炸了\n");
				Display(mine, ROW, COL);//让你知道,怎么炸的
				break;
			}
			else
			{
				int count = GETCOUNT(mine, x, y);
				show[x][y] = count;
				system("cls");//用于清理屏幕
				Display(show, ROW, COL);//打印出来
				win++;
			}
		}
		else
		{
			printf("输入的位置非法,请重新输入:\n");
		}
	}
	if (win == row * col - COUNT)
	{
		printf("厉害哦,排查完毕\n");
		Display(mine, ROW, COL);
	}
}
(5)总体步骤
#include"add.h"
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 Display(char Board[ROWS][COLS], int row, int col)
{
	printf("------来扫雷吧-----\n");
	int i = 0;
	//打印列号
	for (i = 0; i <= row; i++)
	{
		printf("%d ", i);
	}
	printf("\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");
	}
}
//
void setmine(char Board[ROWS][COLS], int row, int col)
{
	int count = COUNT;
	while (count)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (Board[x][y] == '0')
		{
			Board[x][y] = '1';
			count--;
		}
	}
}
//
int GETCOUNT(char mine[ROWS][COLS], int x, int y)
{
	return mine[x - 1][y] +
		mine[x - 1][y - 1] +
		mine[x - 1][y + 1] +
		mine[x][y - 1] +
		mine[x][y + 1] +
		mine[x - 1][y - 1] +
		mine[x + 1][y] +
		mine[x + 1][y - 1] +
		mine[x + 1][y + 1] - 8 * '0';//字符0的ASCII码值是48,1为49,2为50.。。。。。。
}
void Findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int win = 0;
	while (1)
	{
		printf("请输入你要排查的位置:\n");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (mine[x][y] == '1')
			{
				printf("完蛋,炸了\n");
				Display(mine, ROW, COL);//让你知道,怎么炸的
				break;
			}
			else
			{
				int count = GETCOUNT(mine, x, y);
				show[x][y] = count;
				system("cls");//用于清理屏幕
				Display(show, ROW, COL);//打印出来
				win++;
			}
		}
		else
		{
			printf("输入的位置非法,请重新输入:\n");
		}
	}
	if (win == row * col - COUNT)
	{
		printf("厉害哦,排查完毕\n");
		Display(mine, ROW, COL);
	}
}

  • 19
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值