c语言扫雷程序

用c语言实现一个扫雷程序,有挑战性的主要有两部分内容:游戏的逻辑,空白区域的炸开算法
 1.游戏核心逻辑
观察Windwos的扫雷游戏,可以知道,一个格子有两种类型的状态需要描述,一种类型是这个格子是否有雷,另外一种状态是格子的绘制状态,这个类型就多了,格子上可能显示未知,数字,空白,旗帜,疑问,雷,一共是6种类型。
2.空白区域炸开算法
关于空白区域的炸开,至于炸到什么程度为止,通过观察Windows的扫雷游戏,我们也可以知道,要炸到这个格子显示数字为止,对此可以使用递归算法求解问题。


3.代码实现

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

enum gridState {UNKNOWN,NUMBER,BLANK,FLAG,DOUBT,MINE};
enum mineState {NOMINE, HASMINE };

typedef struct Table_{
    int rows;
    int columns;
    int digNum;
    int mineNum;
    double	timePassed;
    int**	mines;
    int**	state;
}GameTable;

char scanf_char();
int  choisirNombreAleatoire(int Max);
int** AllouerMatrice(int n, int p);
int  LibererMatrice(int **tab, int n);
int  InitialiserMatrice(int **tab, int n, int p, int valeur);
void initGame(GameTable* tab);
int  runGame(GameTable* tab);
void printGame(GameTable* tab);
void deleteGame(GameTable* tab);
void initMines(int** tab, int n, int p, int mineNum);
int  getMines(GameTable* tab , int r, int c);
void blank(GameTable* tab, int r, int c);
int  changeState(GameTable* tab, int r, int c, int flag);
void printMine(GameTable* tab);

int main() {
  //init the rows, columns, mines
    srand(time(NULL));
    GameTable tabs;
    initGame(&tabs);

  //run game
  int flag = 1;
  while (flag) {
    flag = runGame(&tabs);
  }
  if (tabs.digNum == tabs.mineNum)
    printf("you win the game\n");
  else
    printf("you lost the game\n");
  //free memory
  deleteGame(&tabs);

  return 0;
}

//==========================================================================================
void initGame(GameTable* tab)
{
    printf("please input the rows ,columns, and mines you want to set\n");
    scanf("%d%d%d", &tab->rows, &tab->columns, &tab->mineNum);
    tab->digNum = 0;
    tab->mines = AllouerMatrice(tab->rows, tab->columns);
    tab->state = AllouerMatrice(tab->rows, tab->columns);
    InitialiserMatrice(tab->mines, tab->rows, tab->columns, NOMINE);
    InitialiserMatrice(tab->state, tab->rows, tab->columns, UNKNOWN);
    initMines(tab->mines, tab->rows, tab->columns, tab->mineNum);
    printGame(tab);
    printMine(tab);
  setbuf(stdin, NULL);

}
int runGame(GameTable* tab)
{
  int r = -1;
  int c = -1;
  char cmd;
  while (r < 0 || r > tab->rows - 1 || c < 0 || c > tab->columns - 1 || !(cmd == 'n' || cmd == 'y'))
  {
    printf("input the coordinate, cmd:(y, n)");
    scanf("%d %d %c", &r, &c, &cmd);
  }
  int flag = 1;
  if (cmd == 'y')
  {
    if (tab->state[r][c] == FLAG)
      tab->state[r][c] = DOUBT;
    else if (tab->state[r][c] == UNKNOWN)
    {
      tab->state[r][c] = FLAG;
      if (tab->mines[r][c] == HASMINE)
      {
          tab->digNum++;
          if(tab->digNum == tab->mineNum)
              return 0;
      }
    }
  }
  else if (cmd == 'n')
  {
      if (tab->mines[r][c] == HASMINE)
        flag = 0;
      blank(tab, r, c);
  }
  setbuf(stdin, NULL);
  printGame(tab);
  return flag;

}
void printGame(GameTable* tab)
{
  //unknown **, number 11, blank __, flag pp, doubt ??, mine XX
  /*
  -------
  |__|NN|__|!!|
  |__|__|__|XX|
  |__|YY|__|!!|
  |__|__|__|XX|
  */
  int i = 0;
  int j = 0;
  for (i = 0; i < tab->rows; i++)
  {
    for (j = 0; j < tab->columns; j++)
    {
      printf("|");
      switch (tab->state[i][j])
      {
        case UNKNOWN:
          printf("**");
              break;
        case NUMBER:
          printf("%2d",getMines(tab,i,j));
              break;
        case BLANK:
          printf("__");
              break;
        case FLAG:
          printf("PP");
              break;
        case DOUBT:
          printf("??");
              break;
        case MINE:
          printf("XX");
      }
    }
    printf("|\n");
  }
  //printf("|" );
}
void deleteGame(GameTable* tab)
{
  LibererMatrice(tab->mines, tab->rows);
  LibererMatrice(tab->state, tab->rows);
}
void initMines(int** tab, int n, int p, int mineNum)
{
  if (mineNum > n * p || mineNum < 1)
    exit(0);
  int cnt = 0;
  while (cnt < mineNum)
  {
    int r = choisirNombreAleatoire(n-1);
    int c = choisirNombreAleatoire(p-1);
    if (tab[r][c] == NOMINE)
    {
      tab[r][c] = HASMINE;
      cnt++;
    }
  }
}

