C语言学习笔记-二维数组之扫雷

游戏逻辑

1.随机布置炸弹

2.选中一个位置显示该位置周围八个方格的炸弹数目总和

3.当判断某个位置为炸弹可以标记 如果所有炸弹都被标记则游戏结束

4.当被炸弹炸到游戏结束

5.选中位置周围都没有炸弹时候进行扩张,扩张出来周围所有没有炸弹的位置。

游戏组成

main.c

游戏入口

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"

int main()
{
	startgame();
	return 0;
}

game.c

函数名

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"

int num = 0;
int arr[ROWS][COLS] = { 0 };

/*游戏菜单*/
void menu()


/*字符数组初始化*/
void Initboard(char board[ROWS][COLS])


/*数组初始化*/
void Initmine(int mine[ROWS][COLS])

/*打印棋盘*/
void printboard(char board[ROWS][COLS], int row, int col)

/*打印棋盘*/
void printboard2(int board[ROWS][COLS], int row, int col)

/*布置雷*/
void setboom(int mine[ROWS][COLS])

/*检查棋已满*/
int screenboard(char board[ROWS][COLS], int row, int col)//检查棋盘是否已满


/*计算雷数目*/
int fac(int mine[ROWS][COLS],int x,int y)


/*扩张函数*/
int fac2(char board[ROWS][COLS],int mine[ROWS][COLS], int arr[ROWS][COLS],int x, int y)


/*雷位显示函数*/
int fac3(char board[ROWS][COLS], int mine[ROWS][COLS],int row,int col)


/*排查雷*/
int findboom(char board[ROWS][COLS], int mine[ROWS][COLS], int row, int col) 


/*游戏主体*/
void game(char board[ROWS][COLS], int mine[ROWS][COLS], int row, int col)

/*游戏逻辑*/
void menu2(char board[ROWS][COLS], int mine[ROWS][COLS])

/*调用主体*/
void startgame()

 布置雷

void setboom(int mine[ROWS][COLS])
{
	int x = 0;
	int y = 0;
	int i = 0;
	for (i = 1; i <= BNUM; i++)
	{
		x = rand() % (ROW);
		y = rand() % (COL);
		if ((mine[x][y] == 0)&&(x>=1&&x<=ROW) && (y>= 1 && y <= ROW))
		{
			mine[x][y] = 1;
		}
		else
			i--;

		
	}

}

扩张函数

