C语言编程练习,扫雷游戏

编程记录,关于B站上鹏哥C语言课程中的练习记录
记录内容:C语言实现扫雷(关于数组)

  • 思路
    test.c 测试逻辑
    game.h 存储声明
    game.c 编写运行函数

  • 用循环使游戏多次执行(do-while循环)

  • 打印菜单

  • switch选择语句,测试用户输入和测试逻辑(同三子棋和猜数字)

  • 编写函数game()实现扫雷游戏
    游戏规则,是雷:游戏失败;不是雷:显示当前一周有几个雷存在。
    1.布置雷(使用二维数组存储相关信息)(2个)
    存放雷的棋盘,无雷是0,有雷是1,这样会和排查雷产生歧义

    2.排查雷,另设置一个数组,专门存放排查雷的信息
    为了实现神秘初始化设置为*,所以数组使用字符类型,使用字符1/0
    为了避免越界,实现9×9的棋盘要保存11×11的数组大小
    mine[11][11] show[11][11]
    为了实现机动性,不使用具体数字,使用生命,9和11(9+2)都需要声明

  • 编写函数初始化棋盘,布置盘是‘0’,排查盘是*(两个数组均需要初始化)

  • 编写函数打印棋盘(增加行号和列号用于方便用户判断位置)

  • 编写函数完成布置雷(随机坐标在9×9中)(布置10个雷)(while循环)

  • 编写函数完成排查雷(从mine中排查信息放入show数组)
    在这里插入图片描述
    判断坐标合法性(用死循环直到合法,不合法反复输入)

  • 编写函数统计周围坐标雷的数目(将数字结果变为字符)(数字结果+’0’)
    同理,将各个坐标相加再减去字符0×8个,即为周围雷的个数,因此该函数仅需要一个return
    可以在前面增加static,该函数只能在该源文件看到,其他源文件看不到,因为该函数只需要满足该源文件中排查雷函数的功能,这样该函数不会和其他源文件中的函数发生冲突。

  • 增加变量,当所有非雷都成功排出,则跳出循环,并且给出成功提示,并显示当前棋盘

  • 优化内容,当该坐标不是雷且该坐标周围也没有雷,显示当前坐标一周的排查雷情况
    可以使用递归的方式。
    增加标记雷的功能
    优化内容未实现

代码如下:
game.h

//程序所需要的头文件
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>

//程序所需要的数据
//为了能获取一周的数据,棋盘为9*9,则实际棋盘为11*11
#define ROW 9
#define COL 9

#define ROWS ROW+2
#define COLS COL+2
//本次游戏的埋雷个数
#define NUM 10

//初始化二维数组
void InitBoard(char board[ROWS][COLS], int row, int col , char x);

//打印二维数组
void DisplayBoard(char board[ROWS][COLS], int row, int col);

//布置雷
void Arrange(char board[ROWS][COLS], int row, int col);

//排查雷
int FindMine(char board1[ROWS][COLS],char board2[ROWS][COLS],  int row, int col);

game.c

#include  "game.h"

//二维数组初始化
void InitBoard(char board[ROWS][COLS], int row, int col, char x)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			board[i][j] = x;
		}
	}
}

//棋盘打印
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;
	printf( "--------------------\n" );
	for (i = 0; i <= row; i++)
	{
		for (j = 0; j <= col; j++)
		{
			if (0 == i)
			{
				printf("%d ", j);
			}
			else if (0 == j)
			{
				printf("%d ", i);
			}
			else
			{
				printf("%c ", board[i][j]);
			}
		 }
		printf("\n");
	}
	printf("--------------------\n");
}

//布置雷
void Arrange(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;
	int count = 0;
	while (count != NUM)
	{
		i = rand() % row + 1;
		j = rand() % col + 1;
		//if ((strcmp(board[i][j],'0'))==0)  会报错
		if(board[i][j] == '0')
		{
			board[i][j] = '1';
			count++;
		}
	}
}

//返回周围一周雷的个数
int RetNum(char board[ROWS][COLS], int i, int j)
{
	return board[i - 1][j - 1] + board[i - 1][j] + board[i - 1][j + 1] + board[i][j - 1] + board[i][j + 1]
		+ board[i + 1][j - 1] + board[i + 1][j] + board[i + 1][j + 1] - 8 * '0';
}

//排查雷
//若当前坐标恰好是雷:输出玩家失败
//若当前坐标不是雷:显示当前坐标一周的雷的个数
int FindMine(char board1[ROWS][COLS], char board2[ROWS][COLS], int x, int y)
{
	if (board1[x][y] == '1')
	{
		printf("爆炸!玩家失败!!!\n");
		printf("爆炸!玩家失败!!!\n");
		printf("爆炸!玩家失败!!!\n");
		return 0;
	}
	else {
		int ret = 0;
		ret = RetNum(board1, x, y)+48;
		//printf("%d\n", ret);
		board2[x][y] = (char)ret;
		return 1;
	}
	

}

test.c

#include  "game.h"

void menu()
{
	printf("####################\n");
	printf("#####  1 play  #####\n");
	printf("#####  2 exit  #####\n");
	printf("####################\n");
}

void game()
{
	//为了达到初始不可见的要求,用*存放,则存放数组应为char类型
	//使用两个数组,一个存放布置雷的数据,一个存放排查雷的数据
	char board1[ROWS][COLS] = { 0 };  //布置雷
	char board2[ROWS][COLS] = { 0 };  //排查雷

	//初始化二维数组
	InitBoard(board1, ROWS, COLS, '0');
	InitBoard(board2, ROWS, COLS, '*');
	//打印二维数组
	//DisplayBoard(board1, ROW, COL);
	DisplayBoard(board2, ROW, COL);
	//布置雷
	Arrange(board1, ROW, COL);
	//DisplayBoard(board1, ROW, COL);
	//排查雷
	//重复排查,直到玩家失败或排除结束
	int x = 0;
	int y = 0;
	int count = ROW * COL - NUM;
	int ret = 0;
	do {
		printf("请输入你想排查雷的坐标(例如:1空格2):");
		scanf("%d %d", &x, &y);
		ret = FindMine(board1, board2, x, y);
		if (0 == ret)
		{
			DisplayBoard(board1, ROW, COL);
			break;
		}
		else
		{
			DisplayBoard(board2, ROW, COL);
			count--;
		}
	} while (count);
	if (count == 0)
	{
		printf("玩家胜利!!!\n");
		printf("玩家胜利!!!\n");
		printf("玩家胜利!!!\n");
	}


}

int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do{
		//打印菜单
		menu();
		printf("请输入你的操作内容:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			//printf("开始游戏\n");
			game();
			break;
		case 2:
			printf("退出游戏\n");
			break;
		default:
			printf("输入错误,请重新输入!\n");
			break;
		}
	} while (input != 2);
	

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值