C語言版掃雷遊戲

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

1、思路

一、創建二維數組,來表示地圖

每一個格子要表示的信息:

1、未翻開狀態(草地)和已翻開狀態(數字)
2、該格子是地雷或者不是地雷(1表示是地雷,0表示不是)

二、使用兩個二維數組來分別表示以上的兩種狀態

第一個二維數組
char showMap[9][9];表示每個格子的翻開和未翻開狀態
表示未翻開,字符’0′-‘8’表示已翻開的數字
第二個二維數組
char mineMap[9][9];表示每個格子是否是地雷
‘1’表示是地雷,’0’表是不是地雷

三、掃雷遊戲流程

1、創建地圖並初始化
針對showMap來說,初始化全是
針對mineMap來說,先把整個數組都初始化成’0’,隨機生成10個位置,作為地雷,設為’1’,
2、打印地圖showMap
3、讓玩傢輸入坐標,表示要翻開的位置
4、判定是否踩雷
5、更新showMap,再翻開位置顯示周圍有多少個地雷
6、判定玩傢是否翻開瞭所有的位置
如果為否則返回第二步

2、源代碼:

#define  _CRT_SECURE_NO_WARNINGS  
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>


#define MAX_ROW 9
#define MAX_COL 9
#define MINE_COUNT 10

void init(char showMap[MAX_ROW][MAX_COL], char mineMap[MAX_ROW][MAX_COL])
{
 //初始化第一張地圖
 /*for (int row = 0; row < MAX_ROW; row++)
  for (int col = 0; col < MAX_COL; col++)
   showMap[row][col] = '*';*/
 //mem=>memory 內存
 //set:設置,集合
 //memset的功能就是把一段內存上的每一個字節都設置成一個具體的值
 //二維數組的每個元素都是在一個連續的內存空間上佈局的
 memset(showMap,'*',MAX_ROW*MAX_COL);
 //第一個參數表示起始位置,第二個參數表示把這段內存的值設為啥,第三個參數表示這段內存多少字節
 memset(mineMap, '0', MAX_ROW * MAX_COL);
 //隨機產生十個位置作為地雷
 //先設置隨機種子
 srand((unsigned int)time(0));
 int mineCount = 0;
 while (mineCount< MINE_COUNT) {
  int row = rand() % MAX_ROW;
  int col = rand() % MAX_COL;
  if (mineMap[row][col] == '1') {
   continue;
  }
  mineMap[row][col] = '1';
  mineCount++;
 }

}  
//打印地圖,希望這一個函數同時具備打印兩種地圖的功能
//取決於實參填啥
//形參名字叫做"map"不太合適,C++標準庫裡有一個std::map
void print(char theMap[MAX_ROW][MAX_COL]) {
 for (int row = 0; row < MAX_ROW; row++) {
  for (int col = 0; col < MAX_COL; col++) {
   printf("%c",theMap[row][col]);
  }
  printf("\n");
 }
}

void update(char showMap[MAX_ROW][MAX_COL],
    char mineMap[MAX_ROW][MAX_COL],int row,int col){
 //count表示周圍的地雷個數
 int count = 0;
 for (int r = row - 1; r <= row + 1; r++) {
  for (int c = col - 1; c <= col + 1; c++) {
   if (r < 0 || r >= MAX_ROW || c < 0 || c >= MAX_COL) {
    //此時r,c坐標超出棋盤的范圍,直接跳出
    continue;
   }
   if (r == row && c == col) {
    //如果為這個點本身,不需要循環,直接下次循環
    continue;
   }
   if (mineMap[r][c] == '1') {
    count++;
   }
  }
 }
 //如果直接賦值,此時假設count是2,
 //當前row,col位置的元素就被設置成瞭ASCLL值為
 //2的字符而不是'2'
 showMap[row][col] ='0'+ count;
}
int main() {
 //1、創建地圖並初始化
 char showMap[MAX_ROW][MAX_COL] = { 0 };
 char mineMap[MAX_ROW][MAX_COL] = { 0 };
 init(showMap, mineMap);
 int openedCount = 0;//用來表示翻開的個數
 while (1) {
  //清屏
  system("cls");
  //2、打印地圖
  print(showMap);
  //為瞭驗證update函數的正確性,先把地雷的佈局也打印出來
  //printf("============================\n");
  //print(mineMap);
  //3、玩傢輸入坐標
  int row = 0;
  int col = 0;
  printf("請輸入坐標(row,col):");
  scanf("%d %d", &row, &col);
  //進行合法性判定
  if (row < 0 || row >= MAX_ROW || col < 0 || col >= MAX_COL) {
   printf("你輸入的坐標有誤!請重新輸入!\n");
   continue;
  }
  //判斷玩傢輸入的位置是否已經翻開
  if (showMap[row][col] != '*') {
   printf("您輸入的位置已經翻開瞭!請重新輸入!\n");
   continue;
  }
  //4、判定是否踩雷
  if (mineMap[row][col] == '1') {
   printf("您踩雷瞭!!!遊戲結束!\n");
   break;
  }
  //5、更新showMap,顯示當前位置周圍有多少個雷
  update(showMap, mineMap, row, col);
  //6、進行遊戲勝利的判定,統計當前一共翻開瞭多少個格子
  openedCount++;
  if (openedCount == MAX_ROW * MAX_COL - MINE_COUNT) {
   printf("恭喜你,獲勝瞭!\n");
   break;
  }
 }
 system("pause");
 return 0;
}

3、總結

a.memset函數的使用
b.使用數組時應時刻註意越界問題
c.在update函數中數坐標周圍地雷個數時註意不要直接賦值,而應該加字符0,因為地圖元素為char型。

showMap[row][col] ='0'+ count;

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

推薦閱讀: