C语言实现简单扫雷

目录

游戏基本逻辑

游戏实现部分

游戏菜单

创建棋盘

初始化棋盘

打印棋盘

设置雷

排除雷

主要逻辑

坐标标记函数

展开函数

胜负判断函数

完整源代码

声明

实现

逻辑


游戏基本逻辑

#include"game.h"

void menu()
{
	printf("*******    扫雷游戏       *********\n");
	printf("***********************************\n");
	printf("*******     1.play        *********\n");
	printf("*******     0.exit        *********\n");
	printf("***********************************\n");
}

void game()
{
	char mine[ROWS][COLS];
	char show[ROWS][COLS];
	//初始化
	board(mine, ROW, COL,'0');
	board(show, ROW, COL,'*');
	//打印棋盘
	displayboard(show, ROW, COL);
	//设置雷
	set_mine(mine, ROW, COL);
	//排除雷
	finemine(mine, show, ROW, COL);
}

int main()
{
	int input = 1;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		printf("请选择=》");
		scanf_s("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出程序\n");
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}
	} while (input);
	return 0;
}

游戏实现部分

游戏菜单

void menu()
{
	printf("*******    扫雷游戏       *********\n");
	printf("***********************************\n");
	printf("*******     1.play        *********\n");
	printf("*******     0.exit        *********\n");
	printf("***********************************\n");
}

选择1:玩游戏

选择0:退出游戏

创建棋盘

//防止排查时出现数组越界,将棋盘的大小扩大
#define ROWS 11
#define COLS 11
//但真正可用的棋盘大小是9行9列的
#define ROW ROWS-2
#define COL COLS-2
//创建两个数组
char mine[ROWS][COLS];//存储随机设置的雷的信息
char show[ROWS][COLS];//展示给玩家的棋盘,存储排查出的雷信息

【说明】:选择宏定义的方式,方便程序的修改

初始化棋盘

board(mine, ROW, COL,'0');
board(show, ROW, COL,'*');

void board(char mine[ROWS][COLS], int row, int col,char set)
{
	int i = 0;
	int j = 0;
	for (i = 1; i <= row; i++)
	{
		for (j = 1; j <= col; j++)
		{
			mine[i][j] = set;
		}
	}
}

【注意】:需要初始化两个区域,一个用于存放布置好雷的信息,初始时用字符0;

                  另外一个用于存放排查出雷的信息,初始时用字符*

打印棋盘

void displayboard(char mine[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;
	printf("----------扫雷游戏------------\n");
	for (i = 0; i <= row; i++)
	{
		printf("%d ", i);
	}
	printf("\n");
	for (i = 1; i <= row; i++)
	{
		printf("%d ", i);
		for (j = 1; j <= col; j++)
		{
			printf("%c ", mine[i][j]);
		}
		printf("\n");
	}
}

【说明】:打印行号和列号方便玩家使用

设置雷

//随机设置的雷的个数
#define easy_mine_count 10

void set_mine(char mine[ROWS][COLS], int row, int col)
{
	int i= easy_mine_count;
	while(i>0)
	{
		int x=rand()%9+1;
		int y=rand()%9+1;
		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';
			i--;
		}
	}
	
}

【注意】:

要在test函数中使用srand((unsigned int)time(NULL));将时间作为随机数种子,确保得到的行列坐标随机值。

这个在之前关于猜数字的游戏中详细讲解过,所以在这里就不过多赘述了。

排除雷

主要逻辑

void finemine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	
	while (1)
	{
		int x;
		int y;
		choose(show);//对疑似雷的坐标进行标记
		printf("请输入排查坐标:");
		scanf_s("%d%d", &x, &y);
		if (x > 0 && x < 10 && y>0 && y < 10)
		{
			if (mine[x][y] == '0')
			{
				Number_mine_around(mine, show, x, y);//判断周围雷个数,是否进行展开
				displayboard(show, ROW, COL);

			}
			else
			{
				printf("你被炸死了!!!\n");
				displayboard(mine, ROW, COL);
				break;
			}
		}
		else
			printf("坐标非法,请重新输入\n");

        //判断剩余未知区域的个数,个数为雷数时玩家赢
		if (easy_mine_count == count_show_mine(show, ROW, COL))	
        {
			printf("恭喜你,你赢了!!!\n");
			displayboard(mine, ROW, COL);
			break;
		}
	}
}

坐标标记函数

