使用C語言實現(xiàn)掃雷游戲
本文實例為大家分享了C語言實現(xiàn)掃雷游戲的具體代碼,供大家參考,具體內(nèi)容如下
一、游戲介紹
掃雷游戲是在一個指定的二維空間里,隨機布置雷,把不是雷的位置都找出來,在你點一個位置的時候它會顯示它周圍全部雷的個數(shù),根據(jù)這個線索去找 ,會更容易贏。
二、實現(xiàn)模塊
文件名 作用
clear_mine.h 三子棋的函數(shù)聲明,頭文件聲明等
clear_mine.c 三子棋函數(shù)接口的實現(xiàn)
main.c 三子棋函數(shù)測試功能
三、實現(xiàn)原理
1、用兩個2維數(shù)組保存掃雷信息,一個用來設(shè)置雷,另一個用來展示看不見的雷,并把周圍的雷的個數(shù)統(tǒng)計出來展示。
2、也就是當在排查雷輸入坐標的時候要使用這個兩個數(shù)組,這個坐標位置在設(shè)置雷的數(shù)組里面如果不是雷,就統(tǒng)計它周圍雷個數(shù)放在另一個數(shù)組里面進行顯示。直到我們排查排查 ROW乘COL-雷個數(shù)次,即可勝利
3、這里面最重要的怎樣在方格位置上是顯示個數(shù),用字符是最方便的,不是雷的初始化為字符0,是雷放字符置為1。當一個位置上不是雷把他周圍8個的字符加起來-去8*字符0就是有多少個雷的個數(shù)。再把雷的個數(shù)轉(zhuǎn)化為字符放在可視化數(shù)字里面顯示,只需要個數(shù)加上字符0即可。
四、實現(xiàn)邏輯
(一)、創(chuàng)建menu菜單函數(shù)
void menu() { ?? ?printf("########### ?1、游戲開始 ##########\n"); ?? ?printf("########### ?2、退出 ? ##############\n"); }
(二)、用switch語句去創(chuàng)建game游戲開始函數(shù)和退出功能
void game() { ?? ?//用2個棋盤即兩個2維數(shù)組,一個進行放雷另一個進行展示棋盤信息 ?? ?char mine[ROWS][COLS] = { 0 }; ?? ?char show[ROWS][COLS] = { 0 }; ?? ?Init(mine,ROWS,COLS,'0');//先把放雷的數(shù)組初始化為字符0 ?? ?Init(show,ROWS, COLS, '*');//再把棋盤信息初始化為字符* ?? ?set_mine(mine, ROW, COL );//放置雷 ?? ?show1(show, ROW, COL);//展示棋盤信息 ?? ?clear_mine(mine, show, ROW, COL);//排查雷 } int main() { ?? ?int insert = 0; ?? ?srand((unsigned int)time(NULL)); ?? ?do{ ?? ??? ?menu(); ?? ??? ?printf("請選擇:"); ?? ??? ?scanf("%d", &insert); ?? ??? ?switch (insert) ?? ??? ?{ ?? ??? ?case 1: ?? ??? ??? ?game(); ?? ??? ??? ?break; ?? ??? ?case 2: ?? ??? ??? ?printf("退出游戲"); ?? ??? ??? ?break; ?? ??? ?default: ?? ??? ??? ?printf("請重新輸入"); ?? ??? ??? ?break; ?? ??? ?} ?? ?} while (insert); }
(三)、在void game()函數(shù)里面創(chuàng)建上層調(diào)用框架
(1)、初始化棋盤并可視化棋盤
1、創(chuàng)建兩個數(shù)組一個mine數(shù)組,一個是show數(shù)組并初始化,把它們分別置為字符0和字符*。然后創(chuàng)建一個打印棋盤函數(shù)以便呈現(xiàn)我們眼前。我們先調(diào)用Init和show1函數(shù)來看一下打印效果。
2、需要注意的是我們用二維數(shù)組打印兩個棋盤,我們就是要打印9x9的棋盤?答案不是,因為我們在設(shè)計算法時需要統(tǒng)計坐標周圍8個方位的個數(shù),假如要統(tǒng)計邊界周圍雷的個數(shù),那么就會有數(shù)組越界的問題,那么我們就需要在9×9的基礎(chǔ)上加2,這些元素我們不打印,心里有數(shù)就行。
void Init(char a[][COLS], int rows, int cols, char set) { ?? ?int i = 0; ?? ?int j = 0; ?? ?for(i = 0; i < rows; i++) ?? ?{ ?? ??? ?for (j = 0; j < cols; j++) ?? ??? ?{ ?? ??? ??? ?a[i][j] = set; ?? ??? ?} ?? ?} } void show1(char a[][COLS], int row, int col) { ?? ?int i = 0; ?? ?int j = 0; ?? ?for (j = 0; j <col+1; j++) ?? ?{ ?? ??? ?printf("%d ", j); ?? ?} ?? ?printf("\n"); ?? ?for (i = 1; i < row+1; i++) ?? ?{ ?? ??? ?printf("%d ", i); ?? ??? ?for (j= 1; j <col+1; j++) ?? ??? ?{ ?? ??? ??? ?printf("%c ", a[i][j]); ?? ??? ?} ?? ??? ?printf("\n"); ?? ?} ; }
(2)、設(shè)置雷
這一步我門要去設(shè)置雷,就在剛剛我們初始化的mine數(shù)組里面去放隨機雷,這個雷我們可以指定大小 我們定義宏,以便可以方便改。當然我們要現(xiàn)在測試函數(shù)main里面設(shè)置一個隨機數(shù)生成器。然后再set_mine函數(shù)設(shè)置rand函數(shù)生成隨機坐標。我們雷置為字符1,以便我更好計算。如圖代碼:
void set_mine(char mine[][COLS], int row, int col) { ?? ?int i = 0; ?? ?int j = 0; ?? ?int x = 0; ?? ?int y = 0; ?? ?int count = mine_count;//雷的個數(shù) ?? ?while (count) ?? ?{ ?? ??? ?x = rand() % row + 1;//生成一到0的數(shù) ?? ??? ?y = rand() % col + 1; ?? ??? ?if (mine[x][y] == '0') ?? ??? ?{ ?? ??? ??? ?mine[x][y] = '1'; ?? ??? ??? ?count--; ?? ??? ?} ?? ?} ?? ??? ? }
(3)、展示棋盤信息
展示棋盤信息是剛才我們初始化的show函數(shù)里面 放的都是字符*,在這里就調(diào)用一次來開始玩游戲,進行第一次掃雷。
如圖效果:
(4)、排查雷
1、這一步是游戲的核心,進行排查雷,要輸入坐標就要先考慮它的合法性。
2、要要考慮他是否被排查過 也就是去重性。
3、在進行判斷這個坐標在mine數(shù)組里面是否是字符1,如果是游戲結(jié)束,反之則把他周圍的雷數(shù)統(tǒng)計出來給show數(shù)組,再調(diào)用show1來顯示。
4、最一步判斷排雷是否成功,只要排了ROW*COL-雷個數(shù)次,說明排雷成功。
void clear_mine(char ?mine[][COLS], char show[][COLS], int row, int col) { ?? ?int x = 0; ?? ?int y = 0; ?? ?int count = 0; ?? ?while (count = row*col - mine_count) ?? ?{ ?? ??? ?printf("請輸入坐標:"); ?? ??? ?scanf("%d %d", &x, &y); ?? ??? ?if (x >= 1&& x <= row && y >= 1 && y <= col) ?? ??? ?{ ?? ??? ??? ?if (show[x][y] == '*') ?? ??? ??? ?{ ?? ??? ??? ??? ?if (mine[x][y] != '1') ?? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ?int count1 = 0; ?? ??? ??? ??? ??? ?count1 = round_mineCount(mine, x, y); ?? ??? ??? ??? ??? ?show[x][y] = count1 + '0'; ?? ??? ??? ??? ??? ?show1(show, row, col); ?? ??? ??? ??? ??? ?count--; ?? ??? ??? ??? ?} ?? ??? ??? ??? ?else ?? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ?printf("踩到雷,游戲結(jié)束\n"); ?? ??? ??? ??? ??? ?show1(mine, row, col); ?? ??? ??? ??? ??? ?break; ?? ??? ??? ??? ?} ?? ??? ??? ?} ?? ??? ??? ?else ?? ??? ??? ?{ ?? ??? ??? ??? ?printf("已經(jīng)被排查\n"); ?? ??? ??? ?} ?? ??? ?} ?? ??? ?else ?? ??? ?{ ?? ??? ??? ?printf("坐標非法,請重新輸入\n"); ?? ??? ?} ?? ??? ?if (count == 0) ?? ??? ?{ ?? ??? ??? ?printf("排雷成功"); ?? ??? ??? ?show1(mine, row, col); ?? ??? ?} ?? ?} } //t統(tǒng)計雷的個數(shù),八個方向 int round_mineCount(char mine[][COLS],int x,int y) { ?? ?return ?( mine[x - 1][y] + mine[x + 1][y] + ?? ??? ?mine[x][y - 1] + mine[x][y + 1] + ?? ??? ?mine[x - 1][y - 1] + mine[x - 1][y + 1] ?? ??? ?+ mine[x + 1][y - 1] + mine[x + 1][y + 1]-8*'0'); }
五、全部代碼
main.c
#include"clear_mine.h" void menu() { ?? ?printf("########### ?1、游戲開始 ##########\n"); ?? ?printf("########### ?2、退出 ? ##############\n"); } void game() { ?? ?//用2個棋盤即兩個2維數(shù)組,一個進行放雷另一個進行展示棋盤信息 ?? ?char mine[ROWS][COLS] = { 0 }; ?? ?char show[ROWS][COLS] = { 0 }; ?? ?Init(mine,ROWS,COLS,'0');//先把放雷的數(shù)組初始化為字符0 ?? ?Init(show,ROWS, COLS, '*');//再把棋盤信息初始化為字符* ?? ?set_mine(mine, ROW, COL );//放置雷 ?? ?show1(show, ROW, COL);//展示棋盤信息 ?? ?clear_mine(mine, show, ROW, COL);//排查雷 } int main() { ?? ?int insert = 0; ?? ?srand((unsigned int)time(NULL)); ?? ?do{ ?? ??? ?menu(); ?? ??? ?printf("請選擇:"); ?? ??? ?scanf("%d", &insert); ?? ??? ?switch (insert) ?? ??? ?{ ?? ??? ?case 1: ?? ??? ??? ?game(); ?? ??? ??? ?break; ?? ??? ?case 2: ?? ??? ??? ?printf("退出游戲"); ?? ??? ??? ?break; ?? ??? ?default: ?? ??? ??? ?printf("請重新輸入"); ?? ??? ??? ?break; ?? ??? ?} ?? ?} while (insert); }
clear_mine.h
#pragma once #include<stdio.h> #include<stdlib.h> #include<time.h> #define ROW 9 #define COL 9 #define ROWS ROW+2 #define COLS COL+2 #define mine_count 10//設(shè)置雷的個數(shù) #define count2 row*col-Count void Init(char a[][COLS], int rows,int cols, char set);//初始化棋盤 void set_mine(char mine[][COLS], int row, int col);//設(shè)置雷 void show1(char a[][COLS], int row, int col);//展示棋盤信息 void clear_mine(char mine[][COLS], char show[][COLS], int row, int col);// 排查雷 int ?round_mineCount(char mine[][COLS], int row, int col);//統(tǒng)計一個位置周圍的雷的個數(shù)
clear_mine.c
#include"clear_mine.h" void Init(char a[][COLS], int rows, int cols, char set) { ?? ?int i = 0; ?? ?int j = 0; ?? ?for(i = 0; i < rows; i++) ?? ?{ ?? ??? ?for (j = 0; j < cols; j++) ?? ??? ?{ ?? ??? ??? ?a[i][j] = set; ?? ??? ?} ?? ?} } void show1(char a[][COLS], int row, int col) { ?? ?int i = 0; ?? ?int j = 0; ?? ?for (j = 0; j <col+1; j++) ?? ?{ ?? ??? ?printf("%d ", j); ?? ?} ?? ?printf("\n"); ?? ?for (i = 1; i < row+1; i++) ?? ?{ ?? ??? ?printf("%d ", i); ?? ??? ?for (j= 1; j <col+1; j++) ?? ??? ?{ ?? ??? ??? ?printf("%c ", a[i][j]); ?? ??? ?} ?? ??? ?printf("\n"); ?? ?} ; } void set_mine(char mine[][COLS], int row, int col) { ?? ?int i = 0; ?? ?int j = 0; ?? ?int x = 0; ?? ?int y = 0; ?? ?int count = mine_count; ?? ?while (count) ?? ?{ ?? ??? ?x = rand() % row + 1; ?? ??? ?y = rand() % col + 1; ?? ??? ?if (mine[x][y] == '0') ?? ??? ?{ ?? ??? ??? ?mine[x][y] = '1'; ?? ??? ??? ?count--; ?? ??? ?} ?? ?} ?? ??? ? } void clear_mine(char ?mine[][COLS], char show[][COLS], int row, int col) { ?? ?int x = 0; ?? ?int y = 0; ?? ?int count = 0; ?? ?while (count = row*col - mine_count) ?? ?{ ?? ??? ?printf("請輸入坐標:"); ?? ??? ?scanf("%d %d", &x, &y); ?? ??? ?if (x >= 1&& x <= row && y >= 1 && y <= col) ?? ??? ?{ ?? ??? ??? ?if (show[x][y] == '*') ?? ??? ??? ?{ ?? ??? ??? ??? ?if (mine[x][y] != '1') ?? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ?int count1 = 0; ?? ??? ??? ??? ??? ?count1 = round_mineCount(mine, x, y); ?? ??? ??? ??? ??? ?show[x][y] = count1 + '0'; ?? ??? ??? ??? ??? ?show1(show, row, col); ?? ??? ??? ??? ??? ?count--; ?? ??? ??? ??? ?} ?? ??? ??? ??? ?else ?? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ?printf("踩到雷,游戲結(jié)束\n"); ?? ??? ??? ??? ??? ?show1(mine, row, col); ?? ??? ??? ??? ??? ?break; ?? ??? ??? ??? ?} ?? ??? ??? ?} ?? ??? ??? ?else ?? ??? ??? ?{ ?? ??? ??? ??? ?printf("已經(jīng)被排查\n"); ?? ??? ??? ?} ?? ??? ?} ?? ??? ?else ?? ??? ?{ ?? ??? ??? ?printf("坐標非法,請重新輸入\n"); ?? ??? ?} ?? ??? ?if (count == 0) ?? ??? ?{ ?? ??? ??? ?printf("排雷成功"); ?? ??? ??? ?show1(mine, row, col); ?? ??? ?} ?? ?} } int round_mineCount(char mine[][COLS],int x,int y) { ?? ?return ?( mine[x - 1][y] + mine[x + 1][y] + ?? ??? ?mine[x][y - 1] + mine[x][y + 1] + ?? ??? ?mine[x - 1][y - 1] + mine[x - 1][y + 1] ?? ??? ?+ mine[x + 1][y - 1] + mine[x + 1][y + 1]-8*'0'); }
六、運行結(jié)果
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C語言調(diào)用攝像頭實現(xiàn)生成yuv未壓縮圖片
這篇文章主要為大家詳細介紹了C語言如何調(diào)用攝像頭實現(xiàn)生成yuv未壓縮圖片,文中的示例代碼講解詳細,具有一定的學習價值,感興趣的小伙伴可以參考一下2023-11-11VS2022實現(xiàn)VC++打包生成安裝文件圖文詳細歷程
本文主要介紹了VS2022實現(xiàn)VC++打包生成安裝文件圖文詳細歷程,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-02-02Qt如何設(shè)置窗口屏幕居中顯示以及設(shè)置大小
這篇文章主要介紹了Qt如何設(shè)置窗口屏幕居中顯示以及設(shè)置大小的相關(guān)資料,需要的朋友可以參考下2017-01-01OpenCV+Qt實現(xiàn)圖像處理操作工具的示例代碼
這篇文章主要介紹了利用OpenCV+Qt實現(xiàn)圖像處理操作工具,可以實現(xiàn)雪花屏、高斯模糊、中值濾波、毛玻璃等操作,感興趣的可以了解一下2022-08-08