用C语言编写扫雷游戏

本文是一个C语言编写的扫雷游戏程序,包括了游戏的布局、初始化、打印棋盘、布置雷和排查雷的函数。使用二维数组来表示棋盘,通过递归函数进行安全区域的扩展。玩家可以选择玩游戏或退出,游戏过程中会根据用户输入坐标进行排查,如果踩到雷则游戏结束,否则显示周围雷的数量或继续扩展安全区。
摘要由CSDN通过智能技术生成

C语言知识点笔记6

此笔记是我考研备考专业课期间听课的一些C语言知识点混记,可能会有一点乱,有需要的朋友们可以翻阅一下,有利于巩固C语言知识点!

扫雷游戏:
(1)test.c - 扫雷游戏的测试
(2)game.c - 游戏的函数的实现
(3)game.h - 游戏的函数的声明

思路:用到二维数组:1、布置雷 2、排查雷
布置雷时:写两个数组:1个数组存放布置好的雷的信息;1个数组存放排查出的雷的信息
排查雷时:如果想实现99的棋盘,数组的大小设计成1111的比较好

test.c

#include "game.h"

//打印菜单
void menu()
{
     printf("******************\n");   
     printf("****  1.paly  ****\n");   
     printf("****  0.exit  ****\n");   
     printf("******************\n");   
}

void game()
{
     char mine[ROWS][COLS] = {0};//存放布置好的雷的信息
     char show[ROWS][COLS] = {0};//存放排查出的雷的信息

     //初始化棋盘
     InitBoard(mine, ROWS, COLS, '0');//初始化为‘0’
     InitBoard(show, ROWS, COLS, '*');//初始化为‘*’

     //打印一下棋盘
     DisplayBoard(show, ROW, COL);

     //布置雷
     SetMine(mine, ROW, COL);

     //排查雷
     FindMine(mine, show, ROW, COL);
}
  
int main()
{
     int input = 0;
     srand((unsigned int)time(NULL));
     do
     {
          menu();
          printf("请选择:>");
          scanf("%d", &input);
          switch(input)
          {
          case 1:
              game();//扫雷游戏
              break;
          case 0:
              printf("退出游戏\n");
              break;
          default:
              printf("选择错误,请重新选择\n");
              break;
          }
     }while (input);
     return 0;
}

game.h:

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

//定义雷的个数
#define EASY_COUNT 10

#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 mine[ROWS][COLS], int row, int col);
//排查雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
//递归函数
void ExpandBoard(char mine[ROWS][COLS], char  show[ROWS][COLS],int x, int y,int *win);

game.c:

#include "game.h"

//初始化棋盘
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)
{
     //布置10个雷
     int count = EASY_COUNT;
     while (count)
     {
          //产生随机的下标
          int x = rand() % row + 1;//除以9的余数范围为0到8
          int y = rand() % col + 1;//再加上1范围变为1到9
          if(mine[x][y] == '0' )
          {
              mine[x][y] = '1';
              count--;
          }
     }
}


//static:
//1.修饰局部变量
//2.修饰全局变量
//3.修饰函数

//计算周围雷的个数
static 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)
{
     //1.输入排查的坐标
     //2.检查坐标处是不是雷
          //(1)是雷   - 很遗憾炸死了 - 游戏结束
          //(2)不是雷 - 统计坐标周围有几个雷 - 存储排查到雷的信息到show数组,游戏继续
     int x = 0;
     int y = 0;
     int win = 0;//排除的非雷格子数
     while (win < row * col - EASY_COUNT)
     {
          printf("请输入要排查的坐标:>");//输入排查的坐标
          scanf("%d%d", &x, &y);//x、y属于1到9
          //判断坐标的合法性
          if(x >= 1 && x <= row && y >= 1 && y <= col)
          {
              //判断是否为雷
              if(mine[x][y] == '1')
              {
                   printf("很遗憾,你被炸死了\n");//是雷
                   DisplayBoard(mine, row, col);//打印棋盘信息
                   break;
              }

              else//不是雷
              {
                   win++;
                   ExpandBoard(mine,show,x,y,&win);
                   DisplayBoard(show, ROW, COL);//打印棋盘
              }
          }
          else
          {
              printf("坐标不合法,请重新输入\n");
          }
     }

     if(win == row * col - EASY_COUNT)
     {
          printf("恭喜你,排雷成功!\n");
          DisplayBoard(mine, row, col);//打印棋盘信息
     }
}


//传统的扫雷游戏中,当你点击一个坐标,若该坐标没有雷,则会展开该坐标周围所有的安全区域,直到周围有雷的坐标,上述过程可由递归实现。
//1.若该坐标周围八个坐标没有雷,则赋值为空格。之后,判断周围八个坐标的周围是否有雷,周围没有雷的坐标同样赋值为空格,周围没有雷的坐标则继续向外展开,
//直到遇到周围有雷的坐标或达到了扫雷盘面的边缘,则停止递归。
//2.若该坐标八个坐标有雷,则直接赋值为周围雷的个数。
void ExpandBoard(char mine[ROWS][COLS], char show[ROWS][COLS],int x, int y,int *win)
{
     int count = get_mine_count(mine, x, y);
     if (count == 0)
     {
          show[x][y] = ' ';//没有雷的坐标赋值为空格
          (*win)++;
          //递归周围的八个格子
          if (show[x - 1][y - 1] == '*' && x - 1 > 0 && x  - 1 < ROWS && y - 1 > 0 && y - 1 < COLS)
              ExpandBoard(mine, show, x - 1, y - 1,win);
          if (show[x - 1][y] == '*' && x - 1 > 0 && x - 1  < ROWS && y > 0 && y < COLS)
              ExpandBoard(mine, show, x - 1, y,win);
          if (show[x - 1][y + 1] == '*' && x - 1 > 0 && x  - 1 < ROWS && y + 1 > 0 && y + 1 < COLS)
              ExpandBoard(mine, show, x - 1, y + 1,win);
          if (show[x][y - 1] == '*' && x > 0 && x < ROWS  && y - 1 > 0 && y - 1 < COLS)
              ExpandBoard(mine, show, x, y - 1,win);
          if (show[x][y + 1] == '*' && x > 0 && x < ROWS  && y + 1 > 0 && y + 1 < COLS)
              ExpandBoard(mine, show, x, y + 1,win);
          if (show[x + 1][y - 1] == '*' && x + 1 > 0 && x  + 1 < ROWS && y - 1 > 0 && y - 1 < COLS)
              ExpandBoard(mine, show, x + 1, y - 1,win);
          if (show[x + 1][y] == '*' && x + 1 > 0 && x + 1  < ROWS && y > 0 && y < COLS)
              ExpandBoard(mine, show, x + 1, y,win);
          if (show[x + 1][y + 1] == '*' && x + 1 > 0 && x  + 1 < ROWS && y + 1 > 0 && y + 1 < COLS)
              ExpandBoard(mine, show, x + 1, y + 1,win);
     }
     else
     {
          show[x][y] = count + '0';
     }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值