扫雷 第二次完成较复杂游戏感悟

文章目录

  • 前言
  • 一、代码及易错分析
    • test.c 内容
    • game.c
    • game.h
    • 增加扫雷的展开
  • 总结


前言

(本文章没有将扫雷的爆炸式展开实现,将放在下一篇文章中实现。)
请添加图片描述
依旧是跑路的我,今天搞了搞扫雷再次巩固一下基础知识,准备c语言进阶了。
扫雷嘛,大家基本都玩过所以就不过多介绍了先把这次代码的思路放在下面:
扫雷 第二次完成较复杂游戏感悟_第1张图片
我们依旧分为三个源文件来进行程序设计分别是
test.c 负责程序的设计主函数的布置
game.c 负责函数的实现
game.h 负责函数的引用以及定义宏

一、代码及易错分析

test.c 内容

#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void meun()
{
	printf("++++++++++++++++++++++++++++++\n");
	printf("++++++++++ 1.play ++++++++++++\n");
	printf("++++++++++ 0.exit ++++++++++++\n");
	printf("++++++++++++++++++++++++++++++\n");

}
void game()
{
	char mark1 = '0';
	char mark2 = '*';
	char show[ROWS][COLS] = { 0 };//布置的数组
	char mine[ROWS][COLS] = { 0 };//储存雷的数组
	//数组的初始化。
	Initboard(show, ROWS, COLS, mark2);//初始化show
	Initboard(mine, ROWS, COLS, mark1);//初始化mine
	//布置雷
	setmine(mine, ROW, COL);
	//数组的打印
	display(show, ROW, COL);
	//display(mine, ROW, COL);//用来储存雷的信息
	//排雷
	playmove(show, mine, ROW, COL);
}
int main(void)
{
	int i = 0;
	do
	{
		srand(time(NULL));//设置随机数
		meun();
		printf("请输入1/0>:");
		scanf("%d", &i);
		switch (i)
		{
		case 1:
			printf("开始三子棋游戏\n");
			game();
			break;
		case 0:
			printf("退出成功\n");
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}
	} while (i);
		return 0;
	
}

game.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void Initboard(char board[ROWS][COLS], int rows, int cols, char mark)
{
	int n = 0;
	int i = 0;
	for (i = 0; i < cols; i++)
	{
		for (n = 0; n < rows; n++)
		{
			board[n][i] = mark;
		}
	}

}
//易错点在传参时依旧要将board[ROWS][COLS]
//二维数组要一致
//行列按需要传输
void display(char board[ROWS][COLS],int row,int col)

{
	int i = 0;
	int j = 0;
	printf("0");
	for (i = 1; i <= row; i++)
	{
		printf(" %d", i);
	}
	printf("\n");
	for (i = 1; i <= col; i++)//从1行1列开始打印
	{
		printf("%d", i);
		for (j = 1; j <= row; j++)//从1行1列开始打印
		{
			printf(" %c", board[i][j]);//易错点一定是先打印一行而后换行打印列
		}
		printf("\n");
	}
}
void setmine(char mine[ROWS][COLS], int row, int col)//布置雷
{
	int count = COUNT;//使用COUNT在头文件里定义可以方便未来改数据
	while (count)
	{
		unsigned int x = rand() % row+1;
		unsigned int y = rand() % col+1;
		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';
			count--;
		}	
	}
}
int count(char mine[ROWS][COLS], 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 playmove(char show[ROWS][COLS], char mine[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	while (1)
	{
		printf("请输入坐标>:");
		scanf("%d %d", &x, &y);
		int win = 0;
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (mine[x][y] == '1')
			{
				//碰到雷死亡.
				printf("你碰到雷了\n");
				printf("游戏结束\n");
				break;
			}
			else if (mine[x][y] == '0')
			{
				//正常进行
				int z = count(mine, x, y);
				show[x][y] = z + '0';//因为要用字符数字所以加上'0'
				display(show, ROW, COL);
				win++;
			}
		}
		else
		{
			printf("输入错误,请重新输入。\n");
		}
		if (win == row * col - COUNT)
		{
			printf("恭喜你,成功排完所有雷\n");
			break;
		}
	}
}

易错点在相应位置注释处
我在这里总结性强调一下
1.在接收二维数组时一定要与传递的二维数组保持一致列和行数。
2.在display函数打印时一定要注意从行开始打印不然后续程序都会出问题。
3.在打印函数display要从第一行第一列开始打印(为了防止越界访问我们要将二维数组空出一圈及11 11的数组我们只用 9 9 )

game.h

声明和定义宏

#define _CRT_SECURE_NO_WARNINGS 1
#include 
#include 
#include 
#define ROWS 11
#define COLS 11
#define COUNT 10//雷的数目
#define ROW ROWS-2
#define COL COLS-2
void Initboard(char board[ROWS][COLS], int rows, int cols, char mark);
void display(char board[ROW][COL], int row, int col);
void setmine(char mine[ROWS][COLS], int row, int col);
void playmove(char show[ROWS][COLS], char mine[ROWS][COLS], int row, int col);

增加扫雷的展开

void unfold(char show[ROWS][COLS], char mine[ROWS][COLS], int x, int y)
{
	
	int ret = count(mine, x, y);
	if (ret == 0)
	{
		show[x][y] = ' ';
		if (x - 1 > 0 && y > 0 && show[x - 1][y] == '*')
		{
			unfold(show, mine, x - 1, y);
		}
		if (x - 1 > 0 && y-1 > 0 && show[x - 1][y-1] == '*')
		{
			unfold(show, mine, x - 1, y-1);
		}
		if (x - 1 > 0 && y+1 > 0 && show[x - 1][y+1] == '*')
		{
			unfold(show, mine, x - 1, y+1);
		}
		if (x > 0 && y > 0 && show[x][y] == '*')
		{
			unfold(show, mine, x, y);
		}
		if (x > 0 && y-1 > 0 && show[x][y-1] == '*')
		{
			unfold(show, mine, x, y-1);
		}
		if (x > 0 && y+1 > 0 && show[x][y+1] == '*')
		{
			unfold(show, mine, x, y+1);
		}
		if (x + 1 > 0 && y > 0 && show[x + 1][y] == '*')
		{
			unfold(show, mine, x + 1, y);
		}
		if (x + 1 > 0 && y > 0 && show[x + 1][y-1] == '*')
		{
			unfold(show, mine, x + 1, y-1);
		}
		if (x + 1 > 0 && y > 0 && show[x + 1][y+1] == '*')
		{
			unfold(show, mine, x + 1, y+1);
		}
	}
}

使用递归完成

总结

(又把game.c 哪搬过来了方便查看)
1.在接收二维数组时一定要与传递的二维数组保持一致列和行数。
2.在display函数打印时一定要注意从行开始打印不然后续程序都会出问题。
3.在打印函数display要从第一行第一列开始打印(为了防止越界访问我们要将二维数组空出一圈及11 11的数组我们只用 9 9 )
后续文章会讲扫雷的爆炸式展开
再见咯
请添加图片描述

你可能感兴趣的:(c语言,c++,开发语言)