欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

用C语言实现扫雷

程序员文章站 2024-03-18 17:49:40
...

扫雷小游戏大家应该都玩过,今天,我要用C语言来实现这个游戏。
那么,如何完成扫雷小游戏?我之前写过一个三子棋的代码,扫雷的完成中很多函数都可以模仿我们三子棋的函数。

首先,需要顺一下扫雷的思路:

  1. 需要一个菜单,让玩家选择开始游戏或者退出游戏
  2. 初始化数组
  3. 打印棋盘
  4. 设置雷
  5. 玩家扫雷

有一些细节我们需要注意:需要两个棋盘,一个是展现给玩家的,一个是让电脑生成雷的,在坐标周围没雷的时候可以实现展开,让玩家第一次不踩雷。

有了思路,就可以上手了。

game.h中的函数声明

#define _CRT_SECURE_NO_WARNINGS

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

#define ROW 9
#define COL 9

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

#define mine 10

void menu();
void InitBoard(char board[ROWS][COLS], int rows, int cols, char put);
void DisplayBoard(char board[ROWS][COLS], int row, int col);
void SetMine(char save[ROWS][COLS], int row, int col);
void PlayerMove(char save[ROWS][COLS], char show[ROWS][COLS], int row, int col);

game.c实现函数

#include"game.h"
void menu(){
 printf("////////////////////////////\n");
 printf("///1.开始游戏  0.退出游戏///\n");
 printf("////////////////////////////\n");
}

//初始化棋盘
void InitBoard(char board[ROWS][COLS], int rows, int cols, char put){
 int i = 0;
 int j = 0;
 for (i = 0; i < rows; i++){
  for (j = 0; j < cols; j++)
   board[i][j] = put;
 }
}

//打印棋盘
void DisplayBoard(char board[ROWS][COLS], int row, int col){
 int i = 0;
 int j = 0;
 for (i = 0; i <= row; 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 save[ROWS][COLS], int row, int col){
 int i = 0;
 int j = 0;
 int count = mine;
 while (count){
  i = rand() % 9 + 1;//randmax  32767
  j = rand() % 9 + 1;
  if (save[i][j] == '0'){
   save[i][j] = '1';
   count--;
  }
 }
}

//检测雷的个数
int AllMine(char save[ROWS][COLS],int x,int y){
 return save[x - 1][y] + save[x - 1][y - 1] + save[x - 1][y + 1] + save[x][y - 1] +
  save[x][y + 1] + save[x + 1][y] + save[x + 1][y + 1] + save[x + 1][y - 1]-8*'0';
}

//实现展开周边非雷部分
void Open(char save[ROWS][COLS],char show[ROWS][COLS],int row,int col,int x,int y){
 int ret = 0;
 ret = AllMine(save, x, y);
 if (ret == 0){
  show[x][y] = ' ';
  if (x - 1 > 0 && y - 1 > 0 && show[x - 1][y - 1] == '*'){
   Open(save, show, row, col, x-1, y-1);
  }
  if (x > 0 && y - 1 > 0 && show[x][y - 1] == '*'){
   Open(save, show, row, col, x, y - 1);
  }
  if (x + 1 > 0 && y - 1 > 0 && show[x + 1][y - 1] == '*'){
   Open(save, show, row, col, x + 1, y - 1);
  }
  if (x + 1 > 0 && y > 0 && show[x + 1][y] == '*'){
   Open(save, show, row, col, x + 1, y);
  }
  if (x + 1 > 0 && y + 1 > 0 && show[x + 1][y + 1] == '*'){
   Open(save, show, row, col, x + 1, y + 1);
  }
  if (x > 0 && y + 1 > 0 && show[x][y + 1] == '*'){
   Open(save, show, row, col, x, y + 1);
  }
  if (x - 1 > 0 && y + 1 > 0 && show[x - 1][y + 1] == '*'){
   Open(save, show, row, col, x - 1, y + 1);
  }
  if (x - 1 > 0 && y > 0 && show[x - 1][y] == '*'){
   Open(save, show, row, col, x - 1, y);
  }
 }
 else{
  show[x][y] = AllMine(save, x, y) + '0';
 }
}
//第一次不踩雷
void FirstMove(char save[ROWS][COLS],int x, int y)
{
 if (save[x][y] == '1')
 {
  save[x][y] = '0';
  while (1){
   x= rand() % 9 + 1;
   y = rand() % 9 + 1;
   if (save[x][y] != '0')
   {
    save[x][y] = '0';
    break;
   }
  }
 }
}

//玩家扫雷 
void PlayerMove(char save[ROWS][COLS], char show[ROWS][COLS], int row, int col){
 int i = 0;
 int j = 0;//判断坐标是否合法
 int n = 0;
 int m = 0;
 while (m<ROW * COL - mine){
  printf("输入一个坐标:");
  scanf("%d%d", &i, &j);
    if ((i <= row) && (i > 0) && (j <= col) && (j > 0)){
   if (save[i][j] == '1'){
    if (m == 0)
     FirstMove(save, i, j);
    else{
     printf("踩到雷啦!游戏结束!\n");
     DisplayBoard(save, ROW, COL);
     break;
    }
  }
 else{
    n = AllMine(save, i, j);
    show[i][j] = n + '0';
    Open(save, show, row, col, i, j);
    DisplayBoard(show, ROW, COL);
    m++;
   }
  }
  else
   printf("坐标非法!请重新输入!\n");
 }
 if (m >= ROW*COL - mine){
  printf("你真厉害!成功排掉了所有的雷!\n");
  DisplayBoard(save, ROW, COL);
 }
}

在test.c中使用

#include"game.h"
void game(){
 char save[ROWS][COLS] = { 0 };
 char show[ROWS][COLS] = { 0 };
 
 InitBoard(save, ROWS, COLS, '0');
 InitBoard(show, ROWS, COLS, '*');
 
 SetMine(save, ROW, COL);
 DisplayBoard(show, ROW, COL);
 PlayerMove(save, show, ROW, COL);
}

int main(){
 int n = 0;
 srand((unsigned int)time(NULL));
 do{
  menu();
  printf("输入你的选择:");
  scanf("%d", &n);
  switch (n){
  case 1:
   game();
   break;
  case 0:
   printf("退出游戏!");
   break;
  default:
   printf("非法输入,请重新选择!\n");
   break;
  }
 } while (n);
 system("pause");
 return 0;
}

总的来说,扫雷相比较三子棋还是难了一些,如果大家发现有什么问题,帮忙在评论区提醒我一下<.<

相关标签: C语言 扫雷