C語言實現簡易的掃雷遊戲

本文實例為大傢分享瞭C語言實現簡易的掃雷遊戲的具體代碼,供大傢參考,具體內容如下

在正式講內容之前先說一說掃雷遊戲的規則

遊戲規則很簡單,點擊方格,如果是地雷,遊戲失敗,找到所有地雷遊戲勝利

.剛開始需要碰運氣,隻要點開一個區域,就可以正式開始瞭。

3.根據現有情況,判斷出一定有雷的位置。

4.進一步計算,因為“2”右邊的“1”已經有從屬的雷瞭,所以右邊的“2”的正下方沒有雷,因此可以判斷出左邊有兩顆雷,滿足兩個“2”。

5.紅圈表明的“1”已經有一顆確定的雷瞭,這時隻需要把鼠標放在“1”上,按住右鍵不放,再點一下左鍵,“1”周圍的其他方塊就全被點開瞭。這個小技巧對於提升速度非常有幫助。

6.左上角的“1”旁邊必須有一顆雷,可能在紅圈圈住的兩個塊中,目前還無法確定。但是不論在兩個中的哪一個,都從屬於“3”,因此“3”周圍已經有瞭三顆雷,“3”左下角的方塊可以確定沒有雷。

7.紅圈框住的位置肯定有一顆雷,因為“3”周圍必須有三顆雷。不論在兩個中的哪一個,都從屬於“3旁邊的“2”,這樣“2”就滿足兩顆雷的條件瞭。因此“2”左下角的塊是沒有雷的。

8.這樣一來,“3”下面的兩個塊可以確定都是有雷的。

9.把這些有雷的地方標出來,就打開瞭一片新天地。

10.再根據現有的條件把確定有雷的地方表明,點開其他的地方。這時我們發現剛才左上角遺留的問題解決瞭。

11.重復上面的各種方法,不斷推理出,最後就能完成掃雷

好瞭,規則已經講完瞭,現在來說一說怎麼實現的吧:

首先還是得創建三個文件夾,分別為game.c 遊戲需要的具體函數的實現 game.h (所要用的頭文件)test.c(遊戲的邏輯,菜單,以及函數順序調用)。

首先看一下test.c:

遊戲大概的邏輯就是佈置雷,把棋盤打印出來,然後玩傢自己掃雷,這部分代碼不是很難理解

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void game()
{
 char mine[ROWS][COLS] = { 0 };//存放佈置雷的信息 0無雷 1有雷
 char show[ROWS][COLS] = { 0 };//展示給用戶看並且存放排查出的雷的信息
 
 InitBoard(mine, ROWS, COLS, '0');
 InitBoard(show, ROWS, COLS, '*');
 
 //佈置雷
 SetMine(mine, ROW, COL);
 //打印棋盤
 //DisplayBoard(mine, ROW, COL);
 DisplayBoard(show, ROW, COL);
 //排雷
 FindMine(mine,show, ROW, COL);
}
//遊戲菜單界面
void menu()
{
 printf("************\n");
 printf("***1.開始***\n");
 printf("***0.退出***\n");
 printf("************\n");
}
//選擇玩或不玩
void test()
{
 int input = 0;   
 srand((unsigned int)time(NULL));
 do
 {
  menu();
  printf("請選擇->;");
  scanf_s("%d", &input);
  switch (input)
  {
  case 1:
   //掃雷
   game();
   break;
  case 0:
   printf("%d\n",input);
   printf("即將退出遊戲\n");
   break;
  default:
   printf("輸入錯誤,請重新輸入:\n");
   break;
  }
 } while (input);
}
int main(void)
{
 test();
 return 0;
}

接下來是game.h:

我將所使用到的函數和代碼段都寫入瞭代碼裡應該不難理解

#pragma once
#include<stdio.h>
#include<time.h>
#include<Windows.h>
 
#define ROW 9//打印出來的棋盤大小
#define COL 9//打印出來的棋盤大小
 
