欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C語言代碼實現(xiàn)簡單掃雷小游戲

 更新時間:2021年01月27日 09:00:11   作者:H_Strong  
這篇文章主要為大家詳細介紹了C語言實現(xiàn)掃雷游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

用C語言寫一個簡單的掃雷,供大家參考,具體內(nèi)容如下

1.所需要的知識

c語言的基本語法,簡單的二維數(shù)組,一點簡單的遞歸知識。

2.總體思路

掃雷游戲主要由3個部分組成,埋雷子,掃雷,判斷輸贏。
掃雷游戲的主體是兩個個字符類型的二維數(shù)組。一個是mine[][]它的構(gòu)成是'0'和‘1',其中'0'表示無雷,'1'表示有雷。一個是show[][]它的構(gòu)成是'*'和'數(shù)字'。星號表示未開啟的地方,數(shù)字表示周圍的雷數(shù)。這里要注意的是:mine和show的實際大小是11x11,但是展示的效果是 9x9。這樣做的優(yōu)點將在Find()中體現(xiàn)。藍色部分是可見的9x9,實際的類似紅色 11x11。

下面是我用到的一些函數(shù)。

//game.h
#pragma once
#ifndef __GAME_H__
#define __GAME_H__
#include<stdio.h>
#include<stdlib.h>
#include<process.h>
#include<string.h>
#include<time.h>
#define ROW 9 // 9行
#define COL 9 // 9列
#define ROWS ROW+2 //實際行
#define COLS COL+2 //實際列
#define MineNum 10 //雷子數(shù)量
//菜單信息
void menu();
//執(zhí)行菜單
void test(char mine[ROWS][COLS], int row1, int col1, char show[ROWS][COLS], int row2, int col2); 
//游戲主體
void game(char mine[ROWS][COLS], int row1, int col1, char show[ROWS][COLS], int row2, int col2); 
//打印雷陣
void InitBoard(char arr[ROWS][COLS], int row, int col); 
//埋雷子
void SetMine(char mine[ROWS][COLS], int row, int col); 
//找雷子
int FindMine(char mine[ROWS][COLS], int row1, int col1, char show[ROWS][COLS], int row2, int col2); 
//空白算法
void Find(char mine[ROWS][COLS], int row1, int col1, char show[ROWS][COLS], int row2, int col2,int x, int y,int exam[ROWS][COLS]); 
#endif//__GAME_H__

下面是主函數(shù)內(nèi)容

#include"game.h"
int main()
{
 char mine[ROWS][COLS];
 char show[ROWS][COLS];
 srand ((unsigned int)time(NULL)); //生成隨機數(shù),用于隨機埋雷
 int i = 0, j = 0;
 test(mine, ROWS, COLS, show, ROWS, COLS); //測試函數(shù)
 system("pause");
 return 0;
}

3.詳細實現(xiàn)

菜單函數(shù)

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

這個函數(shù)是用來打印信息的,打印一個簡單的菜單。

執(zhí)行菜單

void test(char mine[ROWS][COLS], int row1, int col1,char show[ROWS][COLS],int row2,int col2)
{
 int m = 0;
 do
 {
 menu();
 scanf_s("%d", &m);
 switch (m)
 {
 case 1:
 game(mine, row1, col1, show, row2, col2);
 break;
 case 0:
 exit(0);
 default:
 printf("輸入錯誤!\n");
 }
 } while (m);
}

這個函數(shù)是用來執(zhí)行用戶選項的。1.進行游戲 0.退出游戲。

游戲主體函數(shù)

void game(char mine[ROWS][COLS], int row1, int col1, char show[ROWS][COLS], int row2, int col2)
{
 int i = 0, j = 0;
 int flag = 0;
 int count = 0;
 for (i = 0; i < row1; i++)
 {
 for (j = 0; j < col1; j++)
 {
 mine[i][j] = '0';
 }
 }
 for (i = 0; i < row2; i++)
 {
 for (j = 0; j < col2; j++)
 {
 show[i][j] = '*';
 }
 }
 SetMine(mine, row1, col1);
 while (1)
 {
 InitBoard(mine, row1 - 1, col1 - 1);
 printf("------------------------\n");
 InitBoard(show, row2 - 1, col2 - 1);
 flag = FindMine(mine, row1, col1, show, row2, col2);
 if (flag == 0)
 {
 printf("恭喜你,你被炸死了!\n");
 InitBoard(mine, row1 - 1, col1 - 1);
 break;
 }
 else if (flag == 1 )
 {
 for (i = 1; i < row2 - 1; i++)
 {
 for (j = 1; j < col2 - 1; j++)
 {
 if (show[i][j] == '*')
 {
 count++;
 }
 }
 }
 printf("count == %d\n", count);
 if (count == MineNum)
 {
 printf("很遺憾,游戲結(jié)束\n");
 break;
 }
 else
 {
 count = 0;
 }
 }
 }
}

