简易扫雷小游戏。

论坛 期权论坛 脚本     
匿名技术用户   2020-12-30 21:06   29   0

今天将给大家讲解如何使用C语言多文件编程实现扫雷小游戏,这个扫雷游戏有如下几个主要功能:

  1. 显示该点周围雷的个数
  2. 第一次下子,不炸死
  3. 坐标周围没雷,可以实现展开

我们只要输入坐标就可以扫雷了。

其实要想实现这也不难,我们要用几个算法模块来模拟游戏规则,需要用函数来调用各个模块使游戏跑起来,那么第一步我们就要构思一个棋盘,在开始游戏的界面可以打印两个棋盘,有0和1的棋盘是给我们设计者看的,它可以显示出当前雷的真实分布,这有利于我们测试代码的正确性,而全是 * 的棋盘是给玩家扫雷用的。那我们就需要用二维数组来打印两个棋盘,假如我们要打印9X9的棋盘,那我们的二维数组元素也要为9X9个吗?不能,因为我们在设计算法时需要统计坐标周围8个方位雷X的个数,假如要统计边界坐标周围雷的个数,那么就会有数组越界的问题,那我们就要在9X9的边界多上一圈元素,也就要定义11X11的数组元素,这些元素我们不要打印出来,心里有数就行。

代码如下:

1.game.h

#ifndef _GAME_H_
#define _GAME_H_

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

#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2

#define EASY_COUNT 11
#define HARD_COUNT 61

void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);
void PrintBoard(char board[ROWS][COLS], int row, int col);
void SetMine(char board[ROWS][COLS], int row, int col);
void ClearMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
int GetMineCount(char board[ROWS][COLS], int x, int y);
void OpenMine(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y);
int CountShowMine(char board[ROWS][COLS]);
void SafeMine(char mine[ROWS][COLS], char show[ROWS][COLS]);

#endif// _GAME_H_

2.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 PrintBoard(char board[ROWS][COLS], int row, int col)
{
 int i = 0;
 int j = 0;

 for (i = 0; i <= col; i++)
 {
  printf("%d ", i);
  if (i == col)
   printf("\n");
 }

 for (i = 1; i <= row; i++)
 {
  printf("%d ", i);
  for (j = 1; j <= col; j++)
  {
   printf("%c ", board[i][j]);

  }
  printf("\n");
 }
}

void SetMine(char board[ROWS][COLS], int row, int col)
{
 int count = HARD_COUNT;
 while (count)
 {
  int x = rand() % 9 + 1;
  int y = rand() % 9 + 1;
  if (board[x][y] == '0')
  {
   board[x][y] = '1';
   count--;
  }
 }
}

int GetMineCount(char board[ROWS][COLS], int x, int y)
{
 return 
  board[x - 1][y] +
  board[x - 1][y - 1] +
  board[x][y - 1] +
  board[x + 1][y - 1] +
  board[x + 1][y] +
  board[x + 1][y + 1] +
  board[x][y + 1] +
  board[x - 1][y + 1] - 8 * '0';
}

int CountShowMine(char board[ROWS][COLS])//判断剩余未知区域的个数,个数为雷数时玩家赢
{
 int aaa = 0;
 int i = 0;
 int j = 0;
 for (i = 1; i <= ROWS-2; i++)
 {
  for (j = 1; j <= COLS-2; j++)
  {
   if (board[i][j] == '*')
   {
    aaa++;
   }
  }

 }
 return aaa;
}

void ClearMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
 int x = 0;
 int y = 0;
 int aaa = 0;
 //while(win<(row*col-HARD_COUNT))
 while (HARD_COUNT != (CountShowMine(show)))
 {
  printf("\n");
  printf("请输入排查坐标: ");
  scanf_s("%d%d", &x, &y);
  printf("——————————\n");
  if (x >= 1 && x <= row && y >= 1 && y <= col)
  {
   if (mine[x][y] == '1')
   {
    printf("炸死了!\n");
    PrintBoard(mine, row, col);
    break;
    //return;
   }
   else
   {
    //tongjilei
    int count = GetMineCount(mine, x, y);
    show[x][y] = count + '0';
    OpenMine(mine, show, x, y);//展开 
    //win=win+OpenMine(mine,show,x,y)+'0'; 
    //int nume =OpenMine(mine,show,x,y);
    PrintBoard(mine, row, col);
    printf("\n");
    PrintBoard(show, row, col);
    //win= win+1+nume;
    //win++;
    if (HARD_COUNT == (CountShowMine(show)))
    {
     printf("恭喜您!排雷成功!\n");
     //OpenMine(mine,x,y);
     PrintBoard(mine, ROW, COL);
     printf("\n");
     PrintBoard(show, ROW, COL);
     break;
    }
   }
  }
  else
  {
   printf("坐标非法\n");

  }
 }
 //if(win ==row*col-HARD_COUNT)
