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

C語言實現簡單的掃雷小遊戲

本文例項為大家分享了C語言實現掃雷小遊戲的具體程式碼,供大家參考,具體內容如下

在編寫掃雷小遊戲之前,第一,我們應該列出我們想要實現的掃雷小遊戲的功能:

1.顯示選中的座標周圍的雷的個數。
2.保證第一次選中的座標不是雷。
3.選中的座標周圍8個格子中沒有雷,則展開。

第二,我們應該明白我們需要兩個棋盤來實現掃雷遊戲:一個棋盤用來展示給玩家,初始介面全為“ * ” (未翻開的格子),這個頁面就是我們常見的掃雷頁面。另一個棋盤用來給編寫者看,棋盤內只有字元‘1'和字元‘0' 。‘1'代表雷,‘0'代表非雷。使用字元‘1'‘0'來代表雷和非雷有利於我們下一步計算座標周圍雷的個數。

1.初始化棋盤

nitboard(show_board,ROWS,COLS,'*'); //‘*'代表未翻開的座標
 Initboard(mine_board,'0'); //‘0'代表非雷
 void Initboard(char board[ROWS][COLS],int row,int col,char set)
{
 memset(board,set,row*col * sizeof(board[0][0]));
}

2.列印棋盤

void DisPlayboard(char board[ROWS][COLS],int col)
{
 int i = 0;
 int j = 0;
 printf(" ");
 for (i = 1; i <= row; i++) //列印行
 {
 printf("%d ",i);
 }
 printf("\n");
 for (i = 1; i <= row; i++)
 {
 printf("%d ",i); //列印列
 for (j = 1; j <= col; j++)
 {
 printf("%c ",board[i][j]);
 }
 printf("\n");
 }
 printf("\n");
}

3.在棋盤中埋入雷。(因為每一次重新開始遊戲雷的位置不能重複,所以選擇用隨機數來埋雷)

void GetBoom(char board[ROWS][COLS],int col) //埋雷
{
 int x = 0;
 int y = 0;
 int sum = 0;
 while(1)
 { 
 x = rand() % row +1; //雷放在1-9的範圍裡
 y = rand() % col +1;
 if (1)
 {
 board[x][y] = '1';
 sum++;
 if (sum == M) //埋入雷後跳出迴圈
 {
 break;
 }
 }
 }

4.確保第一次不踩到雷,如果第一次踩到雷,我們就將此位置改為非雷,然後將此處的雷移動到別處未放置雷的位置。

(還要考慮一種特殊情況,即如果第一次落子就獲得勝利的情況時後面函式就不用再執行了,所以此函式要改為有返回值的函式,這樣在呼叫此函式時就可以判斷是否為一次就獲得勝利的情況)

int Judge_first(char mine_board[ROWS][COLS],char show_board[ROWS][COLS],int col)
{
 int x = 0;
 int y = 0;
 int m;
 int n;
 printf("請輸入要排查的座標:");
 scanf("%d%d",&x,&y);
 while (1)
 {
 if (mine_board[x][y] == '1') //如果第一次踩雷,將此座標改為非雷
 {
 mine_board[x][y] = '0';
 show_board[x][y] = ' ';
 while (1)
 {
 m = rand() % 9 + 1;
 n = rand() % 9 + 1;
 if (m != x && n != y && mine_board[m][n] != '1')
 {
 mine_board[m][n] = '1';
 }
 Open(mine_board,show_board,x,y);
 if (Full(show_board,ROW,COL) == 1) //展開後判斷是否一次獲得勝利
 {
 printf("遊戲勝利\n");
 DisPlayboard(mine_board,COL);
 return 2;  //一次獲得勝利返回2 不再執行PlayerMove函式
 break;
 }
 DisPlayboard(show_board,row,col);
 break;
 }
 break;
 }
 else if (mine_board[x][y] == '0')
 {
 show_board[x][y] = ' ';
 Open(mine_board,COL) == 1)
 {
 printf("遊戲勝利\n");
 DisPlayboard(mine_board,COL);
 return 2;
 break;
 }
 DisPlayboard(show_board,col);
 break;
 }
 }
}

5.當座標周圍雷個數為0時,展示周圍格子,再以X和Y周圍八個座標分別為中心展開,當座標周圍有雷時不再遞迴展開,並將雷的個數放在該座標。

