? ? 在編程的世界里,掃雷游戲是一個經典的實踐項目。它不僅能幫助我們鞏固編程知識,還能鍛煉邏輯思維和解決問題的能力。今天,就讓我們一起用 C 語言來實現這個有趣的游戲,并且通過圖文并茂的方式,讓每一步都清晰易懂
1. 游戲功能概述?
我們要實現的掃雷游戲具備以下核心功能:
?
- 界面交互:通過控制臺進行交互,玩家可以看到清晰的游戲界面,包括棋盤和操作提示。
- 菜單系統:提供簡單的菜單,讓玩家能夠選擇開始游戲或退出游戲。
- 棋盤設定:游戲棋盤為 9×9 的格子,默認隨機布置 10 個雷。
- 排雷機制:玩家輸入坐標排查雷,如果位置不是雷,會顯示周圍雷的數量;如果選中雷,游戲結束;成功找出所有非雷位置,游戲勝利。
2. 游戲設計思路
2.1 數據結構的選擇
? ? 1. 棋盤數組:考慮到在排查雷時,棋盤邊緣位置可能會出現越界問題,我們將存放數據的數組設計為 11×11。雷布置在中間 9×9 的區域,周圍一圈不布置雷。
? ? 2. 雙數組策略:為了避免雷的信息與排查出雷的數量信息混淆,我們使用兩個數組。
mine
數組存放布置好的雷的信息,初始化為字符'0'
,布置雷時改為'1'
;show
數組存放排查出的雷的個數信息,初始化為字符'*'
。
?
2.2 文件結構規劃
為了使代碼結構清晰、易于維護,我們采用多文件形式:
?
test.c
:負責編寫游戲的測試邏輯,控制游戲流程。game.c
:實現游戲中的各種函數,如初始化棋盤、布置雷、排查雷等。game.h
:定義游戲所需的數據類型和函數聲明,以及一些宏定義。
?3.?代碼實現詳解
game.h文件
#pragma once #include <stdio.h> #include <stdlib.h> #include <time.h>#define EASY_COUNT 10 #define ROW 9 #define COL 9 #define ROWS ROW + 2 #define COLS COL + 2// 初始化棋盤 void InitBoard(char board[ROWS][COLS], int rows, int cols, char set); // 打印棋盤 void DisplayBoard(char board[ROWS][COLS], int row, int col); // 布置雷 void SetMine(char board[ROWS][COLS], int row, int col); // 排查雷 void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
? ? 在
game.h
文件中,我們引入了必要的頭文件,定義了一些常量,如雷的數量、棋盤大小等,并聲明了游戲中用到的函數。
game.c文件
#include "game.h"// 初始化棋盤函數 void InitBoard(char board[ROWS][COLS], int rows, int cols, char set) {int i = 0;for (i = 0; i < rows; i++) {int j = 0;for (j = 0; j < cols; j++) {board[i][j] = set;}} }// 打印棋盤函數 void DisplayBoard(char board[ROWS][COLS], int row, int col) {int i = 0;printf("------掃雷游戲-------\n");for (i = 0; i <= col; i++) {printf("%d ", i);}printf("\n");for (i = 1; i <= row; i++) {printf("%d ", i);int j = 0;for (j = 1; j <= col; j++) {printf("%c ", board[i][j]);}printf("\n");} }// 布置雷函數 void SetMine(char board[ROWS][COLS], int row, int col) {// 布置10個雷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 GetMineCount(char mine[ROWS][COLS], int x, int y) {return (mine[x - 1][y] + mine[x - 1][y - 1] + mine[x][y - 1] + mine[x + 1][y - 1] +mine[x + 1][y] + mine[x + 1][y + 1] + mine[x][y + 1] + mine[x - 1][y + 1] - 8 * '0'); }// 排查雷函數 void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col) {int x = 0;int y = 0;int win = 0;while (win < row * col - EASY_COUNT) {printf("請輸入要排查的坐標:");scanf("%d %d", &x, &y);if (x >= 1 && x <= row && y >= 1 && y <= col) {if (mine[x][y] == '1') {printf("很遺憾,你被炸死了\n");DisplayBoard(mine, ROW, COL);break;} else {int count = GetMineCount(mine, x, y);show[x][y] = count + '0';DisplayBoard(show, ROW, COL);win++;}} else {printf("坐標非法,重新輸入\n");}}if (win == row * col - EASY_COUNT) {printf("恭喜你,排雷成功\n");DisplayBoard(mine, ROW, COL);} }
? game.c
文件實現了游戲的主要功能函數。InitBoard
函數初始化棋盤,DisplayBoard
函數用于打印棋盤,SetMine
函數隨機布置雷,GetMineCount
函數統計周圍雷的數量,FindMine
函數實現排查雷的邏輯。
test.c文件
#include "game.h"// 菜單函數 void menu() {printf("***********************\n");printf("***** 1. play *****\n");printf("***** 0. exit *****\n");printf("***********************\n"); }// 游戲函數 void game() {char mine[ROWS][COLS];char show[ROWS][COLS];// 初始化棋盤InitBoard(mine, ROWS, COLS, '0');InitBoard(show, ROWS, COLS, '*');// 打印棋盤DisplayBoard(show, ROW, COL);// 布置雷SetMine(mine, ROW, COL);// 排查雷FindMine(mine, show, ROW, COL); }int main() {int input = 0;srand((unsigned int)time(NULL));do {menu();printf("請選擇:>");scanf("%d", &input);switch (input) {case 1:game();break;case 0:printf("退出游戲\n");break;default:printf("選擇錯誤,重新選擇\n");break;}} while (input);return 0; }
? ?
test.c
文件中的menu
函數展示游戲菜單,game
函數整合游戲流程,main
函數通過循環和switch
語句處理玩家的選擇,控制游戲的開始和結束。