1. 程式人生 > 程式設計 >C語言掃雷遊戲的實現程式碼

C語言掃雷遊戲的實現程式碼

這是一個用C語言實現的控制檯掃雷小遊戲,實現了隨機佈置炸彈、掃描炸彈、標記炸彈、百分百第一次不被炸死等功能。

編譯器:vs2015

功能模組圖

C語言掃雷遊戲的實現程式碼

原始碼

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

void show(int cbd[10][10],int u[10][10])  //介面輸出函式
{
  int i,j;
  //for (i = 0; i < 10; i++)   //輸出全部炸彈資訊(上帝視角,除錯用)
  //{
  // for (j = 0; j < 10; j++)
  // {
  //   printf("%2d ",cbd[i][j]);
  // }
  // printf("\n");
  //}
  printf("   1 2 3 4 5 6 7 8 9 10\n");   //行標
  printf("  --------------------\n");
  for (i = 0; i<10; i++)    //根據u陣列和cbd陣列的值選擇輸出
  {                //■:未掃描,□:周圍無炸彈,◇:炸彈標記
    for (j = 0; j<10; j++)
    {
      if (j == 0)printf("%2d║ ",i+1);
      if (u[i][j] == 0)printf("■");
      else if (u[i][j] == 1)
      {
        if (cbd[i][j] == 0)printf("□");
        else printf("%2d",cbd[i][j]);
      }
      else if (u[i][j] == -1) 
      {
        printf("◇");
      }
    }
    printf("\n");
  }
}

int find(int cbd[10][10],int i,int j)   //掃描周圍炸彈數目
{
  int l,c,lmin,cmin,lmax,cmax,num = 0;
  l = lmin = (i - 1) >= 0 ? (i - 1) : 0;   //計算行、列起點
  c = cmin = (j - 1) >= 0 ? (j - 1) : 0;
  lmax = ((i + 1) < 10 ? (i + 1) : 9);    //計算行、列終點
  cmax = ((j + 1) < 10 ? (j + 1) : 9);

  for (l = lmin; l <= lmax; l++)
  {
    for (c = cmin; c <= cmax; c++)
    {
      if (l == i&&c == j)continue;    //跳過自身
      if (cbd[l][c] == -1)num++;  //炸彈計數
    }
  }
  return num;
}

void init(int cbd[10][10])    //cbd陣列初始化(隨機佈置炸彈並填充各個格子的數目)
{
  int n = 10,l,i,j;
  srand(time(NULL));      //隨機數種子設定
  for (i = 0; i< 10; i++)
  {
    for (j = 0; j< 10; j++)
    {
      cbd[i][j] = 0;      //全0填充
    }
  }
  while (n--)     //隨機行列放置炸彈
  {
    l = rand() % 10;
    c = rand() % 10;
    if (cbd[l][c] != -1)cbd[l][c] = -1;    //炸彈重複處理
    else n++;
  }
  for (i = 0; i< 10; i++)
  {
    for (j = 0; j< 10; j++)
    {
      if (cbd[i][j] != -1)
      {
        cbd[i][j] = find(cbd,j);  //炸彈數目填充
      }
    }
  }
}

void open(int cbd[10][10],int u[10][10],int j)   //周圍無炸彈時的展開函式(遞迴展開)
{
  u[i][j] = 1;
  if (cbd[i][j] == 0)
  {
    if(i - 1 >= 0 && u[i - 1][j] != 1)open(cbd,u,i - 1,j);  //上
    if(j - 1 >= 0 && u[i][j - 1] != 1)open(cbd,j - 1);  //左
    if (i + 1 <= 9 && u[i + 1][j] != 1)open(cbd,i + 1,j); //下
    if (j + 1 <= 9 && u[i][j + 1] != 1)open(cbd,j + 1); //右
  }
}

int judge(int u[10][10])    //判斷遊戲是否通關
{
  int i,j,num = 0;
  for (i = 0; i < 10; i++)
  {
    for (j = 0; j < 10; j++)
    {
      if (u[i][j] == 0 || u[i][j] == -1)num++;
    }
  }
  if (num == 10)return 1;
  else return 0;
}

void fail(int cbd[10][10],int u[10][10])    //遊戲失敗函式
{
  int i,j;
  for (i = 0; i < 10; i++)          //輸出全部炸彈資訊
  {
    for (j = 0; j < 10; j++)
    {
      if (cbd[i][j] == 0)printf(" ");
      else if (cbd[i][j] != -1)printf("%2d",cbd[i][j]); 
      else printf("●");
    }
    printf("\n");
  }
  printf("請大俠重新來過~\n");
}

void menu(int cbd[10][10],int u[10][10])  //選單函式
{
  int chs,j;
  int boom = 10;    //剩餘炸彈數
  int num = 0;     //步數
  while (1)                  
  {
    system("cls");
    show(cbd,u);
    printf("還有%d個炸彈\n",boom);
    printf("1.掃描  2.標記  3.取消標記\n");
    printf("請輸入選項:>");
    scanf("%d",&chs);
    if (chs > 3 || chs < 1) {
      printf("請輸入正確選項!\n");
      system("pause");
      continue;
    }
    printf("請輸入座標:>");
    scanf("%d %d",&i,&j);
    if (i < 1 || i>10)
    {
      printf("請輸入正確座標!\n");
      system("pause");
      continue;
    }
    i--;      //輸入行列數處理(適用陣列下標)
    j--;
    if (chs == 1)
    {
      if (cbd[i][j] == -1) {
        if (num == 0) {   //若第一步掃描到炸彈,就重新初始化棋盤
          init(cbd);
          show(cbd,u);
          open(cbd,j);
          num++;
          continue;
        }
        else
        {
          fail(cbd,u);  //否則遊戲失敗,迴圈跳出
          break;
        }
      }
      if (u[i][j] == 1)    //重複掃描時的處理
      {
        printf("該位置已經掃描過了!\n");
        system("pause");
        continue;
      }
      open(cbd,j);
      num++;
    }
    else if(chs == 2)
    {
      if (u[i][j] == 1) {
        printf("該位置已經掃描過了!\n"); //只能標記未掃描到的
        system("pause");
        continue;
      }
      u[i][j] = -1;
      boom --;      
    }
    else if (chs == 3)
    {
      if (u[i][j] != -1) {
        printf("該位置沒有標記!\n");    //只能取消標記過的
        system("pause");
        continue;
      }
      u[i][j] = 0;
      boom++;
    }
    if (judge(u))    //判斷遊戲是否通關
    {
      printf("Old Fe 666!\n");    //老鐵666!,迴圈跳出
      break;
    }
  }
}

int main()
{
  int cbd[10][10] = { 0 };    //儲存炸彈資訊的二維陣列
  int u[10][10] = { 0 };     //儲存是否翻開資訊的二維陣列
  init(cbd);      //陣列初始化
  menu(cbd,u);    //進入選單
  return 0;
}

Tips:在掃描到周圍無炸彈的格子時,要將此格子周圍的部分依次開啟,直到上下左右都出現炸彈數字為止,這裡要用到遞迴的方法,我的順序為依次遞迴處理上、左、下、右的格子,這裡順序可以任意。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。