int  getMines(GameTable* tab, int r, int c)
{
  int cnt = 0;
  for (int i = -1; i <= 1; i++)
  {
    for (int j = -1; j <= 1; j++)
    {
      int rr = r + i;
      int cc = c + j;
      if (rr >= 0 && rr < tab->rows && cc >= 0 && cc < tab->columns && !(rr == r && cc == c))
      {
        if (tab->mines[rr][cc] == HASMINE)
          cnt++;
      }
    }
  }
  return cnt;
}
void blank(GameTable* tab, int r, int c)
{
  if (r < 0 || r >= tab->rows || c < 0 || c >= tab->columns)
    return;
  if ((tab->state[r][c] == UNKNOWN || tab->state[r][c] == DOUBT ) && tab->mines[r][c] == NOMINE)
  {
    if (getMines(tab, r, c) > 0 )
    {
      tab->state[r][c] = NUMBER;
    }
    else
    {
      tab->state[r][c] = BLANK;
      blank(tab, r - 1, c - 1);
      blank(tab, r - 1, c);
      blank(tab, r - 1, c + 1);
      blank(tab, r + 1, c - 1);
      blank(tab, r + 1, c);
      blank(tab, r + 1, c + 1);
      blank(tab, r, c + 1);
      blank(tab, r, c - 1);
    }
  }
  return;
}
int  changeState(GameTable* tab, int r, int c, int flag)
{
  return 0;
}

void printMine(GameTable* tab)
{
    int i = 0;
    int j = 0;
    printf("the mins position\n");
    for (i = 0; i < tab->rows; i++)
    {
        for (j = 0; j < tab->columns; j++)
        {
            printf("|");
            switch (tab->mines[i][j])
            {
                case HASMINE:
                    printf("**");
                    break;
                case NOMINE:
                    printf("__");
                    break;
            }
        }
        printf("|\n");
    }
}
//==========================================================================================
char scanf_char()
{
  char A = 0;
  char chaine[2] = { 'A','\n' };
  scanf("%s", chaine);
  A = chaine[0];
  return A;
}

int choisirNombreAleatoire(int Max)
{
  return (rand() % (Max + 1));
}