void Open(char mine_board[ROWS][COLS],int x,int y)
{
 int ret = 0;
 ret = Num(mine_board,y);
 if (ret == 0) //當座標周圍雷個數為0時 開啟周圍格子 再以X和Y周圍八個座標為中心展開 重複即為遞迴展開
 {
 show_board[x][y] = ' '; 
 if (x - 1 > 0 && y - 1 > 0 && show_board[x - 1][y - 1] == '*')
 {
 Open(mine_board,x - 1,y - 1);
 }
 if (x - 1 > 0 && y > 0 && show_board[x - 1][y] == '*')
 {
 Open(mine_board,y);
 }
 if (x - 1 > 0 && y + 1 <= COL && show_board[x - 1][y + 1] == '*')
 {
 Open(mine_board,y + 1);
 }
 if (x > 0 && y + 1 <= COL && show_board[x][y + 1] == '*')
 {
 Open(mine_board,y + 1);
 }
 if (x + 1 < ROW && y + 1 <= COL && show_board[x + 1][y + 1] == '*')
 {
 Open(mine_board,x + 1,y + 1);
 }
 if (x + 1 <= ROW && y > 0 && show_board[x + 1][y] == '*')
 {
 Open(mine_board,y);
 }
 if (x + 1 <= ROW && y - 1 > 0 && show_board[x + 1][y - 1] == '*')
 {
 Open(mine_board,y - 1);
 }
 if (x > 0 && y - 1 > 0 && show_board[x][y - 1] == '*')
 {
 Open(mine_board,y - 1);
 }
 }
 else if (ret != 0)
 show_board[x][y] = Num(mine_board,y) + 48;
}

6.計算座標周圍一圈中所含雷的個數。

int Num(char board[ROWS][COLS],int y)
{
 int sum = 0; //sum為座標周圍雷的個數
 sum = board[x - 1][y - 1]
 + board[x][y - 1] + board[x + 1][y - 1]
 + board[x + 1][y] + board[x + 1][y + 1]
 + board[x][y + 1] + board[x - 1][y + 1]
 + board[x - 1][y] - (8 * '0');
 return sum;
}

7.判斷玩家是否排完所有雷。

int Full(char board[ROWS][COLS],int col) 
{
 int i;
 int j;
 int sum = 0; //sum為棋盤未翻開格子的個數
 for (i = 1; i <= row; i++)
 {
 for (j = 1; j <= col; j++)
 {
 if (board[i][j] == '*')
 sum++;
 } 
 }
 if (sum == M) //當未翻開的格子數為雷數時 返回1
 return 1;
}

8.玩家輸入座標掃雷。

void PlayerMove(char mine_board[ROWS][COLS],int col)
{
 int x = 0;
 int y = 0;
 int ret = 0;
 while (1)
 {
 if (Full(show_board,COL) == 1) //棋盤未翻開格子等於雷數時玩家勝利
 {
 printf("遊戲勝利\n");
 DisPlayboard(mine_board,COL);
 break;
 }
 printf("請輸入座標:");
 scanf("%d%d",&y);
 if (x >= 1 && x <= row && y >= 1 && y <= col)
 {
 
 if (mine_board[x][y] == '1') //玩家踩到雷,遊戲結束
 {
 printf("遊戲結束\n");
 DisPlayboard(mine_board,COL);
 break;
 }
 ret = Num(mine_board,y);
 if (ret == 0) //周圍沒有雷時,展開周圍格子
 {
 Open(mine_board,y);
 DisPlayboard(show_board,COL);
 }
 else if (ret != 0) //周圍有雷時列印雷的個數
 {
 show_board[x][y] = ret + 48;
 DisPlayboard(show_board,COL);
 }
 }
 else
 printf("輸入錯誤,請重新輸入");
 }
}

9.函式宣告,巨集定義,函式的定義實現,測試。

原始檔:test.c //主要負責測試整個程式碼
標頭檔案:game.h //包含函式各種宣告,巨集定義
原始檔:game.c //包含各種函式的定義

test.c

#include"game.h"
void menu()
{
 printf("************************************\n");
 printf("************************************\n");
 printf("******* 1.play  *******\n");
 printf("******* 0.exit  *******\n");
 printf("************************************\n");
}

