《扫雷》游戏代码及其编程思路

        今天带来了《扫雷》游戏的代码及其编程思路,废话不多说,开始讲解:

一、先构思

        一个游戏打开以后先映入眼帘的是游戏的开始菜单,那么先这就展示我们的游戏菜:

这里给定两个选项“选择1开始游戏,选择0退出游戏”。

void Menu()//开始菜单
	{
		printf("************************\n");
		printf("*****输入1开始游戏******\n");
		printf("*****输入0退出游戏******\n");
		printf("************************\n");

	}

那么第二步就是选了之后应该干什么,如果选了1,那么开始,选了0,那就退出,那么如果输入了其他的数字呢?我们也可以提示玩家重新输入:

		
            int qq = 1;
            int input = 0;

        printf("请输入,按回车键结束->");
		scanf("%d", &input);
		switch (input)
		{
			case 1:
			{
			
			}break;
			case 0:
			{
			printf("您即将推出游戏\n");
			
			
			}break;

			default:
			{
			printf("输入了不合法的参数,请重新输入。\n");
			}break;
		}

这个代码有个问题,那就是完了一次之后程序就会退出,不够过瘾,那么我们就可以把它放到循环里:

	        int qq = 1;
            int input = 0;

    do
	{
	
		printf("请输入,按回车键结束->");
		scanf("%d", &input);
		switch (input)
		{
			case 1:
			{
			
			goto Begin;
			}break;
			case 0:
			{
			printf("您即将推出游戏\n");
			qq = 0;
			
			}break;

			default:
			{
			printf("输入了不合法的参数,请重新输入。\n");
			}break;
		}
			

	} while (qq);

主体大致就是这样。我们先从简单的开始:

二、代码实现

为了方便后期修改代码,我将各个部分进行模块化

首先是开始菜单

void Menu()//开始菜单
	{
		printf("************************\n");
		printf("*****输入1开始游戏******\n");
		printf("*****输入0退出游戏******\n");
		printf("************************\n");

	}

        然后是开始游戏的主体

游戏开始后,首先看到的是扫雷游戏的棋盘,那么这个棋盘应该怎么实现呢?

        我们已经学习过二维数组,这里可以通过打印数组的方式展现棋盘,那么我们先写一个打印数组的函数:

void Print_Checkerboard(char arr[Row1][Col1],int row,int col)//打印棋盘,在输入row和col时注意数组元素是否溢出(输入的数加上1需要小于等于数组元素个数(行,列))
{
	for (int i = 0; i <= col; i++)
	{
		printf("%2d", i);
	}
	printf("\n");
	for (int x = 1; x <= row; x++)
	{
		
		printf("%2d ", x);
		for (int y = 1; y <= col; y++)
		{			
			printf("%c ", arr[x][y]);
		}
		printf("\n");
	}

}

然后我们在定义两个字符型的二维数组,为什么是两个呢?一个是需要打印给玩家看的,一个是统计雷子的数量的,在后期我们可以知道原因:        

			



            char mine[Row1][Col1] = { '0' };
			char show[Row1][Col1] = { '0' };

然后再头文件里声明行和列用来设置数组的行和列

#define Row 9
#define Col 9

#define Row1 Row+2
#define Col1 Col+2

现在有了行和列,但是我们的数组空空的,好像少了点什么,在这里,我们把数组设置为11x11的大小,具体原因看后面统计雷子数量那里,然后一个数组放满字符“0”,以便用来统计雷子数量,一个数组放满字符“*”,用来显示未知的位置:

