首页 > 其他分享 >c语言实现扫雷

c语言实现扫雷

时间:2023-05-25 13:32:36浏览次数:38  
标签:语言 show 实现 int 扫雷 board && printf data

一、简介

其中包括一个头文件function.h

两个源文件game.c和function.c

二、function.h代码

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<windows.h>

#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define MINE 10

void menu();
void initial_show_board(char show_board[ROW][COL]);
void lay_mine(int data_board[ROWS][COLS]);
void scan_mine(int data_board[ROWS][COLS], char show_board[ROW][COL]);
void printf_data_board(int data_board[ROWS][COLS]);
void printf_show_board(char show_board[ROW][COL]);
int sum_mine(int data_board[ROWS][COLS], int row, int col);
void scan_diffusion(int data_board[ROWS][COLS], char show_board[ROW][COL], int x, int y,  int* win);
void printf_result(int data_board[ROWS][COLS], char show_board[ROW][COL]);

三、function.c代码

#define _CRT_SECURE_NO_WARNINGS 1
#include"function.h"
void menu() {
	printf("********************\n");
	printf("****** 1.play ******\n");
	printf("****** 2.exit ******\n");
	printf("****** 3.rule ******\n");
	printf("********************\n");
	printf("\n请输入1或2或3进行选择:>");
}

void initial_show_board(char show_board[ROW][COL]) {
	for (int row=0;row < ROW;row++) {
		for (int col=0;col < COL;col++) {
			show_board[row][col] = '*';
		}
	}
}

void lay_mine(int data_board[ROWS][COLS]) {
	//埋雷下标范围为1--9即(1--(ROWS-2))
	int mine = 0;
	srand((unsigned)time(NULL));
	while(mine < MINE) {
		int rows= rand() % (ROWS-2) + 1;
		int cols= rand() % (COLS-2) + 1;
		if (data_board[rows][cols] == 0) {    //此处用if判断的目的是防止在同一位置重复埋雷
			data_board[rows][cols] = 1;
			mine++;
		}
		else
			;
	}
}

void scan_mine(int data_board[ROWS][COLS], char show_board[ROW][COL]) {
	int x = 0;
	int y = 0;
	int win = 0;  //计数器,计算已经扫描的区域
	while (win<(ROW*COL-MINE)) {   
		printf_show_board(show_board);
		printf("\n");
		printf("请输入扫雷坐标:>");
		scanf("%d%d", &x, &y);
		if ((x >= 1 && x <= COL) && (y >= 1 && y <= ROW)) {  //x和y必须合法
			//用户输入x=9,y=1代表
			//在show棋盘中的第1行第9列,对应下标为[y-1][x-1]
			//在data棋盘中的第2行第10列,对应下标为[y][x]
			if (data_board[y][x] == 1) {  
				show_board[y-1][x-1] = 'X';
				printf("game over\n\n");
				printf_result(data_board, show_board);
				Sleep(2000);
				break;
			}
			else {
				if(show_board[y - 1][x - 1] != '*')
				printf("此坐标已扫描\n\n");
				else
					scan_diffusion(data_board, show_board, x, y,&win);	
			}
		}	
		else
			printf("非法输入\n\n");
	}
	if (win == (ROW * COL - MINE)){
		printf("扫雷成功\n\n");
		printf_result(data_board, show_board);
		Sleep(2000);
	}
		
}

void printf_result(int data_board[ROWS][COLS], char show_board[ROW][COL]) {
	for (int row = 1;row < (ROWS-1);row++) {
		for (int col = 1;col < (COLS-1);col++) {
			if (data_board[row][col] == 1)
				show_board[row - 1][col - 1] = 'X';
		}
	}
}

int sum_mine(int data_board[ROWS][COLS], int row, int col) {
	//统计此坐标周围的8个坐标中值的总数
	int sum = data_board[row][col + 1] + data_board[row][col - 1]
		+ data_board[row + 1][col + 1] + data_board[row + 1][col] + data_board[row + 1][col - 1]
		+ data_board[row - 1][col + 1] + data_board[row - 1][col] + data_board[row - 1][col - 1];
	return  sum;
}