int** AllouerMatrice(int n, int p)
/* allocation d’un tableau de n lignes et p colonnes*/
{
  int i = 0;
  int **tab = (int**)malloc(n * sizeof(int*));
  if (tab == NULL)
  {
    exit(0);
  }
  for (i = 0; i<n; i++)
  {
    tab[i] = (int*)malloc(p * sizeof(int));
  }
  return tab;
}
int LibererMatrice(int **tab, int n)
/* liberation d’un tableau de n lignes*/
{
  int i = 0;
  for (i = 0; i<n; i++)
  {
    free(tab[i]);
  }
  free(tab);
  return 0;
}
int InitialiserMatrice(int **tab, int n, int p, int valeur)
/* initialisation de toutes les cases d’un tableau de n lignes et p
colonnes à la valeurs ? valeur ? */
{
  int i = 0, j = 0;
  for (i = 0; i<n; i++)
  {
    for (j = 0; j<p; j++)
    {
      tab[i][j] = valeur;
    }
  }
  return 0;
}

4 结果

please input the rows ,columns, and mines you want to set

9 9 10

9 9 10

|**|**|**|**|**|**|**|**|**|

|**|**|**|**|**|**|**|**|**|

|**|**|**|**|**|**|**|**|**|

|**|**|**|**|**|**|**|**|**|

|**|**|**|**|**|**|**|**|**|

|**|**|**|**|**|**|**|**|**|

|**|**|**|**|**|**|**|**|**|

|**|**|**|**|**|**|**|**|**|

|**|**|**|**|**|**|**|**|**|

the mins position

|**|__|**|__|__|__|__|__|__|

|__|__|__|__|__|__|__|__|__|

|__|__|__|__|__|__|__|__|__|

|__|__|__|__|__|__|__|__|__|

|__|__|__|__|__|__|__|__|__|

|**|__|__|__|__|__|**|__|**|

|__|__|__|__|__|__|__|__|__|

|**|__|__|__|__|__|__|__|**|

|**|__|**|__|__|__|__|__|**|

input the coordinate, cmd:(y, n)4 4 n

4 4 n

|**|**|**| 1|__|__|__|__|__|

| 1| 2| 1| 1|__|__|__|__|__|

|__|__|__|__|__|__|__|__|__|

|__|__|__|__|__|__|__|__|__|

| 1| 1|__|__|__| 1| 1| 2| 1|

|**| 1|__|__|__| 1|**|**|**|

|**| 2|__|__|__| 1| 1| 3|**|

|**| 3| 1| 1|__|__|__| 2|**|

|**|**|**| 1|__|__|__| 2|**|

input the coordinate, cmd:(y, n)0 0 y

0 0 y

|PP|**|**| 1|__|__|__|__|__|

| 1| 2| 1| 1|__|__|__|__|__|

|__|__|__|__|__|__|__|__|__|

|__|__|__|__|__|__|__|__|__|

| 1| 1|__|__|__| 1| 1| 2| 1|

|**| 1|__|__|__| 1|**|**|**|

|**| 2|__|__|__| 1| 1| 3|**|

|**| 3| 1| 1|__|__|__| 2|**|

|**|**|**| 1|__|__|__| 2|**|

input the coordinate, cmd:(y, n)0 2 y

0 2 y

|PP|**|PP| 1|__|__|__|__|__|

| 1| 2| 1| 1|__|__|__|__|__|

|__|__|__|__|__|__|__|__|__|

|__|__|__|__|__|__|__|__|__|

| 1| 1|__|__|__| 1| 1| 2| 1|

|**| 1|__|__|__| 1|**|**|**|

|**| 2|__|__|__| 1| 1| 3|**|

|**| 3| 1| 1|__|__|__| 2|**|

|**|**|**| 1|__|__|__| 2|**|

input the coordinate, cmd:(y, n)5 0 y

5 0 y

|PP|**|PP| 1|__|__|__|__|__|

| 1| 2| 1| 1|__|__|__|__|__|

|__|__|__|__|__|__|__|__|__|

|__|__|__|__|__|__|__|__|__|

| 1| 1|__|__|__| 1| 1| 2| 1|

|PP| 1|__|__|__| 1|**|**|**|

