C語言掃雷遊戲的實現程式碼
阿新 • • 發佈:2020-03-17
這是一個用C語言實現的控制檯掃雷小遊戲,實現了隨機佈置炸彈、掃描炸彈、標記炸彈、百分百第一次不被炸死等功能。
編譯器:vs2015
功能模組圖
原始碼
#include<stdio.h> #include<stdlib.h> #include<time.h> void show(int cbd[10][10],int u[10][10]) //介面輸出函式 { int i,j; //for (i = 0; i < 10; i++) //輸出全部炸彈資訊(上帝視角,除錯用) //{ // for (j = 0; j < 10; j++) // { // printf("%2d ",cbd[i][j]); // } // printf("\n"); //} printf(" 1 2 3 4 5 6 7 8 9 10\n"); //行標 printf(" --------------------\n"); for (i = 0; i<10; i++) //根據u陣列和cbd陣列的值選擇輸出 { //■:未掃描,□:周圍無炸彈,◇:炸彈標記 for (j = 0; j<10; j++) { if (j == 0)printf("%2d║ ",i+1); if (u[i][j] == 0)printf("■"); else if (u[i][j] == 1) { if (cbd[i][j] == 0)printf("□"); else printf("%2d",cbd[i][j]); } else if (u[i][j] == -1) { printf("◇"); } } printf("\n"); } } int find(int cbd[10][10],int i,int j) //掃描周圍炸彈數目 { int l,c,lmin,cmin,lmax,cmax,num = 0; l = lmin = (i - 1) >= 0 ? (i - 1) : 0; //計算行、列起點 c = cmin = (j - 1) >= 0 ? (j - 1) : 0; lmax = ((i + 1) < 10 ? (i + 1) : 9); //計算行、列終點 cmax = ((j + 1) < 10 ? (j + 1) : 9); for (l = lmin; l <= lmax; l++) { for (c = cmin; c <= cmax; c++) { if (l == i&&c == j)continue; //跳過自身 if (cbd[l][c] == -1)num++; //炸彈計數 } } return num; } void init(int cbd[10][10]) //cbd陣列初始化(隨機佈置炸彈並填充各個格子的數目) { int n = 10,l,i,j; srand(time(NULL)); //隨機數種子設定 for (i = 0; i< 10; i++) { for (j = 0; j< 10; j++) { cbd[i][j] = 0; //全0填充 } } while (n--) //隨機行列放置炸彈 { l = rand() % 10; c = rand() % 10; if (cbd[l][c] != -1)cbd[l][c] = -1; //炸彈重複處理 else n++; } for (i = 0; i< 10; i++) { for (j = 0; j< 10; j++) { if (cbd[i][j] != -1) { cbd[i][j] = find(cbd,j); //炸彈數目填充 } } } } void open(int cbd[10][10],int u[10][10],int j) //周圍無炸彈時的展開函式(遞迴展開) { u[i][j] = 1; if (cbd[i][j] == 0) { if(i - 1 >= 0 && u[i - 1][j] != 1)open(cbd,u,i - 1,j); //上 if(j - 1 >= 0 && u[i][j - 1] != 1)open(cbd,j - 1); //左 if (i + 1 <= 9 && u[i + 1][j] != 1)open(cbd,i + 1,j); //下 if (j + 1 <= 9 && u[i][j + 1] != 1)open(cbd,j + 1); //右 } } int judge(int u[10][10]) //判斷遊戲是否通關 { int i,j,num = 0; for (i = 0; i < 10; i++) { for (j = 0; j < 10; j++) { if (u[i][j] == 0 || u[i][j] == -1)num++; } } if (num == 10)return 1; else return 0; } void fail(int cbd[10][10],int u[10][10]) //遊戲失敗函式 { int i,j; for (i = 0; i < 10; i++) //輸出全部炸彈資訊 { for (j = 0; j < 10; j++) { if (cbd[i][j] == 0)printf(" "); else if (cbd[i][j] != -1)printf("%2d",cbd[i][j]); else printf("●"); } printf("\n"); } printf("請大俠重新來過~\n"); } void menu(int cbd[10][10],int u[10][10]) //選單函式 { int chs,j; int boom = 10; //剩餘炸彈數 int num = 0; //步數 while (1) { system("cls"); show(cbd,u); printf("還有%d個炸彈\n",boom); printf("1.掃描 2.標記 3.取消標記\n"); printf("請輸入選項:>"); scanf("%d",&chs); if (chs > 3 || chs < 1) { printf("請輸入正確選項!\n"); system("pause"); continue; } printf("請輸入座標:>"); scanf("%d %d",&i,&j); if (i < 1 || i>10) { printf("請輸入正確座標!\n"); system("pause"); continue; } i--; //輸入行列數處理(適用陣列下標) j--; if (chs == 1) { if (cbd[i][j] == -1) { if (num == 0) { //若第一步掃描到炸彈,就重新初始化棋盤 init(cbd); show(cbd,u); open(cbd,j); num++; continue; } else { fail(cbd,u); //否則遊戲失敗,迴圈跳出 break; } } if (u[i][j] == 1) //重複掃描時的處理 { printf("該位置已經掃描過了!\n"); system("pause"); continue; } open(cbd,j); num++; } else if(chs == 2) { if (u[i][j] == 1) { printf("該位置已經掃描過了!\n"); //只能標記未掃描到的 system("pause"); continue; } u[i][j] = -1; boom --; } else if (chs == 3) { if (u[i][j] != -1) { printf("該位置沒有標記!\n"); //只能取消標記過的 system("pause"); continue; } u[i][j] = 0; boom++; } if (judge(u)) //判斷遊戲是否通關 { printf("Old Fe 666!\n"); //老鐵666!,迴圈跳出 break; } } } int main() { int cbd[10][10] = { 0 }; //儲存炸彈資訊的二維陣列 int u[10][10] = { 0 }; //儲存是否翻開資訊的二維陣列 init(cbd); //陣列初始化 menu(cbd,u); //進入選單 return 0; }
Tips:在掃描到周圍無炸彈的格子時,要將此格子周圍的部分依次開啟,直到上下左右都出現炸彈數字為止,這裡要用到遞迴的方法,我的順序為依次遞迴處理上、左、下、右的格子,這裡順序可以任意。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。