C語言實(shí)現(xiàn)掃雷小游戲(擴(kuò)展版)
本文實(shí)例為大家分享了C語言實(shí)現(xiàn)掃雷小游戲的具體代碼,供大家參考,具體內(nèi)容如下
實(shí)現(xiàn)的拓展功能如下:
1.設(shè)置游戲難度等級
2.保證玩家在第一把踩雷后不被炸死
3.若排雷的地方無雷,自動(dòng)擴(kuò)展到有雷的周圍,并給出雷數(shù)
4.標(biāo)記(相當(dāng)于掃雷游戲中的插旗子)
5.取消標(biāo)記
分析:
1.用二維字符數(shù)組mine[ROWS][COLS]來存儲(chǔ)雷,現(xiàn)在我們用字符1來表示有雷,字符0表示無雷。用二維字符數(shù)組show[ROWS][COLS]將所有的元素初始化為*,并打印作為展現(xiàn)給玩家的。同時(shí)用show數(shù)組來表示對應(yīng)的mine數(shù)組中周圍雷即字符0的個(gè)數(shù)。
對于邊緣的格子無法計(jì)算雷的個(gè)數(shù),因此需再增加2行2列,防止數(shù)組越界。
2.游戲難度等級的設(shè)置即就是雷的個(gè)數(shù)和棋盤大小不同,即就是Putmine中傳的COUNT(雷數(shù))不同,棋盤大小不同也就是在初始化、埋雷、掃雷、打印棋盤等函數(shù)中傳的行、列數(shù)不同,由于是控制臺(tái)程序,沒有將一般模式和困難模式的棋盤打印的過大(因?yàn)闀?huì)丑,也容易眼花),正常情況下掃雷的中級模式是40個(gè)雷,16*16格,高級模式是99個(gè)雷,16*30格.
3.為了保證玩家體驗(yàn),保證玩家在第一把踩雷后不被炸死,此時(shí)只需要判斷玩家第一次排查的坐標(biāo)是否等于雷的坐標(biāo),如果是,將雷悄悄移走(重新生成隨機(jī)數(shù))
4.若排雷的地方無雷,自動(dòng)擴(kuò)展到有雷的周圍,并給出雷數(shù),此時(shí)需要用到遞歸,直至遞歸到周圍有雷停止,并計(jì)算雷數(shù),顯示在棋盤上。
5.標(biāo)記與取消標(biāo)記這個(gè)是很容易實(shí)現(xiàn)的,將標(biāo)記位置改為P(也可以為其他),取消標(biāo)記改回*即可。
實(shí)現(xiàn)效果:
詳細(xì)代碼如下:
test.c
/* date:2018/12/27 author:Better Me1 program:Mine Clearance compiler:Visual Studio 2013 拓展功能: 1.設(shè)置游戲難度等級 2.保證玩家在第一把踩雷后不被炸死 3.若排雷的地方無雷,自動(dòng)擴(kuò)展到有雷的周圍,并給出雷數(shù) 4.標(biāo)記(相當(dāng)于掃雷游戲中的插旗子) 5.取消標(biāo)記 */ ? /*測試部分*/ #define _CRT_SECURE_NO_WARNINGS 1 #include "game.h" #include <stdio.h> #include <stdlib.h> ? void menu(){ ?? ?printf("************ ?掃雷小游戲 ?************\n"); ?? ?printf("****** ?1.進(jìn)入游戲 ?2.退出游戲 ?******\n"); ?? ?printf("**************************************\n"); } void menu2(){ ?? ?printf("******** ?請選擇要挑戰(zhàn)的模式 ?********\n"); ?? ?printf("******** ?1.簡單模式(10個(gè)雷)********\n"); ?? ?printf("******** ?2.一般模式(15個(gè)雷)********\n"); ?? ?printf("******** ?3.困難模式(20個(gè)雷)********\n"); } void game(int COUNT ){ ?? ?if (COUNT == 10){ ?? ??? ?char mine[ROWS][COLS] = { 0 }; ?? ??? ?char show[ROWS][COLS] = { 0 };//顯示雷,給玩家看 ?? ??? ?InitBoard(mine, ROWS, COLS, '0'); ?? ??? ?InitBoard(show, ROWS, COLS, '*');//初始化棋盤 ?? ??? ?Putmine(mine, ROW-6, COL-6, COUNT);//埋雷 ?? ??? ?//DisplayBoard(mine, ROW - 6, COL - 6); ?? ??? ?DisplayBoard(show, ROW-6, COL-6);//打印棋盤 ?? ??? ?Findmine(mine, show, ROW-6, COL-6, COUNT);//掃雷 ?? ?} ?? ?else if (COUNT == 15){ ?? ??? ?char mine[ROWS][COLS] = { 0 }; ?? ??? ?char show[ROWS][COLS] = { 0 };//顯示雷,給玩家看 ?? ??? ?InitBoard(mine, ROWS, COLS, '0'); ?? ??? ?InitBoard(show, ROWS, COLS, '*');//初始化棋盤 ?? ??? ?Putmine(mine, ROW - 2, COL - 2, COUNT);//埋雷 ?? ??? ?//DisplayBoard(mine, ROW - 2, COL - 2); ?? ??? ?DisplayBoard(show, ROW - 2, COL - 2);//打印棋盤 ?? ??? ?Findmine(mine, show, ROW - 2, COL - 2, COUNT);//掃雷 ?? ?} ?? ?else{ ?? ??? ?char mine[ROWS][COLS] = { 0 }; ?? ??? ?char show[ROWS][COLS] = { 0 };//顯示雷,給玩家看 ?? ??? ?InitBoard(mine, ROWS, COLS, '0'); ?? ??? ?InitBoard(show, ROWS, COLS, '*');//初始化棋盤 ?? ??? ?Putmine(mine, ROW, COL, COUNT);//埋雷 ?? ??? ?//DisplayBoard(mine, ROW, COL); ?? ??? ?DisplayBoard(show, ROW, COL);//打印棋盤 ?? ??? ?Findmine(mine, show, ROW , COL, COUNT);//掃雷 ?? ?} } void test(){ ?? ?srand((unsigned int)time(0));//隨機(jī)種子 ?? ?int input = 0; ?? ?int input2 = 0; ?? ?int COUNT = 0; ?? ?do{ ?? ??? ?menu(); ?? ??? ?printf("請選擇:>"); ?? ??? ?scanf("%d", &input); ?? ??? ?system("cls"); ?? ??? ?switch (input){ ?? ??? ?case 1: ?? ??? ??? ?while (1){ ?? ??? ??? ??? ?menu2(); ?? ??? ??? ??? ?printf("請選擇:>"); ?? ??? ??? ??? ?scanf("%d", &input2); ?? ??? ??? ??? ?switch (input2){ ?? ??? ??? ??? ?case 1: ?? ??? ??? ??? ??? ?COUNT = EASY_COUNT; ?? ??? ??? ??? ??? ?break; ?? ??? ??? ??? ?case 2: ?? ??? ??? ??? ??? ?COUNT = USUAL_COUNT; ?? ??? ??? ??? ??? ?break; ?? ??? ??? ??? ?case 3: ?? ??? ??? ??? ??? ?COUNT = HARD_COUNT; ?? ??? ??? ??? ??? ?break; ?? ??? ??? ??? ?default: ?? ??? ??? ??? ??? ?printf("輸入有誤,請重新選擇!\n"); ?? ??? ??? ??? ??? ?break; ?? ??? ??? ??? ?} ?? ??? ??? ??? ?if (input2 >= 1 && input2 <= 3){ ?? ??? ??? ??? ??? ?break; ?? ??? ??? ??? ?} ?? ??? ??? ?} ?? ??? ??? ?system("cls"); ?? ??? ??? ?game(COUNT); ?? ??? ??? ?break; ?? ??? ?case 2: ?? ??? ??? ?printf("退出游戲!\n"); ?? ??? ??? ?break; ?? ??? ?default: ?? ??? ??? ?printf("輸入有誤,請重新選擇!\n"); ?? ??? ??? ?break; ?? ??? ?} ?? ?} while ((input - 2)); } void main(){ ?? ?test(); ?? ?system("pause"); }
game.h
#ifndef _GAME_H_ #define _GAME_H ? #define EASY_COUNT 10 //簡單級,10個(gè)雷 #define USUAL_COUNT 15 //普通級,15個(gè)雷 #define HARD_COUNT 20 //單級,20個(gè)雷 ? ? #define ROW 15//行 #define COL 15 //列 ? #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 Putmine(char board[ROWS][COLS], int row, int col, int count);//埋雷 void Findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col,int count);//掃雷 ? #endif
game.c
#define _CRT_SECURE_NO_WARNINGS 1 #include "game.h" #include <string.h> #include <stdio.h> #include <stdlib.h> #include <Windows.h> ? void InitBoard(char board[ROWS][COLS], int rows, int cols, char set){ ?? ?memset(board, set, rows*cols*sizeof(board[0][0])); } void DisplayBoard(char board[ROWS][COLS], int row, int col){ ?? ?int i, j = 0; ?? ?if (row == ROW - 6){ ?? ??? ?printf("------------------------------\n"); ?? ?} ?? ?if (row == ROW - 2){ ?? ??? ?printf("-----------------------------------------\n"); ?? ?} ?? ?if (row == ROW){ ?? ??? ?printf("----------------------------------------------\n"); ?? ?} ?? ?for (i = 0; i <= row; i++){ ?? ??? ?for (j = 0; j <= col; j++){ ?? ??? ??? ?if (i == 0 || j == 0){ ?? ??? ??? ??? ?if (j == 0){ ?? ??? ??? ??? ??? ?if (i < 10){ ?? ??? ??? ??? ??? ??? ?printf("%d ?", i); ?? ??? ??? ??? ??? ?} ?? ??? ??? ??? ??? ?else{ ?? ??? ??? ??? ??? ??? ?printf("%d ", i); ?? ??? ??? ??? ??? ?} ?? ??? ??? ??? ?} ?? ??? ??? ??? ?else{ ?? ??? ??? ??? ??? ?if (j < 10){ ?? ??? ??? ??? ??? ??? ?printf("%d ?", j); ?? ??? ??? ??? ??? ?} ?? ??? ??? ??? ??? ?else{ ?? ??? ??? ??? ??? ??? ?printf("%d ", j); ?? ??? ??? ??? ??? ?} ?? ??? ??? ??? ?} ?? ??? ??? ?} ?? ??? ??? ?else{ ?? ??? ??? ??? ?printf("%c ?", board[i][j]); ?? ??? ??? ?} ?? ??? ?} ?? ??? ?printf("\n"); ?? ?} ?? ?if (row == ROW - 6){ ?? ??? ?printf("------------------------------\n"); ?? ?} ?? ?if (row == ROW - 2){ ?? ??? ?printf("-----------------------------------------\n"); ?? ?} ?? ?if (row == ROW){ ?? ??? ?printf("----------------------------------------------\n"); ?? ?} } void Putmine(char board[ROWS][COLS], int row, int col, int count){ ?? ?int c = 0;//埋好的雷的個(gè)數(shù) ?? ?int i = 0; ?? ?int j = 0; ?? ?do{ ?? ??? ?i = rand() % row + 1; ?? ??? ?j = rand() % col + 1; ?? ??? ?if (board[i][j] =='0'){//保證雷的個(gè)數(shù)為 count個(gè) ?? ??? ??? ?board[i][j] = '1'; ?? ??? ??? ?c++; ?? ??? ?}?? ? ?? ?} while (count-c); } /*統(tǒng)計(jì)雷的個(gè)數(shù)*/ int MineCount(char mine[ROWS][COLS], int i, int j){ ?? ?return (mine[i - 1][j] + ?? ??? ?mine[i - 1][j + 1] + ?? ??? ?mine[i][j + 1] + ?? ??? ?mine[i + 1][j + 1] + ?? ??? ?mine[i + 1][j] + ?? ??? ?mine[i + 1][j - 1] + ?? ??? ?mine[i][j - 1] + ?? ??? ?mine[i - 1][j - 1]) - 8 * '0'; } void ExpansionMine(char mine[ROWS][COLS], char show[ROWS][COLS], int i, int j, int row, int col){ ?? ?if (MineCount(mine, i, j) == 0){ ?? ??? ?show[i][j] = ' '; ?? ??? ?//再次遍歷周圍的雷 ?? ??? ?if (i - 1 > 0 && show[i - 1][j] == '*'){ ?? ??? ?//?? ?printf("1\n"); ?? ??? ??? ?ExpansionMine(mine, show, i - 1, j, row, col);//遞歸 ?? ??? ?} ?? ??? ?if (i - 1 > 0 && j + 1 <= col && show[i - 1][j + 1] == '*'){ ?? ??? ??? ?ExpansionMine(mine, show, i - 1, j + 1, row, col); ?? ??? ?} ?? ??? ?if (j + 1 <= col && show[i][j + 1] == '*'){ ?? ??? ??? ?ExpansionMine(mine, show, i, j + 1, row, col); ?? ??? ?} ?? ??? ?if (i + 1 <= row && j + 1 <= col && show[i + 1][j + 1] == '*'){ ?? ??? ??? ?ExpansionMine(mine, show, i + 1, j + 1, row, col); ?? ??? ?} ?? ??? ?if (i + 1 <= row && show[i + 1][j] == '*'){ ?? ??? ??? ?ExpansionMine(mine, show, i + 1, j, row, col); ?? ??? ?} ?? ??? ?if (i + 1 <= row && j - 1 >0 && show[i + 1][j - 1] == '*'){ ?? ??? ??? ?ExpansionMine(mine, show, i + 1, j - 1, row, col); ?? ??? ?} ?? ??? ?if (j - 1 > 0 && show[i][j - 1] == '*'){ ?? ??? ??? ?ExpansionMine(mine, show, i, j - 1, row, col); ?? ??? ?} ?? ??? ?if (i - 1 > 0 && j - 1 > 0 && show[i - 1][j + 1] == '*'){ ?? ??? ??? ?ExpansionMine(mine, show, i - 1, j + 1, row, col); ?? ??? ?} ?? ?} ?? ?else{//周邊有雷 ?? ??? ?show[i][j] = MineCount(mine, i, j) + '0'; ?? ?} } void menu3(){ ?? ?printf("******** ? 1.標(biāo)記 ? ?2.排查 ? ********\n"); ?? ?printf("請選擇:>"); } void Findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int count){ ?? ?int i, j;//行列坐標(biāo) ?? ?int playcount = 0;//玩家排雷的次數(shù) ?? ?int remine = 0;//已標(biāo)記的或沒有排查的坐標(biāo); ?? ?while (remine!=count){ ?? ??? ?//printf("%d", remine); ?? ??? ?int input = 0; ?? ??? ?printf("***** 1.標(biāo)記 ?2.取消標(biāo)記 ?3.排查 *****\n"); ?? ??? ?printf("請選擇:>"); ?? ??? ?scanf("%d", &input); ?? ??? ?if (input == 1){ ?? ??? ??? ?printf("請輸入要標(biāo)記的坐標(biāo)(如:a b):>"); ?? ??? ??? ?scanf("%d %d", &i, &j); ?? ??? ??? ?if (i >= 1 && i <= row && j >= 1 && j <= col){ ?? ??? ??? ??? ?if (show[i][j] == '*'){ ?? ??? ??? ??? ??? ?show[i][j] = 'P'; ?? ??? ??? ??? ??? ?system("cls"); ?? ??? ??? ??? ??? ?DisplayBoard(show, row, col); ?? ??? ??? ??? ?} ?? ??? ??? ??? ?else if (show[i][j] == 'P'){ ?? ??? ??? ??? ??? ?printf("此坐標(biāo)已被標(biāo)記過,請重新輸入!\n"); ?? ??? ??? ??? ?} ?? ??? ??? ??? ?else{ ?? ??? ??? ??? ??? ?printf("此坐標(biāo)已被排查過,請重新輸入!\n"); ?? ??? ??? ??? ?} ?? ??? ??? ?} ? ?? ??? ??? ?else{ ?? ??? ??? ??? ?printf("坐標(biāo)輸入有誤,請重新輸入!\n"); ?? ??? ??? ?} ?? ??? ?} ?? ??? ?else if (input == 2){ ?? ??? ??? ?printf("請輸入要取消標(biāo)記的坐標(biāo)(如:a b):>"); ?? ??? ??? ?scanf("%d %d", &i, &j); ?? ??? ??? ?if (i >= 1 && i <= row && j >= 1 && j <= col){ ?? ??? ??? ??? ?if (show[i][j] == 'P'){ ?? ??? ??? ??? ??? ?show[i][j] = '*'; ?? ??? ??? ??? ??? ?system("cls"); ?? ??? ??? ??? ??? ?DisplayBoard(show, row, col); ?? ??? ??? ??? ?} ?? ??? ??? ??? ?else if (show[i][j] == '*'){ ?? ??? ??? ??? ??? ?printf("此坐標(biāo)還沒有被標(biāo)記過,請重新輸入!\n"); ?? ??? ??? ??? ?} ?? ??? ??? ??? ?else{ ?? ??? ??? ??? ??? ?printf("此坐標(biāo)已被排查過,請重新輸入!\n"); ?? ??? ??? ??? ?} ?? ??? ??? ?} ? ?? ??? ??? ?else{ ?? ??? ??? ??? ?printf("坐標(biāo)輸入有誤,請重新輸入!\n"); ?? ??? ??? ?} ?? ??? ?} ?? ??? ?else if (input == 3){ ?? ??? ??? ?//printf("%d", remine); ?? ??? ??? ?printf("請輸入要排查的坐標(biāo)(如:a b):>"); ?? ??? ??? ?scanf("%d%d", &i, &j); ?? ??? ??? ?if (i >= 1 && i <= row && j >= 1 && j <= col){ ?? ??? ??? ??? ?if (show[i][j] == '*'){ ?? ??? ??? ??? ??? ?if (mine[i][j] == '1'){ ?? ??? ??? ??? ??? ??? ?if (playcount == 0){//此時(shí)說明玩家首次排雷且踩到雷了 ?? ??? ??? ??? ??? ??? ??? ?mine[i][j] = '0'; ?? ??? ??? ??? ??? ??? ??? ?Putmine(mine, row, col, 1);//重新放雷,保證玩家在第一把不踩雷 ?? ??? ??? ??? ??? ??? ??? ?playcount = 1; ?? ??? ??? ??? ??? ??? ??? ?ExpansionMine(mine, show, i, j, row, col);//擴(kuò)展周邊的雷 ?? ??? ??? ??? ??? ??? ??? ?DisplayBoard(show, row, col); ?? ??? ??? ??? ??? ??? ?} ?? ??? ??? ??? ??? ??? ?else{ ?? ??? ??? ??? ??? ??? ??? ?printf("很遺憾,你被炸死了!\n"); ?? ??? ??? ??? ??? ??? ??? ?printf("雷陣布局如下:\n"); ?? ??? ??? ??? ??? ??? ??? ?DisplayBoard(mine, row, col); ?? ??? ??? ??? ??? ??? ??? ?break; ?? ??? ??? ??? ??? ??? ?} ?? ??? ??? ??? ??? ?} ?? ??? ??? ??? ??? ?else{ ?? ??? ??? ??? ??? ??? ?ExpansionMine(mine, show, i, j, row, col);//擴(kuò)展周邊的雷 ?? ??? ??? ??? ??? ??? ?system("cls"); ?? ??? ??? ??? ??? ??? ?//DisplayBoard(mine, row, col); ?? ??? ??? ??? ??? ??? ?DisplayBoard(show, row, col); ?? ??? ??? ??? ??? ??? ?playcount = 1; ?? ??? ??? ??? ??? ?} ?? ??? ??? ??? ?} ?? ??? ??? ??? ?else if (show[i][j] == 'P'){ ?? ??? ??? ??? ??? ?printf("此坐標(biāo)已被標(biāo)記過,請重新輸入!\n"); ?? ??? ??? ??? ?} ?? ??? ??? ??? ?else{ ?? ??? ??? ??? ??? ?printf("此坐標(biāo)已被排查過,請重新輸入!\n"); ?? ??? ??? ??? ?} ?? ??? ??? ?} ?? ??? ??? ?else{ ?? ??? ??? ??? ?printf("坐標(biāo)輸入有誤,請重新輸入!\n"); ?? ??? ??? ?} ?? ??? ?} ?? ??? ?else{ ?? ??? ??? ?printf("輸入有誤,請重新輸入!\n"); ?? ??? ?} ?? ??? ?remine = 0;//重新統(tǒng)計(jì); ?? ??? ?for (int m = 1; m <= row; m++){ ?? ??? ??? ?for (int n = 1; n <= col; n++){ ?? ??? ??? ??? ?if ((show[m][n] == '*' )||( show[m][n] == 'P')){ ?? ??? ??? ??? ??? ?remine++; ?? ??? ??? ??? ?} ?? ??? ??? ?} ?? ??? ?} ?? ?} ?? ?//printf("%d", remine); ?? ?if (remine == count){ ?? ??? ?printf("恭喜您,排雷成功!\n"); ?? ??? ?printf("雷陣布局如下:\n"); ?? ??? ?DisplayBoard(mine, row, col); ?? ?} ? }
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C++實(shí)現(xiàn)校園運(yùn)動(dòng)會(huì)報(bào)名系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)校園運(yùn)動(dòng)會(huì)報(bào)名系統(tǒng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-10-10