#define ROWS ROW+2//實際棋盤大小,為瞭防止越界
#define COLS COL+2//實際棋盤大小,為瞭防止越界
 
#define EASY_COUNT 10//簡單模式10個雷然後根據自己的需要調整大小
 
//初始化棋盤
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);
//打印棋盤
void DisplayBoard(char mine[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);

接下來是game.c:

掃雷遊戲有一個功能是,點開一個位置,如果周圍都沒有雷的話就會展開那一片,我們這裡用遞歸來實現:

//將棋盤展開的函數
void Open(char mine[ROWS][COLS], char show[ROWS][COLS],int x,int y)
{
 int n = get_mine_count(mine, x, y);
 if (n != 0)
 {
  show[x][y] = '0' + n;
 }
 else if (show[x][y] != ' ')
 {
  show[x][y] = ' ';
  int i = 0;
  for (i = x - 1; i <= x + 1; i++)
  {
   int j = 0;
   for (j = y - 1; j <= y + 1; j++)
   {
    Open(mine, show, i, j);
   }
  }
 }
 else
 {
  return;
 }
}

完整代碼:

#define _CRT_SECURE_NO_WARNINGS 1
#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;
 for (i = 0; i <= row; i++)
 {
  printf("%d|", i);
 }
 printf("\n");
 for (i = 0; i < 10; i++)
 {
  printf("-|");
 }
 printf("\n");
 for (i = 1; i <= row; i++)
 {
  printf("%d|", i );
  for (j = 1; j <= col; j++)
  {
   printf("%c|", board[i][j]);
  }
  printf("\n");
  for (j = 0; j <col+1; j++)
  {
   printf("-|");
 
  }
  printf("\n");
 }
}
void SetMine(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--;
  }
 }
}
static int get_mine_count(char mine[ROWS][COLS], int x, int y)
{
 return mine[x + 1][y] +
  mine[x - 1][y] +
  mine[x][y + 1] +
  mine[x][y - 1] +
  mine[x - 1][y - 1] +
  mine[x - 1][y + 1] +
  mine[x + 1][y - 1] +
  mine[x + 1][y + 1] -
  8 * '0';
}
//將棋盤展開的函數
void Open(char mine[ROWS][COLS], char show[ROWS][COLS],int x,int y)
{
 int n = get_mine_count(mine, x, y);
 if (n != 0)
 {
  show[x][y] = '0' + n;
 }
 else if (show[x][y] != ' ')
 {
  show[x][y] = ' ';
  int i = 0;
  for (i = x - 1; i <= x + 1; i++)
  {
   int j = 0;
   for (j = y - 1; j <= y + 1; j++)
   {
    Open(mine, show, i, j);
   }
  }
 }
 else
 {
  return;
 }
}
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
 int x = 0;
 int y = 0;
 while (1)
 {
  printf("請輸入你要查詢的坐標->");
  scanf("%d%d", &x, &y);
  Sleep(500);
  if (x >= 1 && x <= row && y >= 1 && y <= col)
  {
   if ('1' == mine[x][y])
   {
    printf("很遺憾,你無瞭\n");
    Sleep(500);
    DisplayBoard(mine, row, col);
    break;
   }
   else
   {
    //計算坐標x,y周圍有幾個雷
    Open(mine,show,x,y);
    DisplayBoard(show, row, col);
   }
  }
  else
  {
   printf("輸入坐標非法,無法排雷,請重新輸入\n");
  }
 
  int i = 0;
  int j = 1;
  int flag = 0;
  for (i = 1; i <= row; i++)
  {
   for (j = 1; j <= col; j++)
   {
    if (show[i][j] == '*')
    {
     flag++;
    }
   }
  }
  if (flag == EASY_COUNT)//棋盤全部展開後掃描玩傢找的雷的個數是否復合實際雷的個數
  {
   printf("恭喜你,你贏瞭!\n");
   DisplayBoard(mine, row, col);
   break;
  }
 }
 
 
}

以上就是本文的全部內容,希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。

推薦閱讀: