C语言扫雷小游戏

玩家思路:
扫雷游戏该怎么玩呢,我们想到最简单的是先选择游戏开始,然后选择难度,一般分为简单,中等难度,高等难度,选择完毕后就可以开始玩了,出现一个像棋盘的界面,然后会提示输入坐标,如果有雷就会被炸死(提高游戏趣味,第一次输入坐标遇到雷,则把雷悄悄移走),无雷会显示此坐标周围八个坐标中雷的个数。然后就一步步玩下去,如果成功把所有的雷找出,那么恭喜你成功了,或者你在玩时触碰到雷就会游戏失败。
代码思路:
那么代码中该如何实现游戏呢? 首先游戏界面经思考可得,一个数组即存放雷有显示某坐标周围雷的个数,且还要不断打印游戏界面,显然不好实现,因此应该定义2个数组,数组1中应该布雷,数组2中显示雷的个数,且不断打印数组2游戏界面,在游戏失败或者游戏成功时,打印数组1界面,需要让玩家看到所有雷的布局。
其次的是两个数组的大小问题,否则在计算最边上的坐标周围雷个数时将很难计算,所有我们可以设置2个不同的行和列,并使两个行数和列数都相差2,这样在定义不同函数时,传递不同的行列参数,可以很省精力,比如最开始两个数组和计算坐标周围雷个数时需要设置成大的行列,而布雷,排雷和打印时需要设置成小行列。
最后两个数组中应该放什么,显然应该放字符,这样打印时可避免很多问题,所以数组1中初始化为字符0,数组2中初始化为’*’,然后布雷时把雷设置成字符1,这样在计算某坐标周围雷个数时会变的很容易,最后把某坐标周围雷个数也设置成字符1,2,3,4,5,6,7,8,某坐标雷个数最多为8个。最后就是各个函数的实现了,代码分了三个文件test.h ,test.c ,game.c ,具体实现如下:

test.h----头文件

#ifndef __TEST_H__
#define __TEST_H__

#define _CRT_SECURE_NO_WARNINGS 1       //编译环境不同,主要解决scanf函数报错问题

# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <time.h>

#define  ROW 9      //小行数
#define  COL 9      //小列数

#define EASY_COUNT 10        //难度,雷数量
#define MIND_COUNT 30
#define HARD_COUNT 50

#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,int COUNT);     //布雷函数声明
void FindMine (char ArrBoard[ROWS][COLS],char ShowBoard[ROWS][COLS],int row,int col,int COUNT);      //排雷函数声明
int GetMineCount (char Arr[ROWS][COLS],int x,int y);      //计算坐标周围雷个数函数声明

#endif __TEST_H__

test.c----文件

   #include "test.h"

1.先定义菜单函数
2.在自定义游戏函数
3.主函数

void menu ()                          // 菜单函数
{
  printf ("***********************\n");
  printf ("****** 1.开始 *********\n");
  printf ("****** 0.退出 *********\n");
  printf ("****** 2.简单 *********\n");
  printf ("****** 3.中等难度 ****\n");
  printf ("****** 4.高等难度 ****\n"); 
  printf ("***********************\n");

}
void game ()                          //游戏函数
{     int count=0;
	  int word;
	  char arr[ROWS][COLS]={0};         //定义布雷的数组,
	  char show[ROWS][COLS]={0};     //定义向玩家展示的数组
again:		  
	  printf ("请选择难度:  ");           //难度选择,三个等级
	  scanf ("%d",&word);
	  switch (word)
	  {
	  case 2 :
             count=EASY_COUNT;
	         break;
	    
	  case 3 :
			 count= MIND_COUNT ;
			 break;
	  case 4 :
			 count= HARD_COUNT ;
			 break;
	default :
			printf ("输入错误,请重新选择难度\n");
			goto again;
	  }
	InitBoard (arr,ROWS,COLS,'0');         //调用初始化函数,使布雷数组为'0'
	InitBoard (show,ROWS,COLS,'*');       //调用初始化函数,使先玩家展示数组初始化为'*'
    SetMine(arr,ROW,COL,count);          //调用布雷函数,并传递雷的个数
	DisplayBoard(show,ROW,COL);          //调用打印数组函数,打印向玩家展示数组
	//DisplayBoard (arr,ROW,COL);        //调用打印数组函数,方便测试
	FindMine (arr,show,ROW,COL,count);   //调用排雷函数,并传递雷个数
	}