這個函數(shù)是游戲的主體部分。在一開始定義了一個標志變量flag和一個計數(shù)變量count。之后,使用了兩個兩個for循環(huán)對二維數(shù)組進行了初始化,mine被初始化為全'0',show被初始化了全'*'。然后,使用了SetMine()函數(shù)對mine進行了埋雷活動。最后使用個一個while死循環(huán),開始進行掃雷游戲。

在while循環(huán)里首先是兩個InitBoard()函數(shù)對mine和show進行打印。

FindMine函數(shù)是掃雷函數(shù)。它會返回一個值,如果被雷炸死了,他會返回0,如果點開區(qū)域沒有觸發(fā)雷的話,它會返回1。

接下來如果flag==1時,開始進行掃描,看看show中還剩下幾個星號,如果剩下10個星號,那么就證明掃完了,此時打印獲勝信息,并break跳出循環(huán)。如果沒有剩下10個星號,那么將已有的count信息清除,繼續(xù)進行以上步驟。

打印面板函數(shù)

void InitBoard(char arr[ROWS][COLS], int row, int col)
{
 int i = 0;
 int j = 0;
 for (i = 0; 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 ", arr[i][j]);
 }
 printf("\n");
 }
}

這是一個簡單的打印函數(shù),show和mine都可以公共使用。第一個for循環(huán)打印的是列坐標。第二個for循環(huán)中,第一個printf函數(shù)打印的是行坐標。

埋雷函數(shù)

void SetMine(char mine[ROWS][COLS], int row, int col)
{
 int m = 0, n = 0;
 int count = 0;
 while (count < MineNum)
 {
 m = rand() % 9 + 1;
 n = rand() % 9 + 1;
 if (mine[m][n] == '0')
 {
 mine[m][n] = '1';
 count++;
 }
 }
}

這是一個埋雷函數(shù)。埋雷需要用到隨機數(shù),我使用m和n來存放隨機數(shù)。while循環(huán)的終止條件是埋雷數(shù) count 達到預(yù)設(shè)雷數(shù) MineNum 。rand()%9+1是為了產(chǎn)生1~9的隨機數(shù)。if語句保證設(shè)雷地區(qū)不重復(fù)。

掃雷函數(shù)

int FindMine(char mine[ROWS][COLS], int row1, int col1, char show[ROWS][COLS], int row2, int col2)
{
 int m = 0, n = 0;
 int flag = 0;
 static int fflag = 0;
 int a1 = 0, a2 = 0;
 int exam[ROWS][COLS] = { 0 };
 while (1)
 {
 scanf_s("%d %d", &m, &n);
 if ((m >= 1 && m <= 9) && (n >= 1 && n <= 9))
 {
 break;
 }
 else
 {
 printf("輸錯了吧?\n");
 }
 }
 if (mine[m][n] == '0')
 {
 Find(mine, row1, col1, show, row2, col2, m, n, exam);
 flag = 1;
 }
 if (mine[m][n] == '1' && fflag > 0)
 {
 flag = 0;
 }
 if (mine[m][n] == '1' && fflag == 0)
 {
 mine[m][n] = '0';
 a1 = m;
 a2 = n;
 while (1)
 {
 m = rand() % 9 + 1;
 n = rand() % 9 + 1;
 if (mine[m][n] == '0'&& m != a1 && n != a2)
 {
 mine[m][n] = '1';
 flag = 1;
 break;
 }
 }
 fflag = 1;
 }
 return flag;
}

