扫雷游戏进阶(递归实现扫雷展开)

简介: 笔记

用户选择菜单


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

用户按1进入游戏


棋盘初始化


void Itnboard(char board[ROWS][COLS], int rows, int cols,char c)
{
  int i, j;
  for (i = 0; i < rows; i++)
  {
  for (j = 0; j <cols; j++)
  {
    board[i][j] = c;
  }
  }
}

创建数组,并对其进行初始化


布置雷(随机布置)


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

用time函数产生随机值


打印棋盘


void Displayboard(char board[ROWS][COLS], int row, int col)
{
  int i, j;
  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");
  }
}


打印棋盘


玩家下棋


void Player(char board[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
  int x, y;
  int count = 0;
  while (1)
  {
  printf("请排雷:\n");
  scanf("%d %d", &x, &y);
  if (x >= 1 && x <= 9 && y >= 1 && y <= 9)
  {
    if (board[x][y] == '0')
    {
    Openboard(show, board, x, y);
    Displayboard(show, ROW, COL);
    }
    else if (board[x][y] == '1')
    {
    printf("你死了\n");
    break;
    }
  }
  else
  {
    printf("请重新输入");
  }
  int i, j;
  for (i = 1; i <= row; i++)
  {
    for (j = 1; j <= col; j++)
    {
    if (show[i][j] == '*')
    {
      count++;
    }
    }
  }
  if (count == Easy_count)
  {
    printf("成功\n");   //这里的判断条件是遍历整个数组,统计雷的个数,如果雷的个数等于所剩余未排的*,说明排雷成功
    break;
  }
  }
}


用户输入值,并进行判断,如果该位置没有雷,我们进入展开函数


棋盘展开


void Openboard(char show[ROWS][COLS], char board[ROWS][COLS], int row, int col)
{
  if (row >= 1 && row <= ROW && col >= 1 && col <= COL)
  {
  int count=sum(board, row, col);
  if (count != 0)
  {
    show[row][col] = count + '0';
  }
  else if (show[row][col] != '_')
  {
    show[row][col] = '_';
    int i = 0, j = 0;
    for (i = row - 1; i <= row + 1; i++)
    {
    for (j = col - 1; j <= col + 1; j++)
    {
      Openboard(show, board, i,j);
    }
    }
  }
  else
  {
    return;
  }
  }
}


如果用户输入的这个位置没有雷,我们对其周围8个位置进行判断是否有雷,若有雷,我们把雷的个数显示在该位置上,若其周围8个位置没有雷并且不是下划线,我们把这个位置赋值为下划线,然后并对其8个位置进行同样的判断,如果周围没雷,而且周围的棋子也不是下划线,我们对其进行返回。


展开部分思维导图


1.png


展开函数最后一个else return 作用

这里我们show棋盘有三种情况,1.该位置是*


                                                    2.该位置是下划线


                                                    3.该位置是雷的个数


else


   return;


这里是作用:如果是下划线,我们就返回上一层函数。因为如果这里不是下划线,我们会在else return 之前的语句中进行判断,并对其周围8个位置进行操作,然后再对这8个棋子各个周围8个位置进行判断并操作,如果这里是下划线,就说明由这个位置为中心的周围8个棋子已经判断过了,并且以这8个位置为中心,已经递归过了,我们不需要再进行判断,所以直接返回就行


周围雷个数判断  


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

test.c

#include"game.h"
void menu()
{
  printf("****************************\n");
  printf("********  1.play  **********\n");
  printf("********  0.exit  **********\n");
  printf("****************************\n");
}
void game()
{
  char board[ROWS][COLS] = { 0 };
  char show[ROWS][COLS] = { 0 };
  Itnboard(board, ROWS, COLS,'0');  //初始化棋盘
  Itnboard(show, ROWS, COLS, '*');
  Setboard(board, ROW, COL);   
  Displayboard(board, ROW, COL);
  Player(board, show, ROW, COL);            //玩家输入
}
int main()
{
  int input=1;
  srand((unsigned int)time(NULL));
  do{
    menu();
  scanf("%d", &input);
  switch (input)
  {
  case 1:
    game();
    break;
  case 0:
    break;
  default:
    printf("输入错误请重新输入:\n ");
  }
  } while (input);
}

game.c

#include"game.h"
void Itnboard(char board[ROWS][COLS], int rows, int cols,char c)
{
  int i, j;
  for (i = 0; i < rows; i++)
  {
    for (j = 0; j <cols; j++)
    {
      board[i][j] = c;
    }
  }
}
void Displayboard(char board[ROWS][COLS], int row, int col)
{
  int i, j;
  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");
  }
}
void Setboard(char board[ROWS][COLS], int row, int col)
{
  int count = Easy_count;
  while (count)
  {
    int x = rand() % row+1;
    int y = rand() % col+1;
    if (board[x][y] == '0')
    {
      board[x][y] = '1';
      count--;
    }
  }
}
int sum(char board[ROWS][COLS], int x, int y)
{
  return (board[x - 1][y - 1] +
    board[x - 1][y] +
    board[x - 1][y + 1] +
    board[x][y - 1] +
    board[x][y + 1] +
    board[x + 1][y - 1] +
    board[x + 1][y] +
    board[x + 1][y + 1] - 8 * '0');
}
void Player(char board[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
  int x, y;
  int count = 0;
  while (1)
  {
    printf("请排雷:\n");
    scanf("%d %d", &x, &y);
    if (x >= 1 && x <= 9 && y >= 1 && y <= 9)
    {
      if (board[x][y] == '0')
      {
        Openboard(show, board, x, y);
        Displayboard(show, ROW, COL);
      }
      else if (board[x][y] == '1')
      {
        printf("你死了\n");
        break;
      }
    }
    else
    {
      printf("请重新输入");
    }
    int i, j;
    for (i = 1; i <= row; i++)
    {
      for (j = 1; j <= col; j++)
      {
        if (show[i][j] == '*')
        {
          count++;
        }
      }
    }
    if (count == Easy_count)
    {
      printf("成功\n");
      break;
    }
  }
}
void Openboard(char show[ROWS][COLS], char board[ROWS][COLS], int row, int col)
{
  if (row >= 1 && row <= ROW && col >= 1 && col <= COL)
  {
    int count=sum(board, row, col);
    if (count != 0)
    {
      show[row][col] = count + '0';
    }
    else if (show[row][col] != '_')
    {
      show[row][col] = '_';
      int i = 0, j = 0;
      for (i = row - 1; i <= row + 1; i++)
      {
        for (j = col - 1; j <= col + 1; j++)
        {
          Openboard(show, board, i,j);
        }
      }
    }
    else
    {
      return;
    }
  }
}

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 10
void Itnboard(char board[ROWS][COLS], int rows, int cols,char c);
void Displayboard(char board[ROWS][COLS], int row, int col);
void Setboard(char board[ROWS][COLS], int row, int col);
void Player(char board[ROWS][COLS], char show[ROWS][COLS], int row, int col);
void Openboard(char show[ROWS][COLS], char board[ROWS][COLS], int row, int col);
相关文章
|
6天前
|
C语言
C语言之详解数组【附三子棋和扫雷游戏实战】(二)
C语言之详解数组【附三子棋和扫雷游戏实战】(二)
|
7月前
三子棋小游戏思路及代码实现的详解
三子棋小游戏思路及代码实现的详解
23 0
|
6天前
|
编译器 C语言
C语言之扫雷小游戏的实现【含递归展开】
C语言之扫雷小游戏的实现【含递归展开】
|
6天前
|
存储 编译器 C语言
C语言之详解数组【附三子棋和扫雷游戏实战】(一)
C语言之详解数组【附三子棋和扫雷游戏实战】(一)
|
6天前
leetcode-529:扫雷游戏
leetcode-529:扫雷游戏
23 0
|
9月前
|
C语言
C/关于扫雷小游戏的创建
C/关于扫雷小游戏的创建
|
7月前
|
C语言
|
9月前
|
C语言
扫雷小游戏 递归展开
扫雷小游戏 递归展开
|
9月前
|
C语言
经典游戏扫雷详解--你也可以写出扫雷和玩好扫雷(上)
经典游戏扫雷详解--你也可以写出扫雷和玩好扫雷(上)
107 0