int game()
{
 char show_board[ROWS][COLS] = { 0 };
 char mine_board[ROWS][COLS] = { 0 };
//
 Initboard(show_board,'*'); //初始化陣列
 Initboard(mine_board,'0'); 
 printf("遊戲開始\n");
 DisPlayboard(show_board,COL); //列印玩家雷盤
//
 GetBoom(mine_board,COL); //埋雷
 printf("\n\n\n");
 DisPlayboard(mine_board,COL); //列印雷盤
//
 if (Judge_first(mine_board,COL) == 2) //如果一次勝利,就不再執行PlayerMove函式
 return 2;
// 
 PlayerMove(mine_board,COL); 
}

void test()
{
 int n;
 menu();
 do
 {
 printf("請輸入選項按鈕: ");
 scanf("%d",&n);
 switch (n)
 {
 case 1:
 game();
 break;
 case 0:
 printf("遊戲退出\n");
 break;
 default:
 printf("輸入錯誤,請重新輸入\n");
 break;
 } 
 }while(1);
}
int main()
{
 srand((unsigned int)time(NULL));
 test();
}

game.c

#include"game.h"
void Initboard(char board[ROWS][COLS],row*col * sizeof(board[0][0]));
}
void DisPlayboard(char board[ROWS][COLS],board[i][j]);
 }
 printf("\n");
 }
 printf("\n");
}

void GetBoom(char board[ROWS][COLS],int col) //埋雷
{
 int x = 0;
 int y = 0;
 int sum = 0;
 while(1)
 { 
 x = rand() % row +1; //雷放在1-9的範圍裡
 y = rand() % col +1;
 if (1)
 {
 board[x][y] = '1';
 sum++;
 if (sum == M) //埋入所需的雷後跳出迴圈
 {
 break;
 }
 }
 }
}

int Judge_first(char mine_board[ROWS][COLS],col);
 break;
 }
 }
}

void PlayerMove(char mine_board[ROWS][COLS],COL) == 1) //棋盤下滿玩家勝利
 {
 printf("遊戲勝利\n");
 DisPlayboard(mine_board,&y);
 if (x >= 1 && x <= row && y >= 1 && y <= col)
 {
 
 if (mine_board[x][y] == '1')
 {
 printf("遊戲結束\n");
 DisPlayboard(mine_board,COL);
 }
 }
 else
 printf("輸入錯誤,請重新輸入");
 }
}

void Open(char mine_board[ROWS][COLS],y) + 48;
}

int Num(char board[ROWS][COLS],int y)
{
 int sum = 0;
 sum = board[x - 1][y - 1]
 + board[x][y - 1] + board[x + 1][y - 1]
 + board[x + 1][y] + board[x + 1][y + 1]
 + board[x][y + 1] + board[x - 1][y + 1]
 + board[x - 1][y] - (8 * '0');
 return sum;
}

int Full(char board[ROWS][COLS],int col)
{
 int i;
 int j;
 int sum = 0;
 for (i = 1; i <= row; i++)
 {
 for (j = 1; j <= col; j++)
 {
 if (board[i][j] == '*')
 sum++;
 } 
 }
 if (sum == M)
 return 1;
}

game.h

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

#define ROW 9
#define COL 9
#define ROWS ROW + 2
#define COLS COL + 2
#define M 10 //所需雷的個數

void test();
int game();
void Initboard(char board[ROWS][COLS],int set); //初始化陣列
void DisPlayboard(char board[ROWS][COLS],int col); //列印雷盤
void GetBoom(char board[ROWS][COLS],int col); //安放炸彈
int Judge_first(char mine_board[ROWS][COLS],int col); //保證第一次不是雷
void PlayerMove(char mine_board[ROWS][COLS],int col); //玩家排雷
void Open(char mine_board[ROWS][COLS],int y); //展開函式
int Num(char mine_board[ROWS][COLS],int y); //計算座標周圍雷的數量
int Full(char board[ROWS][COLS],int col); //判斷雷是否下滿

更多有趣的經典小遊戲實現專題,分享給大家:

C++經典小遊戲彙總

python經典小遊戲彙總

python俄羅斯方塊遊戲集合

JavaScript經典遊戲 玩不停

java經典小遊戲彙總

javascript經典小遊戲彙總

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