void scan_diffusion(int data_board[ROWS][COLS], char show_board[ROW][COL], int x, int y, int* win) {
	if (show_board[y - 1][x - 1] == '*') {
		*win = *win + 1;
		int numb_mine = sum_mine(data_board, y, x); //统计周围8格的雷数
		if (numb_mine != 0) {
			show_board[y - 1][x - 1] = 48 + numb_mine; //show_board是char型,对照ascll码表,数字0ascll码为48
		}
		else {
			show_board[y - 1][x - 1] = ' ';
			//用递归的思想传递扫描
			int min_x = x - 1;
			int max_x = x + 1;
			int min_y = y - 1;
			int max_y = y + 1;
			int temp_x = x;
			int temp_y = y;
			if ((min_x >= 1 && min_x <= COL) && (y >= 1 && y <= ROW)) {
				x = min_x;
				scan_diffusion(data_board, show_board, x, y, win);
			}
			x =temp_x;   //每一个if语句之间要相互独立,上一个if不能影响到下一个if的x和y值
			y = temp_y;

			if ((max_x >= 1 && max_x <= COL) && (y >= 1 && y <= ROW)) {
				x = max_x;
				scan_diffusion(data_board, show_board, x, y, win);
			}
			x = temp_x;
			y = temp_y;

			if ((min_x >= 1 && min_x <= COL) && (min_y >= 1 && min_y <= ROW)) {
				x = min_x;
				y = min_y;
				scan_diffusion(data_board, show_board, x, y, win);
			}
			x = temp_x;
			y = temp_y;

			if ((x >= 1 && x <= COL) && (min_y >= 1 && min_y <= ROW)) {
				y = min_y;
				scan_diffusion(data_board, show_board, x, y, win);
			}
			x = temp_x;
			y = temp_y;

			if ((max_x >= 1 && max_x <= COL) && (min_y >= 1 && min_y <= ROW)) {
				x = max_x;
				y = min_y;
				scan_diffusion(data_board, show_board, x, y, win);
			}
			x = temp_x;
			y = temp_y;

			if ((min_x >= 1 && min_x <= COL) && (max_y >= 1 && max_y <= ROW)) {
				x = min_x;
				y = max_y;
				scan_diffusion(data_board, show_board, x, y, win);
			}
			x = temp_x;
			y = temp_y;

			if ((x >= 1 && x <= COL) && (max_y >= 1 && max_y <= ROW)) {
				y = max_y;
				scan_diffusion(data_board, show_board, x, y, win);
			}
			x = temp_x;
			y = temp_y;

			if ((max_x >= 1 && max_x <= COL) && (max_y >= 1 && max_y <= ROW)) {
				x = max_x;
				y = max_y;
				scan_diffusion(data_board, show_board, x, y, win);
			}
		}
	}
}



void printf_data_board(int data_board[ROWS][COLS]) {
	for (int row=1;row < ROWS-1;row++) {
		for (int col=1;col < COLS-1;col++) {
			printf("%d ", data_board[row][col]);
		}
		printf("\n");
	}
}

void printf_show_board(char show_board[ROW][COL]) {
	int x = 0;  //打印x和y的坐标
	int y = 1;
	for (x;x <= COL;x++)
		printf("%d ", x);
	printf("\n");
	for (int row=0;row < ROW;row++) {
		printf("%d ", y);
		y++;
		for (int col=0;col < COL;col++) {
			printf("%c ", show_board[row][col]);
		}
		printf("\n");
	}
}

四、game.c代码

#define _CRT_SECURE_NO_WARNINGS 1
#include"function.h"
void game() {
	int data_board[ROWS][COLS] = { 0 };  //数据棋盘11x11
	char show_board[ROW][COL] = { 0 };   //展示棋盘9x9
	initial_show_board(show_board);  //初始化棋盘
	lay_mine(data_board);    //布设地雷
	//printf_data_board(data_board); //调试时查看data_board
	//printf("\n");
	scan_mine(data_board, show_board);  //扫雷
	printf_show_board(show_board);
	printf("\n");
	Sleep(5000);
	

}
int main() {
	while (1) {
		int input = 0;
		menu();
		scanf("%d", &input);
		switch (input) {
		case 1:
			printf("\n扫雷\n\n");
			game();
			break;
		case 2:
			printf("\n退出游戏\n");
			break;
		case 3:
			printf("\n输入坐标后,*下显示的数字为周围地雷总数(周围指上下左右和右上右下左上左下,共八个位置)\n\n");
			break;
		default:
			printf("\n非法输入\n\n");
			break;
		}
		if (input == 2)
			break;
	}
	return 0;
}


五、写程序时犯的错误

1.在二维数组传参时报错:访问权限冲突。

收集资料后发现这种报错通常是由数组访问越界引起的,但检查逻辑之后并没有发现此类型错误,最后发现是二维数组传参时格式错误。

定义函数时应为function(arr[a][b]),但使用函数时直接function(arr),不要加下标!

2.传址调用在递归中的转变