int fac2(char board[ROWS][COLS],int mine[ROWS][COLS], int arr[ROWS][COLS],int x, int y)
{
	int temp = 0;
	arr[x][y] = 1;
	if ((fac(mine, x+1, y ) == 0)&&(arr[x+1][y]!=1))//1
	{
		board[x + 1][y] = '0';
		arr[x + 1][y] = 1;
		fac2(board, mine, arr, x + 1, y);
	}
	else if ((fac(mine, x + 1, y) != 0) && (arr[x + 1][y] != 1))//1
	{
		temp = fac(mine, x + 1, y) + 48;
		board[x + 1][y] = temp;
		arr[x + 1][y] = 1;
	}
	if ((fac(mine, x-1, y) == 0) && (arr[x - 1][y] != 1))//2
	{
		board[x - 1][y] = '0';
		arr[x - 1][y]= 1;
		fac2(board, mine, arr, x - 1, y);
	}
	else if ((fac(mine, x - 1, y) != 0) && (arr[x - 1][y] != 1))//2
	{
		temp = fac(mine, x-1, y) + 48;
		board[x - 1][y] = temp;
		arr[x - 1][y] = 1;
	}
	if ((fac(mine, x, y+1) == 0) && (arr[x][y+1] != 1))//3
	{
		board[x][y+1] = '0';
		arr[x][y + 1] = 1;
		fac2(board, mine, arr, x, y+1);
	}
	else if ((fac(mine, x, y + 1) != 0) && (arr[x][y + 1] != 1))//3
	{
		temp = fac(mine, x, y + 1) + 48;
		board[x][y + 1] = temp;
		arr[x][y+1] = 1;
	}
	if ((fac(mine, x, y-1) == 0) && (arr[x][y-1] != 1))//4
	{
		board[x][y-1] = '0';
		arr[x][y - 1] = 1;
		fac2(board, mine, arr, x, y-1);
	}
	else if ((fac(mine, x, y-1) != 0) && (arr[x][y-1] != 1))//4
	{
		temp = fac(mine, x, y-1) + 48;
		board[x][y-1] = temp;
		arr[x][y-1] = 1;
	}
	if ((fac(mine, x+1, y-1) == 0) && (arr[x + 1][y-1] != 1))//5
	{
		board[x + 1][y-1] = '0';
		arr[x + 1][y - 1] = 1;
		fac2(board, mine, arr, x + 1, y-1);
	}
	else if ((fac(mine, x + 1, y-1) != 0) && (arr[x + 1][y-1] != 1))//5
	{
		temp = fac(mine, x+1, y-1) + 48;
		board[x + 1][y-1] = temp;
		arr[x + 1][y-1] = 1;
	}
	if ((fac(mine, x+1, y+1) == 0) && (arr[x + 1][y+1] != 1))//6
	{
		board[x + 1][y+1] = '0';
		arr[x + 1][y + 1] = 1;
		fac2(board, mine, arr, x + 1, y+1);
	}
	else if ((fac(mine, x + 1, y+1) != 0) && (arr[x + 1][y+1] != 1))//6
	{
		temp = fac(mine, x+1, y+1) + 48;
		board[x + 1][y+1] = temp;
		arr[x + 1][y+1] = 1;
	}
	if ((fac(mine, x-1, y+1) == 0) && (arr[x - 1][y+1] != 1))//7
	{
		board[x - 1][y+1] = '0';
		arr[x - 1][y + 1] = 1;
		fac2(board, mine, arr, x - 1, y+1);
	}
	else if ((fac(mine, x - 1, y+1) != 0) && (arr[x - 1][y+1] != 1))//7
	{
		temp = fac(mine, x-1, y+1) + 48;
		board[x - 1][y+1] = temp;
		arr[x - 1][y+1] = 1;
	}
	if ((fac(mine, x-1, y-1) == 0) && (arr[x - 1][y-1] != 1))//8
	{
		board[x - 1][y-1] = '0';
		arr[x - 1][y - 1] = 1;
		fac2(board, mine, arr, x - 1, y-1);
	}
	else if ((fac(mine, x - 1, y-1) != 0) && (arr[x - 1][y-1] != 1))//8
	{
		temp = fac(mine, x-1, y-1) + 48;
		board[x - 1][y-1] = temp;
		arr[x - 1][y-1] = 1;
	}
}

 排雷逻辑

int findboom(char board[ROWS][COLS], int mine[ROWS][COLS], int row, int col) 
{
	int x = 0;
	int y = 0;
	int m = 0;
	char ch = '0';
	printf("请输入需要排雷的坐标\n(x坐标 y坐标 m(1标记,0取消标记/点击 \neg :1 1 0)\n");
	scanf("%d %d %d", &x, &y, &m);
	while ((ch = getchar()) != '\n')
	{
		;
	}
	if ((x > row) || (y > col) || (m != 1 && m != 0))
	{
		printf("非法输入,请重新输入\n");
		return 0;
	}
	if ((mine[x][y] == 1) && m != 1)
	{
		board[x][y] = '*';
		return 1;
	}
	else if (m == 1)
	{
		if ((board[x][y] < 48)|| (board[x][y] > 56))
		{
			board[x][y] = '#';
			arr[x][y] = 1;
			if (mine[x][y] == 1)
			{
				num++;
			}
			return 0;
		}
		else
		{
			printf("非法操作\n");
			return 0;
		}

	}
	else if ((m == 0)&&(board[x][y] == '#'))
	{
		board[x][y] = ' ';
		arr[x][y] = 0;
		return 0;
	}
	else if ((m == 0) && (mine[x][y] != 1))
	{
		int temp = fac(mine, x, y) + 48;
		if (temp == 48)
		{
			fac2(board, mine, arr, x, y);

		} 
		board[x][y] = temp;
		return 0;
	}
}