int main ()
{
   int input=0;
   srand((unsigned int) time(NULL));       //这个是种子函数 为rand函数提供不同的种子 每次运行程序产生不同的随机数
      do
	  {
        menu ();
		printf ("请选择游戏开始或退出: ");      
		scanf ("%d",&input);
		switch (input)
		{
			case 1 :
				game ();
				break;
			case 0 :
				printf ("退出游戏\n");
				break;
			default :
				printf ("输入错误,请重新输入\n");
				break;
		}
       }
	  while (input);
	  system ("pause");         //系统函数,防止运行结果快闪
	  return 0;
}

运行界面如图:
a.选择成功时
在这里插入图片描述
b.选择失败时
在这里插入图片描述

game.c—游戏函数定义文件

#include "test.h"

1.数组初始化函数,利用memset函数给数组赋值

void InitBoard (char board[ROWS][COLS],int rows,int cols,char set)   
{
  memset (&board[0][0],set,rows*cols*sizeof (board[0][0]));  //从二维数组的首地址开始进行赋值,把set赋给char board[ROWS][COLS]
}
}

2.打印游戏界面(打印数组函数),主要利用for循环

void DisplayBoard (char board[ROWS][COLS],int row,int col)
{
	int i=0;
	int j=0;
	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.布雷函数,主要数组坐标随机布雷

void  SetMine(char board[ROWS][COLS],int row,int col,int COUNT)
{  
  while (COUNT)
  {
    int x=rand()%row+1;
	int y=rand()%col+1;          //生成随机坐标
	if (board[x][y]=='0')         //判断此处是否有雷
	{
	  board[x][y]='1';       //把字符1作为雷置入空坐标
	  COUNT--;
	}
  }
}

4.计算坐标周围雷个数函数,返回雷的个数

int GetMineCount (char Arr[ROWS][COLS],int x,int y)
{
	    return (Arr[x+1][y]+Arr[x+1][y+1]+
		Arr[x+1][y-1]+Arr[x-1][y]+Arr[x-1][y+1]+
		Arr[x-1][y-1]+Arr[x][y-1]+Arr[x][y+1]-8*'0');     //返回雷个数
}

5.排雷函数 (包含第一步不被炸死)

void FindMine (char ArrBoard[ROWS][COLS],char ShowBoard[ROWS][COLS],int row,int col,int COUNT)
{
	int x=0;
	int y=0;
	int win=0;
	int count=0;
	int p=1;
	while (win<row*col-COUNT)     //判断是否排完雷
	{  
	  printf ("请重新输入坐标: ");    //玩家输入坐标
	  scanf ("%d%d",&x,&y);
	  if (x>=1 && x<=row && y>=1 && y<=col)      //判断坐标是否合理
	  {
	   if (ArrBoard[x][y]=='1')          //判断是否遇到雷
	   {   
		   if (p==1)                           //判断是否是第一次输入坐标遇雷
		   { 
			    p++;
			    ArrBoard[x][y]='0';            //把雷移走
				SetMine(ArrBoard, row, col,1);      //重新布1颗雷
		        count=GetMineCount(ArrBoard,x,y);      //计算坐标周围雷个数
		        ShowBoard[x][y]=count+'0';             //把雷个数放入向玩家展示数组的坐标中
			    DisplayBoard (ShowBoard,row,col);     //打印游戏界面
			  // DisplayBoard (ArrBoard,row,col);         //打印布雷界面,方便测试

		   }
		   else
		   {
		   printf ("游戏失败\n");                      //不是第一次输入坐标遇到雷,则提示游戏失败
		   DisplayBoard  (ArrBoard,row,col);     //打印布雷界面,让玩家知道为何游戏失败
		   break;
		   }
	   }
	   else
	   {                                             //输入坐标无雷
		  p++;
	     count=GetMineCount(ArrBoard,x,y);      
		 ShowBoard[x][y]=count+'0';
		 DisplayBoard (ShowBoard,row,col);        //打印游戏游戏界面
		 win++;
	   }
	  }
	  else                                  //坐标不合理
       {
		   printf ("坐标错误,请重新输\n");   //则提示重新输入坐标
		  
	   }
	}
	if(win==row*col-COUNT)     //判断雷排完
	{
	  printf ("恭喜你成功\n");             //则提示游戏成功
	  DisplayBoard (ArrBoard,ROW,COL);    //打印布雷数组,使玩家知道有布雷界面
	
	}
}

游戏运行界面:
a.高等难度成功游戏界面:(把雷调成row*col-1个,方便测试)
在这里插入图片描述
此图片表明第一次输入坐标遇到雷时不死
在这里插入图片描述

b.简单游戏失败界面:(玩家玩时游戏界面)
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值