C语言实现扫雷

游戏逻辑

1.游戏菜单

   打印菜单来让玩家来开始或结束游戏。

2.打印两个棋盘,也就是两个变量名分别为mine和show的二维字符型数组。

   mine二维数组用来存放地雷信息。show二维数组用来展示玩家的游戏进程。

3.实现玩家一步一步的排雷过程,若没有踩到雷则继续排雷,若踩到雷则游戏结束——玩家失败,若玩家未踩到雷并且     只剩下10格雷未排,则游戏结束——玩家通关。

一、程序框架

我们将游戏的源文件和头文件分为三个部分,分别是:game.h 、test.c 、game.c

1. game.h        

在game.h中为所有需要用到的库函数的头文件的声明,以及要在test.c源文件中使用需要在game.h中定义的自定义函数的声明。

2.test.c

test.c为游戏的整体逻辑部分,并引用头文件"game.h"。

3.game.c

game.c为游戏的实现部分,也要引用头文件"game.h"。

二、游戏的实现

1.在源文件test.c中编辑游戏的整体逻辑

1-1.创建主函数

为了让主函数简洁,通过在主函数中调用test(),在test()中实现整体逻辑。

int main()
{
	test();

	return 0;
}

1-2.定义test()函数

1.随机数的生成

2.调用menu自定义函数生成菜单

3.运用do...while语句和switch语句实现开始界面

4.在switch语句中调用game()自定义函数开始游戏进程

void test()
{
	srand((unsigned int)time(NULL)); //生成随机数的库函数调用
	int input = 0;
	do
	{
		menu();
		printf("请输入:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏 \n");
			break;
		default:
			printf("输入错误!!!(请重新输入1 or 0)");
			break;
		}
	} while (input);
}

1-3.定义menu()函数

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

1-4.定义game()函数


以下为test.c源文件的整体逻辑

#include "game.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');
	InitBoard(show, ROWS, COLS, '*');
	//DisplayBoard(mine, ROWS, COLS);
	DisplayBoard(show, ROWS, COLS);
	SetMines(mine, ROW, COL);
	//DisplayBoard(mine, ROWS, COLS);
	SweepMines(mine, show, ROWS, COLS);
}

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

int main()
{
	test();

	return 0;
}


2.game.h头文件部分的内容

头文件中包含对库函数、自定义函数的声明。

//库函数的声明
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

//定义宏常量,便于后期增加雷的数量、棋盘的大小,来增加游戏难度
#define ROW 9
#define COL 9
//这里定义COWS COLS为11行是为了方便后续对周围8个位置的雷的数量的计算
//要注意 COW COL 和 COWS COLS 使用情况的区别
#define ROWS ROW + 2
#define COLS COL + 2
#define EASY_COUNT 10

//自定义函数的声明
InitBoard(char board[ROWS][COLS], int row, int col, char set);
DisplayBoard(char board[ROWS][COLS], int row, int col);
SetMines(char board[ROWS][COLS], int row, int col);
SweepMines(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);


3.game.c 游戏逻辑的实现

game.c是对test.c中game()函数中所使用的函数的定义。

3-1.InitBoard() 自定义的棋盘初始化函数

       将mine二维数组的所有元素都初始化为 '0',将show二维数组的所有元素都初始化为 '*'。

//初始化
InitBoard(char board[ROWS][COLS], int row, int col, char set)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			board[i][j] = set;
		}
	}
}

3-2.打印二维数组的内容

//打印二维数组
DisplayBoard(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row - 1; i++)
	{
		printf("%d ", i); //在每一行前面加上行号
	}
	printf("\n");
	for (i = 1; i < row - 1; i++) //数组打印从下标为[1]开始,到下标为[9]结束一共9行
	{
		printf("%d ", i); //在每一列上面加上列号
		for(j = 1; j < col - 1; j++) //数组打印从下标为[1]开始,到下标为[9]结束一共9列
		{
			printf("%c ", board[i][j]);
		}
		printf("\n");
	}
	printf("\n");
}

打印效果:

mine二维数组:

 show二维数组:

 3-3.随机生成地雷

