0
点赞
收藏
分享

微信扫一扫

扫雷小游戏,可展开

快乐码农Alan007 2022-01-23 阅读 34

这里写目录标题

初始化棋盘

这里的大体思路还是创建两个棋盘,一个它用来存放地雷判断条件,另一个用来看,假设要9×9的棋盘一定要创建11*11的,方便计数。

void initqipan(char a[ROW1S][COL1S], int row, int col, char set)
{/*这里的a数组是显示棋盘,并且未展开前,全部初始化为‘*’ */
	for (int i = 1; i < row; i++)
	{
		for (int z = 1; z < col; z++)
		{
			a[i][z] = set;
		}
	}
}

显示棋盘

为了方便观看,加入了横标,竖标。

void show_board(char a[ROW1S][COL1S], int row, int col)
{
	printf("----------扫雷---------\n");
	for (int i = 0; i <= col; i++)
		printf("%d ", i);
	printf("\n");
	for (int z = 1; z <= row; z++)
	{
		printf("%d ", z);
		for (int i = 1; i <= col; i++)
		printf("%c ", a[z][i]);
		printf("\n");
	}
	printf("----------扫雷---------\n");
}

放置地雷

void set_mine(char mine[ROW1S][COL1S], int row, int col)
{/*我这里lei就是放置的地雷总数*/
	int count = lei;
	for (int i = 0; i < ROW1S; i++)
	{
		for (int z = 0; z < COL1S; z++)
		{/*没有地雷就是表示为0*/
			mine[i][z] = '0';
		}
	}
	while(count)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (mine[x][y] == '0')
		{/*1就是表示此处有地雷*/
			mine[x][y] = '1';
			count--;
		}
	}
}

记录周围地雷数目

int jishu(char mine[ROW1S][COL1S], int x, int y)
{/*访问周边8个格子,统计一共的地雷数量*/
	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';
}

展开

void openboard(char mine[ROW1S][COL1S], char a[ROW1S][COL1S], int x, int y)
{/*此处用的递归,访问8个格子,看看是否都无地雷,若是,展开*/
	if (jishu(mine, x, y) == 0)
	{
		a[x][y] = ' ';
		if (x > 0 && x <= ROW1 && y - 1 > 0 && y - 1 <= COL1 && a[x][y - 1] == '*')
		openboard(mine, a, x, y - 1);
		if (x - 1 > 0 && x - 1 <= ROW1 && y - 1 > 0 && y - 1 <= COL1 && a[x - 1][y - 1] == '*')
		openboard(mine, a, x - 1, y - 1);
		if (x + 1 > 0 && x + 1 <= ROW1 && y - 1 > 0 && y - 1 <= COL1 && a[x + 1][y - 1] == '*')
		openboard(mine, a, x + 1, y - 1);
		if (x > 0 && x <= ROW1 && y + 1 > 0 && y + 1 <= COL1 && a[x][y + 1] == '*')
		openboard(mine, a, x, y + 1);
		if (x + 1 > 0 && x + 1 <= ROW1 && y + 1 > 0 && y + 1 <= COL1 && a[x + 1][y + 1] == '*')
		openboard(mine, a, x, y - 1);
		if (x + 1 > 0 && x + 1 <= ROW1 && y > 0 && y <= COL1 && a[x + 1][y] == '*')
		openboard(mine, a, x + 1, y);
		if (x - 1 > 0 && x - 1 <= ROW1 && y > 0 && y <= COL1 && a[x + 1][y] == '*')
		openboard(mine, a, x + 1, y);
		if (x - 1 > 0 && x - 1 <= ROW1 && y + 1 > 0 && y + 1 <= COL1 && a[x - 1][y + 1] == '*')
		openboard(mine, a, x - 1, y + 1);
	}
	else/*结束条件*/
		a[x][y] = jishu(mine, x, y) + '0';
}

判断条件

int wins(char a[ROW1S][COL1S])
{
	int count = 0;
	for (int i = 1; i <= ROW1; i++)
	{
		for (int z = 1; z <= COL1; z++)
		{/*看看棋盘中还有多少个‘*’ */
			if (a[i][z] == '*')
				count++;
		}
	}
	return count;
}
void is_win(char mine[ROW1S][COL1S], char a[ROW1S][COL1S], int row, int col)
{
	int x, y,win=wins(a);
	while (win > lei) {
		printf("请输入坐标:");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col&&a[x][y]=='*')
		{
			if (mine[x][y] == '1') {
				system("cls");
				show_board(mine,row,col);
				printf("你被炸死了\n");
				break;
			}
			else
			{
				openboard(mine, a, x, y);
				system("cls");
				show_board(a, row, col);
			}
		}
		else
			printf("坐标非法,请重新输入\n");
	}/*每次扫描过后,棋盘中的*号会变少,直到剩余的*号全是地雷*/
	if (win == lei)
	{
		printf("你赢了\n");
		system("cls");
		show_board(mine, row, col);
	}
}

格局构造

void game()
{
	char a[ROW1S][COL1S] = { 0 };
	char mine[ROW1S][COL1S] = { 0 };
	/*初始化棋盘*/
	initqipan(a, ROW1S, COL1S, '*');
	initqipan(mine, ROW1S, COL1S, '0');
	/*埋地雷*/
	set_mine(mine, ROW1, COL1);
	show_board(a, ROW1, COL1);
	/*周边地雷计数*/
	jishu(mine, ROW1, COL1);
	/*输赢判断*/
	is_win(mine, a, ROW1, COL1);
}