//对疑似雷的坐标进行标记
void choose(char show[ROWS][COLS])
{
	while (1)
	{
		int flag = 0;
		printf("0.排查坐标  1.标记坐标 2.取消标记\n");
		printf("请选择:");
		scanf_s("%d", &flag);
		if (flag == 1)
		{
			do
			{
				int a = 0;
				int b = 0;
				printf("请输入要标记坐标:");
				scanf_s("%d%d", &a, &b);
				if (show[a][b] == '*' && a > 0 && a <= ROW && b > 0 && b <= COL)
				{
					show[a][b] = '#';
					displayboard(show, ROW, COL);
					break;
				}
				else if (show[a][b] != '*' && a > 0 && a <= ROW && b > 0 && b <= COL)
				{
					printf("该坐标已展示,请重新输入\n");
				}
				else
				{
					printf("坐标非法,请重新输入\n");
				}
			} while (1);

		}
		else if (flag == 0)
		{
			break;
		}
		else if (flag == 2)
		{
			do
			{
				int a = 0;
				int b = 0;
				printf("请输入要取消标记坐标:");
				scanf_s("%d%d", &a, &b);
				if (show[a][b] == '#' && a > 0 && a <= ROW && b > 0 && b <= COL)
				{
					show[a][b] = '*';
					displayboard(show, ROW, COL);
					break;
				}
				else if (show[a][b] != '#' && a > 0 && a <= ROW && b > 0 && b <= COL)
				{
					printf("该坐标未标记,请重新输入\n");
					break;
				}
				else
				{
					printf("坐标非法,请重新输入\n");
					break;
				}
			} while (1);

		}
		else
		{
			printf("输入错误,请重新输入\n");
		}
	}
}

展开函数

void Number_mine_around(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{
	int i;
	int j;
	int n = 0;
	//判断周围雷个数
	for (i = -1; i < 2; i++)
	{
		for (j = -1; j < 2; j++)
		{
			if (mine[x + i][y + j] == '1')
			{
				n++;
			}
		}
	}
	show[x][y] = n + '0';
	//若周围没有雷,则展开一片
	if (show[x][y] == '0')
	{
		if (x < ROWS && x>0 && y < COLS && y - 1>0 && show[x][y - 1] == '*')
		{
			Number_mine_around(mine, show, x, y-1);
		}
		if (x < ROWS && x>0 && y + 1< COLS && y>0 && show[x][y+1] == '*')
		{
			Number_mine_around(mine, show, x, y + 1);
		}
		if (x < ROWS && x-1>0 && y < COLS && y>0 && show[x-1][y] == '*')
		{
			Number_mine_around(mine, show, x - 1, y);
		}
		if (x + 1< ROWS && x>0 && y < COLS && y>0 && show[x+1][y] == '*')
		{
			Number_mine_around(mine, show, x + 1, y);
		}
	}
}

胜负判断函数

//判断剩余未知区域的个数,个数为雷数时玩家赢
int count_show_mine(char show[ROWS][COLS], int row, int col)
{
	int count = 0;
	int i = 0;
	int j = 0;
	for (i = 1; i <= row; i++)
	{
		for (j = 1; j <= col; j++)
		{
			if (show[i][j] == '*')
			{
				count++;
			}
		}

	}
	return count;
}

完整源代码

声明

#pragma once

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

#define ROWS 11
#define COLS 11

#define ROW ROWS-2
#define COL COLS-2

//随机设置的雷的个数
#define easy_mine_count 10

//初始化
void board(char mine[ROWS][COLS],int row,int col,char set);
//打印棋盘
void displayboard(char mine[ROWS][COLS],int row,int col);
//设置雷
void set_mine(char mine[ROWS][COLS],int row,int col); 
//排除雷
void finemine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);

实现

#include"game.h"

void board(char mine[ROWS][COLS], int row, int col,char set)
{
	int i = 0;
	int j = 0;
	for (i = 1; i <= row; i++)
	{
		for (j = 1; j <= col; j++)
		{
			mine[i][j] = set;
		}
	}
}

void displayboard(char mine[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;
	printf("----------扫雷游戏------------\n");
	for (i = 0; i <= row; i++)
	{
		printf("%d ", i);
	}
	printf("\n");
	for (i = 1; i <= row; i++)
	{
		printf("%d ", i);
		for (j = 1; j <= col; j++)
		{
			printf("%c ", mine[i][j]);
		}
		printf("\n");
	}
}

void set_mine(char mine[ROWS][COLS], int row, int col)
{
	int i= easy_mine_count;
	while(i>0)
	{
		int x=rand()%9+1;
		int y=rand()%9+1;
		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';
			i--;
		}
	}
	
}

