c語言---掃雷游戲
- 前言
- 一、前期準備--游戲介紹
- 二、代碼的具體實作
- 1. game.c 頭檔案
- 2. game.c具體實作檔案
- 3. test.c 測驗檔案
- 總結:
前言
本系列博文僅為博主個人學習筆記,通過博客理清學習思路用于復習,如有記述不周到的地方請諒解;如能指出,更加感謝,
一、前期準備–游戲介紹
掃雷游戲它是由row * col的格子拼起來,游戲規則:這款游戲的玩法是在一個99(初級),1616(中級),16*30(高級),或自定義大小的方塊矩陣中隨機布置一定量的地雷(初級為10個,中級為40個,高級為99個),由玩家逐個翻開方塊,以找出所有地雷為最終游戲目標,如果玩家翻開的方塊有地雷,則游戲結束,

// 本程式采用兩個二維陣列存盤棋盤
char mine[row][col] ; // 用來存盤雷的資訊
char show[row][col] ; // 用來展示當前玩家展開棋盤的資訊
```
## 1.該如何用c語言實作這樣一款游戲 ---- 代碼分析
該游戲主要步驟就是兩步1.如何設定雷2.如何排查雷,
1. 設定雷
```c
//隨機產生一對坐標,存盤在x ,y當中
int x = rand() % row + 1 ;
int y = rand() % col + 1 ;
//若存盤地雷的二維陣列該坐標不是雷,則將其設定成雷
if(mine[x][y] == '0'){
mine[x][y] = '1';
}
2、排查雷
玩家輸入一對坐標,對坐標進行判斷是否是合法輸入,如果是合法輸入,則繼續判斷該坐標對應的mine陣列是否為雷,若為雷,則結束游戲,提示玩家您不小心踩到啦雷,游戲結束;若沒有踩到雷,則繼續游戲,并將該格子對應坐標周圍所有的雷數展示出來,玩家繼續挖雷,直到所有的不是雷的格子被玩家全部挖出,則游戲結束,提示玩家獲勝,
playerMove(char mine[][COLS],char show[][COLS], int row, int col) {
int x = 0;
int y = 0;
int count = 0;
while (count < row * col - NUM_MINE) {
printf("請輸入您要排除的雷的坐標:");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col) {
if (mine[x][y] == '1') {
printf("不好意思,你被炸啦,游戲結束\n");
break;
}
/*int ret = count_mine(mine, x, y);
show[x][y] = ret + '0';
count++;*/
else {
//對代碼的遞回優化,詳細請見下文,功能是將與輸入坐標周圍8個格子所有不是雷的展開,提高用戶游戲體驗,
OpenMine(mine, show, row, col, x, y, &count);
//列印當前游戲棋盤的狀態
Display(show, row, col);
}
}
else {
printf("輸入坐標非法:\n");
}
}
if (count >= (col * row - NUM_MINE)) {
printf("恭喜您,掃雷成功\n");
}
}
二、代碼的具體實作
本程式分為三個檔案 game.h 頭檔案,game.c 具體實作檔案,test.c測驗檔案 ,
1. game.c 頭檔案
#include <stdio.h>
#define NUM_MINE 10
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
//initial array 1. mine 2. show
initial(char board[][COLS], int rows, int col,char set);
//display 1. mine 2. show
Display(char board[][COLS], int row, int col);
//set mine
set_mine(char mine[][COLS], int row, int col);
//remove mine
playerMove(char mine[][COLS],char show[][COLS], int row, int col);
2. game.c具體實作檔案
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
//initial array 1. mine 2. show
initial(char board[][COLS], int rows, int cols,char set) {
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
board[i][j] = set;
}
}
}
//display 1. mine 2. show
Display(char board[][COLS], int row, int col) {
printf("------掃雷游戲------\n");
for (int i = 0; i <= row; i++) {
printf("%d ", i);
}
printf("\n");
for (int i = 1; i <= row; i++)
{
printf("%d ", i);
for (int j = 1; j <= col; j++)
{
printf("%c ", board[i][j]);
}
printf("\n");
}
printf("------掃雷游戲------\n");
}
//set mine
set_mine(char board[][COLS], int row, int col) {
int count = NUM_MINE;
while (count) {
int x = rand() % row + 1;
int y = rand() % col + 1;
if (board[x][y] == '0') {
board[x][y] = '1';
count--;
}
}
}
//count mine by every grid
static int count_mine(char mine[][COLS], int x, int y) {
return mine[x - 1][y - 1] +
mine[x-1][y] +
mine[x - 1][y + 1] +
mine[x][y - 1] +
mine[x][y + 1] +
mine[x + 1][y - 1] +
mine[x + 1][y] +
mine[x + 1][y + 1] - '0' * 8;
}
//open mines one by one
static void OpenMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int x, int y,int *level)
{
(*level)++;
if (mine[x][y] == '1' || x < 1 || x > row || y < 1 || y > col || show[x][y] != '*') {
(*level)--;
return;
}
int ret = count_mine(mine, x, y); //呼叫統計雷個數的函式,
if (!ret)
{
show[x][y] = ' ';
//要確定周圍8個坐標本身不是雷,才遞回它周圍的,
OpenMine(mine, show, row, col, x - 1, y - 1,level);
OpenMine(mine, show, row, col, x, y - 1,level);
OpenMine(mine, show, row, col, x + 1, y - 1, level);
OpenMine(mine, show, row, col, x - 1, y, level);
OpenMine(mine, show, row, col, x + 1, y, level);
OpenMine(mine, show, row, col, x - 1, y + 1, level);
OpenMine(mine, show, row, col, x, y + 1, level);
OpenMine(mine, show, row, col, x + 1, y + 1, level);
}
else
{
show[x][y] = ret + '0'; //顯示該坐標周圍有幾個雷
return;
}
}
//playermoving
playerMove(char mine[][COLS],char show[][COLS], int row, int col) {
int x = 0;
int y = 0;
int count = 0;
while (count < row * col - NUM_MINE) {
printf("請輸入您要排除的雷的坐標:");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col) {
if (mine[x][y] == '1') {
printf("不好意思,你被炸啦,游戲結束\n");
break;
}
/*int ret = count_mine(mine, x, y);
show[x][y] = ret + '0';
count++;*/
else {
OpenMine(mine, show, row, col, x, y, &count);
Display(show, row, col);
}
}
else {
printf("輸入坐標非法:\n");
}
}
if (count >= (col * row - NUM_MINE)) {
printf("恭喜您,掃雷成功\n");
}
}
3. test.c 測驗檔案
#include "game.h"
#include <stdlib.h>
#include <time.h>
void menu() {
printf("*********************\n");
printf("******1. play *****\n");
printf("******0. exit *****\n");
printf("*********************\n");
}
void game() {
//定義兩陣列來存盤資料
char mine[ROWS][COLS] = { 0 };
char show[ROWS][COLS] = { 0 };
//initial array
initial(mine, ROWS, COLS,'0');
initial(show, ROWS, COLS,'*');
//Display(mine, ROW, COL);
Display(show, ROW, COL);
//set mine
set_mine(mine, ROW, COL);
playerMove(mine,show, ROW, COL);
Display(mine, ROW, COL);
}
int main() {
srand((unsigned)time(NULL));
int input = 0;
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;
}
此處重點來說說openmine 這個函式,功能是一個一個的展開周圍的8個格子,若該格子的坐標不合法,曾訪問過或者是雷,則滿足條件,return回傳,若滿足以上條件均不滿足,則將該格子周圍的雷數進行統計,若統計數不為零,則不將其周圍格子進行展開,只將其格子周圍的雷數展示出來;若統計數為0,則將該格子置為‘ ’,并進入下一個格子 的判斷:將該格子的左上,左,左下,正上,正下,右上,右,右下8個格子繼續進行以上三個判斷,并用一個變數count計數,依次判斷,直到所有相鄰的格子判斷完畢,若count < row * col - 雷數, 則玩家繼續輸入坐標進行下一輪判斷,重復上述動作,在玩家沒有踩到雷的情況下正常,直到 count < row* col - 雷數不滿足條件,跳出回圈 ,提示玩家勝利,
游戲界面展示

總結:
掃雷游戲還是比較簡單的,希望同學們一起努力,從c語言青銅慢慢變成c語言王者,我們一起在山頂相遇,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/281730.html
標籤:其他
上一篇:Xcode呼叫raylib圖形庫