SetMines(char board[ROWS][COLS], int row, int col)
{
	int count = EASY_COUNT;
	int x = 0;
	int y = 0;
	while (count)
	{
		x = rand() % row + 1; //生成随机数 % 9行 得到数字1~8 加上1 得到数字 1~9
		y = rand() % col + 1; //!!!注意此处的row与col 为ROW和COL,而不是ROWS和COLS
		if (x > 0 && x <= row && y > 0 && y <= col)
		{
			if (board[x][y] == '0') //判断生成雷的位置是否为'0',避免在同一个位置重复生成
			{
				board[x][y] = '1';
				count--;
			}
		}
	}
}

效果:

 3-4.玩家游戏进程

int Mines_num(char mine[ROWS][COLS], int x, int y)
{
    //周围8个位置的字符'1'或'0'加在一起减去8个'0',就能得到雷的数量

	return mine[x + 1][y] +
		   mine[x + 1][y - 1] +
		   mine[x][y - 1] +
		   mine[x - 1][y - 1] +
		   mine[x - 1][y] +
		   mine[x - 1][y + 1] +
		   mine[x][y + 1] +
		   mine[x + 1][y + 1] - 8 * '0';
}

SweepMines(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int count = 0;

    
	while (count < COL * ROW - EASY_COUNT)
	{
		printf("请输入:>");
		scanf("%d%d", &x, &y);

        //第一步:判断玩家输入是否正确

		if (x > 0 && x < row - 1 && y > 0 && y < col - 1) 
		{
             //第二步:判断该位置是否是雷

			if (mine[x][y] == '0') //如果不是雷,则在该位置显示周围8个位置雷的数量
			{
                //调用自定义Mines_num函数计算周围雷的数量,加'0'变为字符存放在该位置。
                   
				show[x][y] = Mines_num(mine, x, y) + '0';
				DisplayBoard(show, ROWS, COLS);
				count++;
			}
			else //如果是雷,则游戏结束,并打印存放地雷的数组,让玩家了解到是什么情况
			{
				DisplayBoard(mine, ROWS, COLS);
				printf("很遗憾!!!地雷爆炸了\n");
				break;
			}
		}
		else 
		{
			printf("输入错误!!!(请重新输入坐标1 ~ 9)\n");
		}
	}

	if (count == COL * ROW - EASY_COUNT)
	{
		printf("恭喜你!!!排雷成功 !^o^!\n	");
	}
}


game.c的整体逻辑:

#include "game.h"

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

DisplayBoard(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row - 1; i++)
	{
		printf("%d ", i);
	}
	printf("\n");
	for (i = 1; i < row - 1; i++)
	{
		printf("%d ", i);
		for(j = 1; j < col - 1; j++)
		{
			printf("%c ", board[i][j]);
		}
		printf("\n");
	}
	printf("\n");
}

SetMines(char board[ROWS][COLS], int row, int col)
{
	int count = EASY_COUNT;
	int x = 0;
	int y = 0;
	while (count)
	{
		x = rand() % row + 1;
		y = rand() % col + 1;
		if (x > 0 && x <= row && y > 0 && y <= col)
		{
			if (board[x][y] == '0')
			{
				board[x][y] = '1';
				count--;
			}
		}
	}
}

int Mines_num(char mine[ROWS][COLS], int x, int y)
{
	return mine[x + 1][y] +
		   mine[x + 1][y - 1] +
		   mine[x][y - 1] +
		   mine[x - 1][y - 1] +
		   mine[x - 1][y] +
		   mine[x - 1][y + 1] +
		   mine[x][y + 1] +
		   mine[x + 1][y + 1] - 8 * '0';
}

SweepMines(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int count = 0;
	while (count < COL * ROW - EASY_COUNT)
	{
		printf("请输入:>");
		scanf("%d%d", &x, &y);
		if (x > 0 && x < row - 1 && y > 0 && y < col - 1)
		{
			if (mine[x][y] == '0')
			{
				int ret = Mines_num(mine, x, y);
				show[x][y] = ret + '0';
				DisplayBoard(show, ROWS, COLS);
				count++;
			}
			else
			{
				DisplayBoard(mine, ROWS, COLS);
				printf("很遗憾!!!地雷爆炸了\n");
				break;
			}
		}
		else
		{
			printf("输入错误!!!(请重新输入坐标1 ~ 9)\n");
		}
	}
	if (count == COL * ROW - EASY_COUNT)
	{
		printf("恭喜你!!!排雷成功 !^o^!\n	");
	}
}

到这里我们就完成了扫雷游戏的整体游戏逻辑了,快去试试看吧!

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值