带你快速实现【C语言】之扫雷(未优化版)

目录

一.游戏底层逻辑

二.菜单

三. 游戏设计

1.雷盘设置.

2.打印雷盘.

 3.设置雷.

4.找雷.

四.总代码

1.game.h 

2.game.c

3.test.c


一.游戏底层逻辑

要写出一款游戏,首先得要知道游戏的底层原理。

在扫雷这个游戏中,首先我们得要有一个雷盘,棋盘中要有N个雷,输入坐标后如果踩到雷,游戏结束。反之,则显示该坐标周围的雷数

二.菜单

设计任何游戏都得有一个菜单方便用户选择,和三子棋一样,我们使用do while结构,让菜单不论什么情况都能打印一次。

int main()
{
	srand((unsigned int)time(NULL));  //rand函数初始化
	int p = 0;
	do {
		menu();
		printf("n请选择->");
		scanf("%d", &p);
		switch (p)
		{
		case 1:
			game();   //选择1进入游戏,转到game函数
			break;
		case 0:
			printf("n再见n");  //退出游戏
			break;
		default:       //选择错误
			printf("n选择错误,请重新选择n");
			break;
		}
	} while(p);
}
void menu()
{
	printf("|---欢迎来到扫雷---|n");
	printf("|------------------|n");
	printf("|------1.play------|n");
	printf("|------0.exit------|n");
	printf("|------------------|n");
}

三. 游戏设计

1.雷盘设置.

这里要注意的是,如果使用1个棋盘,它又要负责设置雷,又要负责打印雷盘,又要负责标记已经扫过的雷,这显然会使得太过繁琐复杂。所以我们用两个雷盘,一个用于设置雷,一个用于展示雷盘。这里我们顺便把他初始化,第一个全部初始化为字符0,第二个全部初始化成字符*

然后,如果雷盘我们选择9*9的矩阵,但这里我们不能设置成9*9的数组,因为我们后续扫雷的会检查周围8个坐标的雷数,如果玩家刚好输入下标为9 9的坐标,去检查雷数的话会导致下标访问越界,所以这里我们把矩阵上下左右各自延展1,也就是设置成11*11的数组,这样就不会存在访问越界的问题了。

#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define mine 10
void game()
{
    char board[ROWS][COLS] = { 0 };   //设置雷
	char show[ROWS][COLS] = { 0 };    //展示
	init(board, ROWS, COLS,'0');     
	init(show, ROWS, COLS,'*');      
}
void init(char board[ROWS][COLS], int r, int c, int set)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < r; i++)
	{
		for (j = 0; j < c; j++)
		{
			board[i][j] = set;  //‘0’或者‘*’
		}
	}
}

2.打印雷盘.

初始化后,我们来检查检查是否完成,设计一个函数print打印,这里不需要把11*11的数组全部打印,因为我们玩家玩的是9*9的雷盘,只需要展示9*9的数组就好。

另外,为了帮助玩家更加直观的输入坐标,我们在第一行,第一列加上坐标

void print(char board[ROWS][COLS], int r, int c)
{
	int i = 0;
	int j = 0;
	//列标
	for (j = 0; j <= c; j++)
		printf("%d ", j);
	printf("n");
	//行标
	for (i = 1; i <= r; i++)
	{
		printf("%d ", i);
		for (j = 1; j <= c; j++)
		{
			printf("%c ", board[i][j]);
		}
		printf("n");
	}
}

 

 3.设置雷.

这里我们设置10颗雷,雷用字符‘1’表示,注意不是数字1。(后面会讲为什么用字符1)

随机生成使用rand函数,rand函数要使用srand初始化。

void set(char board[ROWS][COLS], int r, int c)
{
	int count = mine;
	while (count)           // count为0跳出循环
	{
		int x = rand() % r + 1;  //表示只在下标为1-9的地方生成
		int y = rand() % c + 1;  //表示只在下标为1-9的地方生成
		if (board[x][y] == '0')
		{
			board[x][y] = '1';
			count--;        // 每成功生成一次count--
		}
	}
}

看看效果图 

4.找雷.

 找雷,玩家输入坐标得满足2个条件:1.该坐标在1-9之间。2.该坐标未被重复扫雷。

满足条件后,如果踩到了雷,游戏结束,否则,游戏继续。

而游戏继续中,我们要把该坐标附近8个坐标的雷数打印出来,所以又需要一个函数mine_num来计算。在这里用字符1的好处就体现出来了,我们先找8个坐标中有几个字符1,

假设找到了8个字符1 ,我们减去8*字符0,就得到了数字8。

所以我们要返回一个数字,就得用算出的字符1减去8*字符0,得到数字N返回给函数。

 

最后这个游戏不能一直进行,如果一直没踩到雷的话,它结束的条件应该是除了雷的所有格子被扫过了,即win=r*c-mine的时候游戏结束