void Number_mine_around(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{
	int i;
	int j;
	int n = 0;
	//判断周围雷个数
	for (i = -1; i < 2; i++)
	{
		for (j = -1; j < 2; j++)
		{
			if (mine[x + i][y + j] == '1')
			{
				n++;
			}
		}
	}
	show[x][y] = n + '0';
	//若周围没有雷,则展开一片
	if (show[x][y] == '0')
	{
		if (x < ROWS && x>0 && y < COLS && y - 1>0 && show[x][y - 1] == '*')
		{
			Number_mine_around(mine, show, x, y-1);
		}
		if (x < ROWS && x>0 && y + 1< COLS && y>0 && show[x][y+1] == '*')
		{
			Number_mine_around(mine, show, x, y + 1);
		}
		if (x < ROWS && x-1>0 && y < COLS && y>0 && show[x-1][y] == '*')
		{
			Number_mine_around(mine, show, x - 1, y);
		}
		if (x + 1< ROWS && x>0 && y < COLS && y>0 && show[x+1][y] == '*')
		{
			Number_mine_around(mine, show, x + 1, y);
		}
	}
}

void choose(char show[ROWS][COLS])
{
	while (1)
	{
		int flag = 0;
		printf("0.排查坐标  1.标记坐标 2.取消标记\n");
		printf("请选择:");
		scanf_s("%d", &flag);
		if (flag == 1)
		{
			do
			{
				int a = 0;
				int b = 0;
				printf("请输入要标记坐标:");
				scanf_s("%d%d", &a, &b);
				if (show[a][b] == '*' && a > 0 && a <= ROW && b > 0 && b <= COL)
				{
					show[a][b] = '#';
					displayboard(show, ROW, COL);
					break;
				}
				else if (show[a][b] != '*' && a > 0 && a <= ROW && b > 0 && b <= COL)
				{
					printf("该坐标已展示,请重新输入\n");
				}
				else
				{
					printf("坐标非法,请重新输入\n");
				}
			} while (1);

		}
		else if (flag == 0)
		{
			break;
		}
		else if (flag == 2)
		{
			do
			{
				int a = 0;
				int b = 0;
				printf("请输入要取消标记坐标:");
				scanf_s("%d%d", &a, &b);
				if (show[a][b] == '#' && a > 0 && a <= ROW && b > 0 && b <= COL)
				{
					show[a][b] = '*';
					displayboard(show, ROW, COL);
					break;
				}
				else if (show[a][b] != '#' && a > 0 && a <= ROW && b > 0 && b <= COL)
				{
					printf("该坐标未标记,请重新输入\n");
					break;
				}
				else
				{
					printf("坐标非法,请重新输入\n");
					break;
				}
			} while (1);

		}
		else
		{
			printf("输入错误,请重新输入\n");
		}
	}
}

void finemine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	
	while (1)
	{
		int x;
		int y;
		choose(show);
		printf("请输入排查坐标:");
		scanf_s("%d%d", &x, &y);
		if (x > 0 && x < 10 && y>0 && y < 10)
		{
			if (mine[x][y] == '0')
			{
				Number_mine_around(mine, show, x, y);
				displayboard(show, ROW, COL);

			}
			else
			{
				printf("你被炸死了!!!\n");
				displayboard(mine, ROW, COL);
				break;
			}
		}
		else
			printf("坐标非法,请重新输入\n");

		if (easy_mine_count == count_show_mine(show, ROW, COL))
		{
			printf("恭喜你,你赢了!!!\n");
			displayboard(mine, ROW, COL);
			break;
		}
	}
}
int count_show_mine(char show[ROWS][COLS], int row, int col)//判断剩余未知区域的个数,个数为雷数时玩家赢
{
	int count = 0;
	int i = 0;
	int j = 0;
	for (i = 1; i <= row; i++)
	{
		for (j = 1; j <= col; j++)
		{
			if (show[i][j] == '*')
			{
				count++;
			}
		}

	}
	return count;
}

逻辑


#include"game.h"

void menu()
{
	printf("*******    扫雷游戏       *********\n");
	printf("***********************************\n");
	printf("*******     1.play        *********\n");
	printf("*******     0.exit        *********\n");
	printf("***********************************\n");
}

void game()
{
	char mine[ROWS][COLS];
	char show[ROWS][COLS];
	//初始化
	board(mine, ROW, COL,'0');
	board(show, ROW, COL,'*');
	//打印棋盘
	//displayboard(mine, ROW, COL);
	displayboard(show, ROW, COL);
	//设置雷
	set_mine(mine, ROW, COL);
	//displayboard(mine, ROW, COL);
	//排除雷
	finemine(mine, show, ROW, COL);
}

int main()
{
	int input = 1;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		printf("请选择=》");
		scanf_s("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出程序\n");
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}
	} while (input);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

theonly_Love

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值