|**| 2|__|__|__| 1| 1| 3|**|

|**| 3| 1| 1|__|__|__| 2|**|

|**|**|**| 1|__|__|__| 2|**|

input the coordinate, cmd:(y, n)5 6 y

5 6 y

|PP|**|PP| 1|__|__|__|__|__|

| 1| 2| 1| 1|__|__|__|__|__|

|__|__|__|__|__|__|__|__|__|

|__|__|__|__|__|__|__|__|__|

| 1| 1|__|__|__| 1| 1| 2| 1|

|PP| 1|__|__|__| 1|PP|**|**|

|**| 2|__|__|__| 1| 1| 3|**|

|**| 3| 1| 1|__|__|__| 2|**|

|**|**|**| 1|__|__|__| 2|**|

input the coordinate, cmd:(y, n)5 8 y

5 8 y

|PP|**|PP| 1|__|__|__|__|__|

| 1| 2| 1| 1|__|__|__|__|__|

|__|__|__|__|__|__|__|__|__|

|__|__|__|__|__|__|__|__|__|

| 1| 1|__|__|__| 1| 1| 2| 1|

|PP| 1|__|__|__| 1|PP|**|PP|

|**| 2|__|__|__| 1| 1| 3|**|

|**| 3| 1| 1|__|__|__| 2|**|

|**|**|**| 1|__|__|__| 2|**|

input the coordinate, cmd:(y, n)7 0 y

7 0 y

|PP|**|PP| 1|__|__|__|__|__|

| 1| 2| 1| 1|__|__|__|__|__|

|__|__|__|__|__|__|__|__|__|

|__|__|__|__|__|__|__|__|__|

| 1| 1|__|__|__| 1| 1| 2| 1|

|PP| 1|__|__|__| 1|PP|**|PP|

|**| 2|__|__|__| 1| 1| 3|**|

|PP| 3| 1| 1|__|__|__| 2|**|

|**|**|**| 1|__|__|__| 2|**|

input the coordinate, cmd:(y, n) 7 8 y

 7 8 y

|PP|**|PP| 1|__|__|__|__|__|

| 1| 2| 1| 1|__|__|__|__|__|

|__|__|__|__|__|__|__|__|__|

|__|__|__|__|__|__|__|__|__|

| 1| 1|__|__|__| 1| 1| 2| 1|

|PP| 1|__|__|__| 1|PP|**|PP|

|**| 2|__|__|__| 1| 1| 3|**|

|PP| 3| 1| 1|__|__|__| 2|PP|

|**|**|**| 1|__|__|__| 2|**|

input the coordinate, cmd:(y, n)8 0 y

8 0 y

|PP|**|PP| 1|__|__|__|__|__|

| 1| 2| 1| 1|__|__|__|__|__|

|__|__|__|__|__|__|__|__|__|

|__|__|__|__|__|__|__|__|__|

| 1| 1|__|__|__| 1| 1| 2| 1|

|PP| 1|__|__|__| 1|PP|**|PP|

|**| 2|__|__|__| 1| 1| 3|**|

|PP| 3| 1| 1|__|__|__| 2|PP|

|PP|**|**| 1|__|__|__| 2|**|

input the coordinate, cmd:(y, n)8 2 y

8 2 y

|PP|**|PP| 1|__|__|__|__|__|

| 1| 2| 1| 1|__|__|__|__|__|

|__|__|__|__|__|__|__|__|__|

|__|__|__|__|__|__|__|__|__|

| 1| 1|__|__|__| 1| 1| 2| 1|

|PP| 1|__|__|__| 1|PP|**|PP|

|**| 2|__|__|__| 1| 1| 3|**|

|PP| 3| 1| 1|__|__|__| 2|PP|

|PP|**|PP| 1|__|__|__| 2|**|

input the coordinate, cmd:(y, n)8  8 y

8  8 y

you win the game

Process finished with exit code 0

Process finished with exit code 0

点赞