void findmine(char board[ROWS][COLS], char show[ROWS][COLS], int r, int c)
{
	int win = 0;
	while (win<r*c-mine)
	{
		int x = 0;
		int y = 0;
		printf("n请输入坐标->");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= r && y >= 1 && y <= c)
		{

			if (show[x][y] == '*')
			{
				if (board[x][y] == '1')
				{
					printf("n恭喜你,踩到雷了,游戏失败n");
					break;
				}
				else
				{
					int num = mine_num(board, x, y);
					show[x][y] = num + '0';
					win++;
				}

			}
			else
			{
				printf("n该地已被排查n");
			}
			
			if (win == r * c - mine)
		    { 
				printf("nWINn");
				print(board, r, c);
				break;
			}
		}
		else
		{
			printf("坐标非法,请重新输入n");
		}
		print(show, r, c);
	}
	
}
int mine_num(char board[ROWS][COLS], int x, int y)
{
	return ((board[x - 1][y] + board[x - 1][y - 1] + board[x - 1][y + 1] + board[x][y - 1] +
		board[x][y + 1] + board[x + 1][y - 1] + board[x + 1][y] + board[x + 1][y + 1])-8 * '0');
}

四.总代码

1.game.h 

#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define mine 10
void menu();
void game();
//初始化棋盘
void init(char board[ROWS][COLS], int r,int c,int set);
//打印棋盘
void print(char board[ROW][COL], int r, int c);
//设置雷
void set(char board[ROWS][COLS], int r, int c);
//找雷
void findmine(char board[ROWS][COLS], char[ROWS][COLS], int r, int c);

2.game.c

#define  _CRT_SECURE_NO_WARNINGS
#include"game.h"
void menu()
{
	printf("|---欢迎来到扫雷---|n");
	printf("|------------------|n");
	printf("|------1.play------|n");
	printf("|------0.exit------|n");
	printf("|------------------|n");
}

void init(char board[ROWS][COLS], int r, int c,int set)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < r; i++)
	{
		for (j = 0; j < c; j++)
		{
			board[i][j] = set;
		}
	}
}

void print(char board[ROWS][COLS], int r, int c)
{
	int i = 0;
	int j = 0;
	//列标
	for (j = 0; j <= c; j++)
		printf("%d ", j);
	printf("n");
	//行标
	for (i = 1; i <= r; i++)
	{
		printf("%d ", i);
		for (j = 1; j <= c; j++)
		{
			printf("%c ", board[i][j]);
		}
			printf("n");
		}
}
void set(char board[ROWS][COLS], int r, int c)
{
	int count = mine;
	while (count)
	{
		int x = rand() % r + 1;
		int y = rand() % c + 1;
		if (board[x][y] == '0')
		{
			board[x][y] = '1';
			count--;
		}
	}
}
int mine_num(char board[ROWS][COLS], int x, int y)
{
	return ((board[x - 1][y] + board[x - 1][y - 1] + board[x - 1][y + 1] + board[x][y - 1] +
		board[x][y + 1] + board[x + 1][y - 1] + board[x + 1][y] + board[x + 1][y + 1])-8 * '0');
}
void findmine(char board[ROWS][COLS], char show[ROWS][COLS], int r, int c)
{
	int win = 0;
	while (win<ROW*COL-mine)
	{
		int x = 0;
		int y = 0;
		printf("n请输入坐标->");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= r && y >= 1 && y <= c)
		{

			if (show[x][y] == '*')
			{
				if (board[x][y] == '1')
				{
					printf("n恭喜你,踩到雷了,游戏失败n");
					break;
				}
				else
				{
					int num = mine_num(board, x, y);
					show[x][y] = num + '0';
					win++;
				}

			}
			else
			{
				printf("n该地已被排查n");
			}
			
			if (win == ROW * COL - mine)
			{
				printf("nWINn");
				print(board, r, c);
				break;
			}
		}
		else
		{
			printf("坐标非法,请重新输入n");
		}
		print(show, r, c);
	}
	
}

3.test.c

#define  _CRT_SECURE_NO_WARNINGS
#include"game.h"
void game()
{
	char board[ROWS][COLS] = { 0 };
	char show[ROWS][COLS] = { 0 };
	init(board, ROWS, COLS,'0');
	init(show, ROWS, COLS,'*');
	//print(board, ROW, COL);
	print(show, ROW, COL);
 	set(board, ROW, COL);
	print(board, ROW, COL);
	findmine(board, show, ROW, COL);


}
int main()
{
	srand((unsigned int)time(NULL));
	int p = 0;
	do {
		menu();
		printf("n请选择->");
		scanf("%d", &p);
		switch (p)
		{
		case 1:
			game();
			break;
		case 0:
			printf("n再见n");
			break;
		default:
			printf("n选择错误,请重新选择n");
			break;
		}
	} while(p);
}

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码

)">
< <上一篇

)">
下一篇>>