這是一個掃雷函數(shù)。m和n是用來保存位置,flag 是標志變量,fflag也是踩雷標志變量。a1和a2是暫存m和n的位置的。exam是一個標志數(shù)組,它將在Find函數(shù)發(fā)揮作用。

第一個while死循環(huán)它的作用是確保輸入正確的坐標信息。在確保輸入的m和n的數(shù)據(jù)是正確的后。開始處理數(shù)據(jù),第一個if語句,如果第一下沒有踩雷,那么將執(zhí)行Find空白的算法,結(jié)果是產(chǎn)生周圍雷數(shù)。第二個if語句中,如果不是第一下踩雷,那么將會反饋爆炸信息flag == 0。第三個if語句中,如果第一下踩雷了,那么將這顆雷移動到別的地方去。

移動的方法是將踩雷地點先用a1和a2記錄下來,然后生成隨機數(shù),該隨機數(shù)必須在 無雷 并且 不同于 m和n的坐標的地方。

空白算法函數(shù)

void Find(char mine[ROWS][COLS], int row1, int col1, char show[ROWS][COLS], int row2, int col2, int x, int y,int exam[ROWS][COLS])
{
 int count = 0;

 if (x <= 0 || y <= 0 || x >= row1-1||y >= col1-1)
 {
 return;
 }
 count = 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] - 8 * '0';
 show[x][y] = '0' + count;

 if (show[x][y] == '0' && exam[x][y] == 0)
 {
 if (show[x][y] == '0')
 {
 exam[x][y] = 1;
 }
 Find(mine, row1, col1, show, row2, col2, x - 1, y - 1,exam);
 Find(mine, row1, col1, show, row2, col2, x - 1, y, exam);
 Find(mine, row1, col1, show, row2, col2, x - 1, y + 1, exam);
 Find(mine, row1, col1, show, row2, col2, x , y - 1, exam);
 Find(mine, row1, col1, show, row2, col2, x , y + 1, exam);
 Find(mine, row1, col1, show, row2, col2, x + 1, y - 1, exam);
 Find(mine, row1, col1, show, row2, col2, x + 1, y, exam);
 Find(mine, row1, col1, show, row2, col2, x + 1, y + 1, exam);
 }
 else
 {
 return;
 }
}

這個函數(shù)是用來實現(xiàn)空白算法的。具體效果類似下圖。

從圖中可以發(fā)現(xiàn),點開一個空白產(chǎn)生了連鎖效果。

在Find函數(shù)中第一個if判斷條件,是看看有沒有觸底或者觸頂,如果有,那么將返回到上個函數(shù)中去。
接下來count是為了計算該點周圍的雷數(shù)量。如下圖:

當計算好后,將計算的數(shù)據(jù)填入到show中。由于'0'+數(shù)字 = ‘數(shù)字',相當于把整形的count轉(zhuǎn)成了char填入到 show。

然后使用遞歸算法。

假設(shè)我們首先點開了棕色區(qū)域中心點,那么接下來 從x-1,y-1以順時針方向開始探索。此時我們進入到第一個if中,檢查條件,exam該點默認為0,表示我們沒有操作過它。

接下來將該點exam相對應(yīng)的地方改成1。然后進入第一個Find()探索,也就是x - 1, y - 1。由于該點是‘ 1 ',所以return,返回到上層。此時按次序執(zhí)行第二個Find(),也就是 x - 1, y。由于該點是‘ 0 ',所以以這個點為中心,進行探索(以紅色為標記的九宮格)。探索前將這個點的標記位改為‘ 1 ',表示我們已經(jīng)進行了該點的探索。以該點 為 x,y,它的x-1, y-1是' 0 ‘,所以以黃色九宮格探索。以此類推直到觸頂、觸底停止,或者是周圍有不為 ‘ 0 '的數(shù)字停止。

這里為了防止兩個九宮格相互循環(huán),所以添加了exam標志位。當子九宮格再次探索到上個函數(shù)‘ 0 '時,發(fā)現(xiàn)其對應(yīng)的exam標志為1,不跳越至上個函數(shù)‘ 0 '繼續(xù)進行探索或返回。

4.程序運行效果

開局踩一顆雷,沒事;再踩一顆雷死了。

點開一大片空白。

游戲初始化面

游戲勝利!

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論