void Checkerboard_initialization(char arr[Row1][Col1], char s, int row, int col)//棋盘初始化
{
	for(int i = 0;i< row;i++)

	{
		for (int a = 0; a < col; a++)
		{
			arr[i][a] = s;
		}
	}




			Checkerboard_initialization(mine, '0', Row1, Col1);
			Checkerboard_initialization(show, '*', Row1, Col1);




然后就是将雷子放入全都是“0”的数组里:

void Checkerboard_landmine(char arr[Row1][Col1],int row,int col,int count)//放置雷,最后一个是雷的数量
{
	int i = count;
	while (i)
	{
		
		//注意把产生随机数的语句放入循环,不然随机数不变,会成为死循环
		int rands = rand() % row + 1;
		int rands1 = rand() % col + 1;

		if(arr[rands][rands1]!='1')
		{
			arr[rands][rands1] = '1';
			i--;
		}
	}
}

首先这里有一个知识点,就是生成随机数用来当做坐标,将雷子放入里面,需要用到“rand”函数,但是为了防止每次生成的随机数都是一样的,所以还需要用到“srand”函数用来设置“种子”,为了保证每次的“种子”不一样,还需用到“time”函数来返回时间戳,需要用到“stdlib.h”和“time.h”的头文件,具体用法请查询资料,这里不作过多解释。

void Rand( ) // 生成随机数种子
{
	 srand((unsigned int)time(NULL));
}

然后就是统计坐标周围的八个点的雷子数,放到的数组show里:

			int count = (arrmine[x - 1][y + 1]
				+ arrmine[x - 1][y] + arrmine[x - 1][y - 1]
				+ arrmine[x][y + 1] + arrmine[x][y - 1]
				+ arrmine[x + 1][y + 1] + arrmine[x + 1][y]
				+ arrmine[x + 1][y - 1] - 8 * '0');
			arrshow[x][y] = count + '0';//加'0'是为了将整型转化成字符型,因为数组是字符型

            这里的arrshow[][]是一个形参,因为是我的自定义函数,它也是show这个数组

             前方设置成11*11的数组就是为了便于统计9*9最边缘的雷子数

再次打印棋盘

Print_Checkerboard(arrshow, Row, Col);

如果游戏碰到雷子,游戏就会结束,如果没碰到雷,游戏继续:

			arrshow[x][y] = count + '0';//加'0'是为了将整型转化成字符型,因为数组是字符型
			if (arrmine[x][y] != '1')
			{
				Print_Checkerboard(arrshow, Row, Col);
				printf("\n");
				

				
			}
			else if (arrmine[x][y] == '1')
			{
				printf("你被炸死了,菜就多练\n");
				Print_Checkerboard(arrmine, Row, Col);
				printf("\n");
				break;
				
				
			}

如果排雷排完了,那么游戏通关

	if (coun == (Row * Col - landmine))
	{
		printf("恭喜你,游戏通关");
	}

这里if括号里的判断条件是棋盘坐标的总个数减去雷子数,用来判断雷子是否排完。

由于初学C语言,代码略显凌乱,写博客不太方便

三、以下是全部代码:

1,源文件

#define	_CRT_SECURE_NO_WARNINGS	1

#include "Game.h"


void Game_Begin(char arrmine[Row1][Col1], char arrshow[Row1][Col1] ,int landmine)//a代表雷子的数量
{
	int x, y;
	int coun = 0;
	Print_Checkerboard(arrshow, Row, Col);
	while (coun < (Row*Col - landmine))
	{
		coun++;
		printf("请输入游戏坐标(行,列),中间用空格隔开,按回车键即可输入->");
		
		(void)scanf("%d %d", &x, &y);
		if (x > Row || y > Col || x <= 0 || y <= 0)
		{
			printf("输入不正确,请重新输入\n");
		}
		
		if(x<=Row && y<=Col && x>0 && y>0)
		{
			
			int count = (arrmine[x - 1][y + 1]
				+ arrmine[x - 1][y] + arrmine[x - 1][y - 1]
				+ arrmine[x][y + 1] + arrmine[x][y - 1]
				+ arrmine[x + 1][y + 1] + arrmine[x + 1][y]
				+ arrmine[x + 1][y - 1] - 8 * '0');
			arrshow[x][y] = count + '0';//加'0'是为了将整型转化成字符型,因为数组是字符型
			if (arrmine[x][y] != '1')
			{
				Print_Checkerboard(arrshow, Row, Col);
				printf("\n");
				

				
			}
			else if (arrmine[x][y] == '1')
			{
				printf("你被炸死了,菜就多练\n");
				Print_Checkerboard(arrmine, Row, Col);
				printf("\n");
				break;
				
				
			}
			
		}
		
	}

	if (coun == (Row * Col - landmine))
	{
		printf("恭喜你,游戏通关");
	}

}



int main()
{
	int landmine=10;//设置雷子数
	int qq = 1;
	//展开游戏菜单
	 Begin:
	Menu();
	int input = 0;
	do
	{
	
		printf("请输入,按回车键结束->");
		(void)scanf("%d", &input);
		switch (input)
		{
			case 1:
			{
			//创建两个数组,作为棋盘
			char mine[Row1][Col1] = { '0' };
			char show[Row1][Col1] = { '0' };
			//棋盘初始化
			Checkerboard_initialization(mine, '0', Row1, Col1);
			Checkerboard_initialization(show, '*', Row1, Col1);

			Rand();//生成随机数种子

			Checkerboard_landmine(mine, Row, Col, landmine);//放置雷(最后一个数是雷的数量)	

			Game_Begin(mine, show, landmine);//游戏开始,最后一个是雷子数量

			goto Begin;
			}break;
			case 0:
			{
			printf("您即将推出游戏\n");
			qq = 0;
			
			}break;

			default:
			{
			printf("输入了不合法的参数,请重新输入。\n");
			}break;
		}
			

	} while (qq);


	

	return 0;
}

2,头文件和他的源文件

#define	_CRT_SECURE_NO_WARNINGS	1

#include "Game.h"

void Menu()//开始菜单
	{
		printf("************************\n");
		printf("*****输入1开始游戏******\n");
		printf("*****输入0退出游戏******\n");
		printf("************************\n");

	}




void Checkerboard_initialization(char arr[Row1][Col1], char s, int row, int col)//棋盘初始化
{
	for(int i = 0;i< row;i++)

	{
		for (int a = 0; a < col; a++)
		{
			arr[i][a] = s;
		}
	}


}




void Print_Checkerboard(char arr[Row1][Col1],int row,int col)//打印棋盘,在输入row和col时注意数组元素是否溢出(输入的数加上1需要小于等于数组元素个数(行,列))
{
	for (int i = 0; i <= col; i++)
	{
		printf("%2d", i);
	}
	printf("\n");
	for (int x = 1; x <= row; x++)
	{
		
		printf("%2d ", x);
		for (int y = 1; y <= col; y++)
		{			
			printf("%c ", arr[x][y]);
		}
		printf("\n");
	}

}



void Rand( ) // 生成随机数种子
{
	 srand((unsigned int)time(NULL));
}

void Checkerboard_landmine(char arr[Row1][Col1],int row,int col,int count)//放置雷,最后一个是雷的数量
{
	int i = count;
	while (i)
	{
		
		//注意把产生随机数的语句放入循环,不然随机数不变,会成为死循环
		int rands = rand() % row + 1;
		int rands1 = rand() % col + 1;

		if(arr[rands][rands1]!='1')
		{
			arr[rands][rands1] = '1';
			i--;
		}
	}
}






#pragma once
#include <stdio.h>
#include <stdlib.h>
#include<time.h>


#define Row 9
#define Col 9

#define Row1 Row+2
#define Col1 Col+2


 void Rand();//生成随机数种子


 void Menu();//菜单初始化



 void Checkerboard_initialization();//棋盘初始化

 void Print_Checkerboard(); //打印棋盘


 void Checkerboard_landmine(char arr[Row1][Col1],int row,int col,int count);//放置雷




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值