整体实现

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <Windows.h>
#include <time.h>
#define ROW1 9
#define COL1 9
#define ROW1S ROW1+2
#define COL1S COL1+2
#define lei 10
void meun()
{
	printf("*****************\n");
	printf("****1. 开始  ****\n");
	printf("*****************\n");
	printf("****0.  退出 ****\n");
	printf("*****************\n");
}
void initqipan(char a[ROW1S][COL1S], int row, int col, char set)
{
	for (int i = 1; i < row; i++)
	{
		for (int z = 1; z < col; z++)
		{
			a[i][z] = set;
		}
	}
}
void show_board(char a[ROW1S][COL1S], int row, int col)
{
	printf("----------扫雷---------\n");
	for (int i = 0; i <= col; i++)
		printf("%d ", i);
	printf("\n");
	for (int z = 1; z <= row; z++)
	{
		printf("%d ", z);
		for (int i = 1; i <= col; i++)
		printf("%c ", a[z][i]);
		printf("\n");
	}
	printf("----------扫雷---------\n");
}
void set_mine(char mine[ROW1S][COL1S], int row, int col)
{
	int count = lei;
	for (int i = 0; i < ROW1S; i++)
	{
		for (int z = 0; z < COL1S; z++)
		{
			mine[i][z] = '0';
		}
	}
	while(count)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';
			count--;
		}
	}
}
int jishu(char mine[ROW1S][COL1S], 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';
}
void openboard(char mine[ROW1S][COL1S], char a[ROW1S][COL1S], int x, int y)
{
	if (jishu(mine, x, y) == 0)
	{
		a[x][y] = ' ';
		if (x > 0 && x <= ROW1 && y - 1 > 0 && y - 1 <= COL1 && a[x][y - 1] == '*')
		openboard(mine, a, x, y - 1);
		if (x - 1 > 0 && x - 1 <= ROW1 && y - 1 > 0 && y - 1 <= COL1 && a[x - 1][y - 1] == '*')
		openboard(mine, a, x - 1, y - 1);
		if (x + 1 > 0 && x + 1 <= ROW1 && y - 1 > 0 && y - 1 <= COL1 && a[x + 1][y - 1] == '*')
		openboard(mine, a, x + 1, y - 1);
		if (x > 0 && x <= ROW1 && y + 1 > 0 && y + 1 <= COL1 && a[x][y + 1] == '*')
		openboard(mine, a, x, y + 1);
		if (x + 1 > 0 && x + 1 <= ROW1 && y + 1 > 0 && y + 1 <= COL1 && a[x + 1][y + 1] == '*')
		openboard(mine, a, x, y - 1);
		if (x + 1 > 0 && x + 1 <= ROW1 && y > 0 && y <= COL1 && a[x + 1][y] == '*')
		openboard(mine, a, x + 1, y);
		if (x - 1 > 0 && x - 1 <= ROW1 && y > 0 && y <= COL1 && a[x + 1][y] == '*')
		openboard(mine, a, x + 1, y);
		if (x - 1 > 0 && x - 1 <= ROW1 && y + 1 > 0 && y + 1 <= COL1 && a[x - 1][y + 1] == '*')
		openboard(mine, a, x - 1, y + 1);
	}
	else
		a[x][y] = jishu(mine, x, y) + '0';
}
int wins(char a[ROW1S][COL1S])
{
	int count = 0;
	for (int i = 1; i <= ROW1; i++)
	{
		for (int z = 1; z <= COL1; z++)
		{
			if (a[i][z] == '*')
				count++;
		}
	}
	return count;
}
void is_win(char mine[ROW1S][COL1S], char a[ROW1S][COL1S], int row, int col)
{
	int x, y,win=wins(a);
	while (win > lei) {
		printf("请输入坐标:");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col&&a[x][y]=='*')
		{
			if (mine[x][y] == '1') {
				system("cls");
				show_board(mine,row,col);
				printf("你被炸死了\n");
				break;
			}
			else
			{
				openboard(mine, a, x, y);
				system("cls");
				show_board(a, row, col);
			}
		}
		else
			printf("坐标非法,请重新输入\n");
	}
	if (win == lei)
	{
		printf("你赢了\n");
		system("cls");
		show_board(mine, row, col);
	}
}
void game()
{
	char a[ROW1S][COL1S] = { 0 };
	char mine[ROW1S][COL1S] = { 0 };
	initqipan(a, ROW1S, COL1S, '*');
	initqipan(mine, ROW1S, COL1S, '0');
	set_mine(mine, ROW1, COL1);
	show_board(a, ROW1, COL1);
	jishu(mine, ROW1, COL1);
	is_win(mine, a, ROW1, COL1);
	jishu(mine, ROW1, COL1);
}
int main()
{
	srand((unsigned int)time(NULL));
	int input;
	do
	{
		meun();
		printf("请选择:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:printf("开始游戏\n"); game(); break;
		case 0:printf("退出游戏\n"); break;
		default:printf("请重新输入\n"); break;
		}

	} while (input);
}
举报

相关推荐

0 条评论