/* if(count_show_mine(show) == HARD_COUNT)
 {
  printf("排雷成功!\n");
  //OpenMine(mine,x,y);
  PrintBoard(mine,row,col);
 }*/
 //return 0;
}

void  OpenMine(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{
 int n = 0;
 //int num=0;
 if (mine[x - 1][y - 1] == '0')
 {
  show[x - 1][y - 1] = GetMineCount(mine, x - 1, y - 1) + '0';//显示该坐标周围雷数
  //n++;
 }
 if (mine[x - 1][y] == '0')
 {
  show[x - 1][y] = GetMineCount(mine, x - 1, y) + '0';//显示该坐标周围雷数
    //n++;
 }
 if (mine[x - 1][y + 1] == '0')
 {
  show[x - 1][y + 1] = GetMineCount(mine, x - 1, y + 1) + '0';//显示该坐标周围雷数
  //n++;
 }
 if (mine[x][y - 1] == '0')
 {
  show[x][y - 1] = GetMineCount(mine, x, y - 1) + '0';//显示该坐标周围雷数
  //n++;
 }
 if (mine[x][y + 1] == '0')
 {
  show[x][y + 1] = GetMineCount(mine, x, y + 1) + '0';//显示该坐标周围雷数
  //n++;
 }
 if (mine[x + 1][y - 1] == '0')
 {
  show[x + 1][y - 1] = GetMineCount(mine, x + 1, y - 1) + '0';//显示该坐标周围雷数
  //n++
 }
 if (mine[x + 1][y] == '0')
 {
  show[x + 1][y] = GetMineCount(mine, x + 1, y) + '0';//显示该坐标周围雷数
  //n++;
 }
 if (mine[x + 1][y + 1] == '0')
 {
  show[x + 1][y + 1] = GetMineCount(mine, x + 1, y + 1) + '0';//显示该坐标周围雷数
  //++;
 }
 //num=n;
 //return n;
}

void SafeMine(char mine[ROWS][COLS], char show[ROWS][COLS])//避免第一次炸死
{
 int x = 0;
 int y = 0;
 char ch = 0;
 int count = 0;
 int ret = 1;
 printf("输入坐标扫雷:");
 while (1)
 {
  scanf_s("%d%d", &x, &y);//只能输入1到10,输入错误重新输入
  if ((x >= 1 && x <= 10) && (y >= 1 && y <= 10))//判断输入坐标是否有误
  {
   if (mine[x][y] == '1')//第一次踩到雷后补救
   {
    mine[x][y] = '0';
    int count = GetMineCount(mine, x, y);
    show[x][y] = count + '0';//数字对应的ASCII值和数字字符对应的ASCII值相差48,即'0'的ASCII值
    OpenMine(mine, show, x, y);
    while (ret)//在其余有空的地方设置一个雷
    {
     int x = rand() % 9 + 1;//产生1到10的随机数,在数组下标为1到10的范围内布雷
     int y = rand() % 9 + 1;//产生1到10的随机数,在数组下标为1到10的范围内布雷
     if (mine[x][y] == '0')//找不是雷的地方布雷
     {
      mine[x][y] = '1';
      ret--;
      break;
     }
    }break;//跳出此函数  
   }
   if (mine[x][y] == '0')
   {
    int count = GetMineCount(mine, x, y);
    show[x][y] = count + '0';//数字对应的ASCII值和数字字符对应的ASCII值相差48,即'0'的ASCII值
    OpenMine(mine, show, x, y);
    break;
   }
  }
  else//坐标错误
  {
   printf("输入错误重新输入\n");
  }
 }
}

3.test.c

#include "game.h"

void menu()
{
 printf("**************************\n");
 printf("**********1.play**********\n");
 printf("**********0.exit**********\n");
 printf("**************************\n");
}

void game()
{
 char mine[ROWS][COLS] = { 0 };//原始雷信息 
 char show[ROWS][COLS] = { 0 }; //展示信息 
 InitBoard(mine, ROWS, COLS, '0');
 InitBoard(show, ROWS, COLS, '*');//初始化 
 SetMine(mine, ROW, COL);//buzhi

 PrintBoard(mine, ROW, COL);
 printf("\n");
 PrintBoard(show, ROW, COL);//打印 
 
 SafeMine(mine, show);//pailei

 PrintBoard(mine, ROW, COL);
 printf("\n");
 PrintBoard(show, ROW, COL);

 ClearMine(mine, show, ROW, COL);
}

void test()
{
 int input = 0;
 srand((unsigned int)time(NULL));
 do
 {
  menu();
  printf("请选择:");
  scanf_s("%d", &input);
  printf("——————————\n");
  switch (input)
  {
  case 1:game();
   break;
  case 0:printf("退出游戏!\n");
   break;
  default:printf("选择错误!\n");
   break;
  }
 } while (input);
}

int main(int argc, char* argv[])
{
 test();
 return 0;
}

over~

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:7942463
帖子:1588486
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP