目录
  • 1.游戏的功能 
  • 2.游戏实现的基本思路
    • 2.1实现菜单给玩家选择
    • 2.2初始化棋盘
    • 2.3数组大小的问题
    • 2.4对棋盘赋值
    • 2.5打印棋盘
    • 2.6布置雷
    • 2.7排查雷
  • 3.代码基本实现部分
    • 3.1主函数部分
    • 3.2 初始化棋盘
    •  3.3对两个棋盘进行赋值
    • 3.4打印棋盘
    •  3.5布置雷
    •  3.6排查雷
    •  3.7函数声明
  • 4.扫雷游戏的源代码 
    • 总结

      1.游戏的功能 

      游戏的主要功能有

      1:棋盘内有若干个雷

      2:玩家输入要排查雷的坐标

      3:在玩家输入的坐标处显示周围八个坐标有几个雷

      3:若玩家将所有的雷排查完,结束游戏,玩家胜利

      4:若玩家输入有雷的坐标,则玩家游戏失败

      5:玩完一把玩家可继续选择进入或退出游戏

      2.游戏实现的基本思路

      2.1实现菜单给玩家选择

      站在玩家的角度,我们肯定是要制作一个简易的菜单来供玩家选择的,包括进入游戏,退出游戏等等,这个步骤也很简单,我们通常把这个步骤放到主函数内实现。

      2.2初始化棋盘

      大家看上面的棋盘可别以为我只定义了一个棋盘,其实不然,我们需要用到两个棋盘。

      一个棋盘专门用来存放我们布置好的雷 ,我们把这个棋盘命名为mine吧

      一个棋盘专门展示出来给大家进行排雷 ,并且把排雷的信息存入这个数组,我们把这个棋盘命名为show吧

      注意:这两个棋盘都要定义为字符型的二维数组,而不是整型的

      这两个棋盘都要先初始化为0,在后面的过程中,大家一定要分清这两个数组哦

      2.3数组大小的问题

      虽然图中我们的棋盘时9*9大小的,但是我们前面对游戏的功能进行约定过,我们要在玩家输入的坐标处周围八个坐标有几个雷。如果我们定义的棋盘是9*9大小的。当我们输入的坐标是偏中间 比如 4,4  3 ,6 这些,我们可以很好地访问到这些坐标处周围的八个坐标,但如果我们要排查边边上的那些坐标,在访问边边上的周围的八个坐标时,就会造成越界访问,所以我们要定义11*11大小的坐标刚刚好,上下和左右两边都多出一行。只要我们打印的时候只打印中间的9*9部分就可以了。

      2.4对棋盘赋值

      这里我们要先约定好,我们是有两个棋盘的

      一个是名为mine的棋盘,  我们把它数组的内容全部初始化为字符0,0表示不是雷,我们可以用1表示是雷,后面我们布置雷的时候会用到这个字符1

      一个是名为show的棋盘,我们把这个数组全部内容初始化为字符*,玩家就是在这个棋盘上进行扫雷,每扫一个,*就少一个

      注意:赋值的时候是整个数组的大小,是11*11的部分,而不是9*9的部分

      2.5打印棋盘

      将棋盘初始化好了,我们就要把棋盘打印出来,这样玩家才好进行排雷,我们是只打印中间9*9的部分,而且只打印show数组,如果把布置好雷的mine 数组打印出来了,玩家就可以看到雷了,但我们在后面布置好雷的时候可以把mine 数组打印出来观察一下,看一下有误问题

      2.6布置雷

      这里我们就先约定好在9*9的棋盘上布置10个雷

      布置10个雷,我们就要让电脑随机生成10个坐标,然后对应的二维数组的内容赋值为字符1

      产生随机值是要用到srand函数的,如果大家对这个还不了解,可以去了解一下它的用法

      这里我就不细讲了

      2.7排查雷

      我们要让玩家输入坐标,玩家没输入一次坐标,若玩家没有被雷炸死,需要在坐标处显示坐标周围有几个雷,我们约定过布置了10个雷,所以玩家要赢的话必须排查71个坐标,若玩家输入的坐标处有雷,玩家就被炸死了,结束游戏

      3.代码基本实现部分

      3.1主函数部分

      void menu()
      {
      	printf("***********************\n");
      	printf("********1.play*********\n");
      	printf("********0.exit*********\n");
      	printf("***********************\n");
      }
      int main()
      {
      	int input = 0;
      	srand((unsigned int)time(NULL));    //产生随机数
          //我们将这个过程写成一个do……while循环,使玩家一进来就可以进行选择
      	do
      	{
      		menu();        //打印菜单
      		printf("请选择:\n");
      		scanf_s("%d", &input);
      		switch (input) //switch多分支语句
      		{
      		case 1:
      			printf("扫雷\n");
      			game();   //进入游戏
      			break;
      		case 0:
      			printf("退出游戏\n");
      			break;
      		default:
      			printf("选择错误,请重新选择\n");
      			break;
      		}
       
      	} while (input);
      }

      3.2 初始化棋盘

      棋盘的大小是11*11的,但我们后面有时只用到9*9的部分,所以我们只要分别定义两个行和列的大小,我们可以使用宏定义,方便以后修改

      #define ROW 9        //定义行和列的大小
      #define COL 9
       
      #define ROWS ROW+2
      #define COLS COL+2
      //定义两个字符型的二维数组,并初始化为0
      char mine[ROWS][COL] = { 0 };  //存放布置好雷的信息
      char show[ROWS][COLS] = { 0 }; //存放排查出来的雷的信息

       3.3对两个棋盘进行赋值

      	char mine[ROWS][COL] = { 0 };  //存放布置好雷的信息
      	char show[ROWS][COLS] = { 0 }; //存放排查出来的雷的信息
       
      	//初始化数组 
      	//第一个数组初始化为'0',第二个数组初始化为'*'
      	initboard(mine, ROWS, COLS, '0');   //因为整个数组都要进行初始化,所以传ROWS和COLS
      	initboard(show, ROWS, COLS, '*');
       
      void initboard(char board[ROWS][COLS], int rows, int cols, char set)
      {
      	int i = 0;
      	int j = 0;
      	for (i = 0; i < rows; i++)
      	{
      		for (j = 0; j < cols; j++)
      		{
      			board[i][j] = set;
      		}
      	}
      }

      3.4打印棋盘

      //将这段代码放到game函数内执行
      void displayboard(char board[ROWS][COLS], int row, int col)
      {
          //为了让玩家方便输入坐标,所以我们把棋盘的行和列打印出来
      	int i = 0;
      	int j = 0;
      	printf("-----扫雷游戏-----\n");
      	for (i = 0; i <= col; i++)  //打印行号 
      	{
      		printf("%d ", i);
      	}
      	printf("\n");
      	for (i = 1; i <= row; i++)
      	{
      		printf("%d ", i);//打印列号 
      		for (j = 1; j <= col; j++)
      		{
      			printf("%c ", board[i][j]);
      		}
      		printf("\n");
      	}
      	printf("-----扫雷游戏-----\n");
      }

       3.5布置雷

      我们要在mine数组内布置10个雷

      //布置雷 
      void setmine(char mine[ROWS][COLS], int row, int col)   
                                         //因为要把雷布置在9*9格子内,所以接受的参数是ROW和COL
      {
      	int count = 10;  //布置10个雷
      	while (count)                   //当已经布置了10个雷,退出循环
      	{
              //产生的坐标应该在1-9的坐标范围内
      		int x = rand() % row + 1;    //任何正整数模上9再加上1结果就是1-9
      		int y = rand() % col + 1; 
      		if (mine[x][y] == '0')       //如果棋盘棋盘上内容是'0',也就是说还没有布置雷的话
      		{                            //才将'1'赋值给数组,否则重新生成坐标
      			mine[x][y] = '1';
      			count--;                 //没生成一个坐标,count--
      		}
      	}
      }

       3.6排查雷

      int get_mine_count(char mine[ROWS][COLS], int x, int y)   //注意返回类型为int
      {
      	//遍历周围八个坐标 
      	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';    //周围有8个坐标
             //这里利用的是字符的ASCII码值进行转换 字符0-9的ASCII码值分别是30-39
             //8*'0'总共就是240,减去240就是雷的个数
      }
      void findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
      {
      	int x = 0;
      	int y = 0;
      	int win = 0;       //定义一个变量,统计玩家排了多少个坐标
      	while (win<row*col-10)    //当win=9*9-10的时候,代表所有雷都排完了,不需要再进入循环
      	{
      		//1.输入排查的坐标      
      		//2.检查坐标处是不是雷
      		//(1)是雷 - 炸死了
      		//(2)不是雷 -统计坐标周围有几个雷,存储排查雷的信息放到show数组内
      		printf("请输入要排查的雷的坐标\n");
      		scanf_s("%d %d", &x, &y);
      		//判断坐标是否合法
      		if (x >= 1 && x <= col && y >= 1 && y <= col)
      		{
      			//不需要调整坐标
      			if (mine[x][y] == '1')
      			{
      				printf("很遗憾,你被炸死了\n");
      				displayboard(mine, ROW, COL);
      				break;
      			}
      			else if(mine[x][y] != '1')
      			{
      				//不是雷的话,统计x,y坐标周围有几个雷
      				int count = get_mine_count(mine, x, y);  //调用这个函数,获取雷的个数
      				show[x][y] = count + '0';    //将雷的个数加上'0'就是个数对应的ASCII码值
      				//显示排查出的信息
      				displayboard(show, ROW, COL); //没排完一次雷,显示数组最新的排查信息
      				win++;   //玩家每排一个坐标,win++一次
      			}
      		}
      		else 
      		{
      			printf("输入坐标不合法,请重新输入\n");  //若玩家输入坐标不合法,提示玩家重新输入
      		}
      	}
      	if (win == 71)
      	{
      		printf("恭喜你排雷成功\n");
      		displayboard(mine, ROW, COL);
      	}
       
      }

       3.7函数声明

      最后大家不要忘了函数声明哦,我这是写在一个文件里的,大家也可以写在不同的文件里

      void initboard(char board[ROWS][COLS], int rows, int cols, char set);
      void displayboard(char board[ROWS][COLS], int row, int col);
      void setmine(char board[ROWS][COLS], int row, int col);
      void findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);

      get_mine_count函数是定义在void game函数内部的函数,因此get_mine_count函数不需要进行声明

      4.扫雷游戏的源代码 

      #include<stdio.h>
      #include<windows.h>  //Windows.h和time.h是随机数产生需要的头文件 
      #include<time.h>
       
      #define ROW 9
      #define COL 9
       
      #define ROWS ROW+2
      #define COLS COL+2
       
      void initboard(char board[ROWS][COLS], int rows, int cols, char set);
      void displayboard(char board[ROWS][COLS], int row, int col);
      void setmine(char board[ROWS][COLS], int row, int col);
      void findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
       
      //打印菜单 
      void menu()
      {
      	printf("***********************\n");
      	printf("********1.play*********\n");
      	printf("********0.exit*********\n");
      	printf("***********************\n");
      }
       
      //初始化棋盘
      void initboard(char board[ROWS][COLS], int rows, int cols, char set)
      {
      	int i = 0;
      	int j = 0;
      	for (i = 0; i < rows; i++)
      	{
      		for (j = 0; j < cols; j++)
      		{
      			board[i][j] = set;
      		}
      	}
      }
       
      //打印棋盘
      void displayboard(char board[ROWS][COLS], int row, int col)
      {
      	int i = 0;
      	int j = 0;
      	printf("-----扫雷游戏-----\n");
      	for (i = 0; i <= col; i++)  //打印行号 
      	{
      		printf("%d ", i);
      	}
      	printf("\n");
      	for (i = 1; i <= row; i++)
      	{
      		printf("%d ", i);//打印列号 
      		for (j = 1; j <= col; j++)
      		{
      			printf("%c ", board[i][j]);
      		}
      		printf("\n");
      	}
      	printf("-----扫雷游戏-----\n");
      }
       
      //布置雷 
      void setmine(char mine[ROWS][COLS], int row, int col)
      {
      	int count = 10;  //布置10个雷
      	while (count)
      	{
      		int x = rand() % row + 1; //坐标范围是1-9 
      		int y = rand() % col + 1; //
      		if (mine[x][y] == '0')
      		{
      			mine[x][y] = '1';
      			count--;
      		}
      	}
      }
       
      int get_mine_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 findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
      {
      	int x = 0;
      	int y = 0;
      	int win = 0;
      	while (win<row*col-10)
      	{
      		//1.输入排查的坐标
      		//2.检查坐标处是不是雷
      		//(1)是雷 - 炸死了
      		//(2)不是雷 -统计坐标周围有几个雷,存储排查雷的信息放到show数组内
      		printf("请输入要排查的雷的坐标\n");
      		scanf_s("%d %d", &x, &y);
      		//判断坐标是否合法
      		if (x >= 1 && x <= col && y >= 1 && y <= col)
      		{
      			//不需要调整坐标
      			if (mine[x][y] == '1')
      			{
      				printf("很遗憾,你被炸死了\n");
      				displayboard(mine, ROW, COL);
      				break;
      			}
      			else if(mine[x][y] != '1')
      			{
      				//不是雷的话,统计x,y坐标周围有几个雷
      				int count = get_mine_count(mine, x, y);
      				show[x][y] = count + '0';
      				//显示排查出的信息
      				displayboard(show, ROW, COL);
      				win++;
      			}
      		}
      		else 
      		{
      			printf("输入坐标不合法,请重新输入\n");
      		}
      	}
      	if (win == 1)
      	{
      		printf("恭喜你排雷成功\n");
      		displayboard(mine, ROW, COL);
      	}
       
      }
       
       
      void game()
      {
      	char mine[ROWS][COL] = { 0 };  //存放布置好雷的信息
      	char show[ROWS][COLS] = { 0 }; //存放排查出来的雷的信息
       
      	//初始化数组 
      	//第一个数组初始化为'0',第二个数组初始化为'*'
      	initboard(mine, ROWS, COLS, '0');
      	initboard(show, ROWS, COLS, '*');
       
      	//打印数组
      	  //这个在游戏中是不打印的 
      	displayboard(show, ROW, COL);
      	
      	//布置雷
      	setmine(mine, ROW, COL);  //布置十个雷 
      	
       
      	
      	//排查雷
      	findmine(mine, show, ROW, COL); //在mine排查,结果放到show里 
      	
      }
       
      int main()
      {
      	int input = 0;
      	srand((unsigned int)time(NULL));
      	do
      	{
      		menu();
      		printf("请选择:\n");
      		scanf_s("%d", &input);
      		switch (input)
      		{
      		case 1:
      			printf("扫雷\n");
      			game();  //扫雷游戏
      			break;
      		case 0:
      			printf("退出游戏\n");
      			break;
      		default:
      			printf("选择错误,请重新选择\n");
      			break;
      		}
       
      	} while (input);
      }

      总结

      声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。