游戏主体

void game(char board[ROWS][COLS], int mine[ROWS][COLS], int row, int col)
{
	int res = 0;
	int sel = 0;
	setboom(mine);//布雷
	while (res!=1)
	{
		system("cls");
		printboard(board, row, col);
		//printboard2(mine, row, col);
		res=findboom(board, mine, row, col);
		system("cls");
		if (num == BNUM)
		{
			res = 1;
			system("cls");
			fac3(board, mine, row, col);
			printf("***********************************\n");
			printf("**********恭喜你排雷成功~**********\n");
			printf("***********************************\n");
		}
		else if (res == 1)
		{
			fac3(board, mine, row, col);
			num = 0;
			printf("***********************************\n");
			printf("**************BOOM!!!**************\n");
			printf("*************你踩到雷了************\n");
			printf("***********************************\n");
		}
		printboard(board, row, col);
		
	}
	printf("\n\n**********1.再玩一局**********\n");
	printf("**********2.退出    **********\n");

	do
	{
		char ch = '0';
		res = 0;
		scanf("%d", &sel);
		while ((ch = getchar()) != '\n')
		{
			;
		}
		switch (sel)
		{
		case 1:
			num = 0;
			Initmine(mine);
			Initmine(arr);
			Initboard(board);
			srand((unsigned int)time(NULL));
			game(board, mine, ROW, COL);
			
		case 2:
			res = 2;
			break;
		
		default :
			printf("请重新输入\n");
			break;
		}

	} while (res == 0);
}

 游戏逻辑

void menu2(char board[ROWS][COLS], int mine[ROWS][COLS])
{
	int tem = 0;
	int input = 0;
	char ch = '0';
	do
	{
		tem = scanf("%d", &input);
		ch = getchar(); //'\n';

		if (tem == 1 && ch == '\n' && (input == 1 || input == 2))
		{
			switch (input)
			{
			case 1:
				printf("游戏开始:)\n");
				game(board,mine,ROW,COL);
				input = 2;
				break;

			case 2:
				printf("游戏结束:)\n");
				break;

			default:
			error_1:
				printf("输入错误,请重新输入\n");
				break;
			}
		}
		else
		{
			while ((ch = getchar()) != '\n')
			{
				;
			}//清空缓存区
			goto error_1;
		}
	} while (input != 2);

}

 初始化部分

	char board[ROWS][COLS] = { '0' };//显示界面
	int mine[ROWS][COLS] = { 0 };//背后逻辑
	srand((unsigned int)time(NULL));
	num = 0;
	Initmine(mine);
	Initmine(arr);
	Initboard(board);
	srand((unsigned int)time(NULL));

game.h

#pragma once
#ifndef __GAME_H
#define __GAME_H
#include<stdio.h>
#include<stdlib.h>
#include<memory.h>
#include<windows.h>

#define ROW 9
#define COL 9

#define ROWS ROW+2
#define COLS COL+2

#define BNUM 15




void startgame(void);

#endif//__GAME_H

游戏截图

扩张效果

C语言学习笔记-二维数组之扫雷

 

 游戏过程

C语言学习笔记-二维数组之扫雷

 成功

C语言学习笔记-二维数组之扫雷

 失败

C语言学习笔记-二维数组之扫雷

 

备注

1.没有接入插旗的数目(总共多少雷可插旗多少次)

2.数字太多容易眼花(可以调整输出颜色)

3.可以使用easyX进行进行化界面操作

4.函数不够简洁,有的函数可以进行合并,算法逻辑也不够精简

上一篇:C语言小游戏——井字棋


下一篇:EXISTS 在SQL语句中怎么用?