在scan_diffusion函数里我们想控制函数之外的变量,所以用了传址调用,把int型win(定义的变量,用于计数)转为了指针,但在递归时scan_diffusion函数反复调用它本身,此时win已经是指针,不用再&win,应直接用win。

标签:语言,show,实现,int,扫雷,board,&&,printf,data
From: https://blog.51cto.com/u_16102535/6346815

相关文章

  • 字符串原地修改双指针经典实现
    字符串原地修改经常遇到的一类题,双指针一个用于写入,一个用于扫描,互不干扰,各司其职。题目:https://leetcode.cn/problems/reverse-words-in-a-string/stringreverseWords(strings){reverse(s.begin(),s.end());intwrite=0,scan=0;while......
  • C#使用词嵌入向量与向量数据库为大语言模型(LLM)赋能长期记忆实现私域问答机器人落地
    ------------恢复内容开始------------在上一篇文章中我们大致讲述了一下如何通过词嵌入向量的方式为大语言模型增加长期记忆,用于落地在私域场景的问题。其中涉及到使用openai的接口进行词嵌入向量的生成以及chat模型的调用由于众所周知的原因,国内调用openai接口并不友好,所以今......
  • 单片机消息队列的实现原理和机制2
    出处消息队列在RTOS中基本都有消息队列这个组件,也是使用最常见的组件之一。1.消息队列的基本概念消息队列是一种常用于任务间通信的数据结构,队列可以在任务与任务间、中断和任务间传递信息,实现了任务接收来自其他任务或中断的不固定长度的消息。通过消息队列服务,任务或中断服务......
  • 通过智能电表与管理平台实现电力系统智能化
    安科瑞虞佳豪电力系统保护与控制系统的集成是电力系统运行中至关重要的一环。这种集成可以将保护系统和控制系统进行协调,确保电力系统的稳定性和安全性。电力系统保护与控制系统的集成主要涉及以下三个方面:保护系统、控制系统和通信系统。保护系统负责监测电力系统中的故障,并在......
  • 单片机消息队列的实现原理和机制1
    出处单片机开发过程中通常会用到“消息队列”,一般实现的方法有多种。本文给大家分享一下队列实现的原理和机制。环形队列环形队列是在实际编程极为有用的数据结构,它是一个首尾相连的FIFO的数据结构,采用数组的线性空间,数据组织简单,能很快知道队列是否满为空,能以很快速度的来存......
  • 3.6 Softmax回归的从零开始实现
    我们首先导入相关的包,并读入训练和测试所用的数据集图片的DataLoader: 这里面d2l.load_data_fashion_mnist(batch_size)读入训练和测试所用的图像数据集的DataLoader。 1.初始化模型参数Softmax回归模型参数包括W、b。假设输入特征数量为num_inputs,输出的数量(类别的数量)为n......
  • Meta 开源语音 AI 模型支持 1,100 多种语言
    自从ChatGPT火爆以来,各种通用的大型模型层出不穷,GPT4、SAM等等,本周一Meta又开源了新的语音模型MMS,这个模型号称支持4000多种语言,并且发布了支持1100种语言的预训练模型权重,最主要的是这个模型不仅支持ASR,还支持TTS,也就是说不仅可以语音转文字,还可以文字转语音。因为以前对语音方......
  • 如何利用VBA实现Excel与Word交互?
    excel与word数据交互的需求很常见,例如,利用excel明细生成word合同、利用excel明细生成word报告单、批量提取word数据到excel表格等等。通常情况下大家都是手动复制粘贴。但是其实可以用程序去简化这一部分工作。在做开发过程中,遇到过很多案例,在此总结出来。一、什么是VBA?首先我们来......
  • 直播源码技术之如何实现游戏组队功能
    随着直播行业的发展,直播间的功能技术也在迅速发展,直播间内的游戏功能就是其发展的产物,在观看直播的同时也能去玩游戏,那如果是和几个朋友一起去看直播玩直播间游戏那应该怎么办那,这就要应用到一个功能:直播源码技术游戏组队功能。一、直播源码技术游戏组队功能的意义在这个独生子女居......
  • 《花雕学AI》语言+想象+人工智能=图像魔法:微软 Bing 图像魔法师的功能、价值和评测
    你有没有想过,如果你能够用语言来创造图像,那该有多么神奇和有趣?你有没有想过,如果你能够看到你想象中的图像,那该有多么震撼和美妙?现在,这一切都可以实现了,因为微软Bing图像魔法师来了!微软Bing图像魔法师是一款能够根据用户的描述生成图像的人工智能产品,它可以让你的语言变成视觉,......