C語言實(shí)現(xiàn)簡易的掃雷小游戲
這是一個(gè)用C語言實(shí)現(xiàn)的控制臺(tái)掃雷小游戲,實(shí)現(xiàn)了隨機(jī)布置炸彈、掃描炸彈、標(biāo)記炸彈、百分百第一次不被炸死等功能。
編譯器:vs2015
功能模塊圖
源代碼
#include<stdio.h> #include<stdlib.h> #include<time.h> void show(int cbd[10][10],int u[10][10]) ?//界面輸出函數(shù) { ? ? int i, j; ? ? //for (i = 0; i < 10; i++) ?//輸出全部炸彈信息(上帝視角,調(diào)試用) ? ? //{ ? ? // ?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"); //行標(biāo) ? ? printf(" ? ?--------------------\n"); ? ? for (i = 0; i<10; i++) ?//根據(jù)u數(shù)組和cbd數(shù)組的值選擇輸出 ? ? { ? ? ? ? ? ?//■:未掃描,□:周圍無炸彈,◇:炸彈標(biāo)記 ? ? ? ? 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) ?//掃描周圍炸彈數(shù)目 { ? ? int l, c,lmin,cmin, lmax, cmax, num = 0; ? ? l = lmin = (i - 1) >= 0 ? (i - 1) : 0; ?//計(jì)算行、列起點(diǎn) ? ? c = cmin = (j - 1) >= 0 ? (j - 1) : 0; ? ? lmax = ((i + 1) < 10 ? (i + 1) : 9); ?//計(jì)算行、列終點(diǎn) ? ? 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++; ?//炸彈計(jì)數(shù) ? ? ? ? } ? ? } ? ? return num; } void init(int cbd[10][10]) ? //cbd數(shù)組初始化(隨機(jī)布置炸彈并填充各個(gè)格子的數(shù)目) { ? ? int n = 10, l, c, i, j; ? ? srand(time(NULL)); ? ?//隨機(jī)數(shù)種子設(shè)置 ? ? for (i = 0; i< 10; i++) ? ? { ? ? ? ? for (j = 0; j< 10; j++) ? ? ? ? { ? ? ? ? ? ? cbd[i][j] = 0; ?//全0填充 ? ? ? ? } ? ? } ? ? while (n--) ? //隨機(jī)行列放置炸彈 ? ? { ? ? ? ? l = rand() % 10; ? ? ? ? c = rand() % 10; ? ? ? ? if (cbd[l][c] != -1)cbd[l][c] = -1; ? //炸彈重復(fù)處理 ? ? ? ? else n++; ? ? } ? ? for (i = 0; i< 10; i++) ? ? { ? ? ? ? for (j = 0; j< 10; j++) ? ? ? ? { ? ? ? ? ? ? if (cbd[i][j] != -1) ? ? ? ? ? ? { ? ? ? ? ? ? ? ? cbd[i][j] = find(cbd, i, j); //炸彈數(shù)目填充 ? ? ? ? ? ? } ? ? ? ? } ? ? } } void open(int cbd[10][10],int u[10][10], int i, int j) ?//周圍無炸彈時(shí)的展開函數(shù)(遞歸展開) { ? ? 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, u, i, j - 1); ? //左 ? ? ? ? if (i + 1 <= 9 && u[i + 1][j] != 1)open(cbd, u, i + 1, j); ?//下 ? ? ? ? if (j + 1 <= 9 && u[i][j + 1] != 1)open(cbd, u, i, j + 1); ?//右 ? ? } } int judge(int u[10][10]) //判斷游戲是否通關(guān) { ? ? 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]) ?//游戲失敗函數(shù) { ? ? 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("請(qǐng)大俠重新來過~\n"); } void menu(int cbd[10][10],int u[10][10]) ?//菜單函數(shù) { ? ? int chs,i,j; ? ? int boom = 10; ?//剩余炸彈數(shù) ? ? int num = 0; ? //步數(shù) ? ? while (1) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? ? ? { ? ? ? ? system("cls"); ? ? ? ? show(cbd,u); ? ? ? ? printf("還有%d個(gè)炸彈\n",boom); ? ? ? ? printf("1.掃描 ? ?2.標(biāo)記 ? ?3.取消標(biāo)記\n"); ? ? ? ? printf("請(qǐng)輸入選項(xiàng):>"); ? ? ? ? scanf("%d", &chs); ? ? ? ? if (chs > 3 || chs < 1) { ? ? ? ? ? ? printf("請(qǐng)輸入正確選項(xiàng)!\n"); ? ? ? ? ? ? system("pause"); ? ? ? ? ? ? continue; ? ? ? ? } ? ? ? ? printf("請(qǐng)輸入坐標(biāo):>"); ? ? ? ? scanf("%d %d", &i, &j); ? ? ? ? if (i < 1 || i>10) ? ? ? ? { ? ? ? ? ? ? printf("請(qǐng)輸入正確坐標(biāo)!\n"); ? ? ? ? ? ? system("pause"); ? ? ? ? ? ? continue; ? ? ? ? } ? ? ? ? i--; ?//輸入行列數(shù)處理(適用數(shù)組下標(biāo)) ? ? ? ? j--; ? ? ? ? if (chs == 1) ? ? ? ? { ? ? ? ? ? ? if (cbd[i][j] == -1) { ? ? ? ? ? ? ? ? if (num == 0) { //若第一步掃描到炸彈,就重新初始化棋盤 ? ? ? ? ? ? ? ? ? ? init(cbd); ? ? ? ? ? ? ? ? ? ? show(cbd, u); ? ? ? ? ? ? ? ? ? ? open(cbd, u, i, j); ? ? ? ? ? ? ? ? ? ? num++; ? ? ? ? ? ? ? ? ? ? continue; ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? else ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? ? fail(cbd, u); ?//否則游戲失敗,循環(huán)跳出 ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? ? ? if (u[i][j] == 1) ?//重復(fù)掃描時(shí)的處理 ? ? ? ? ? ? { ? ? ? ? ? ? ? ? printf("該位置已經(jīng)掃描過了!\n"); ? ? ? ? ? ? ? ? system("pause"); ? ? ? ? ? ? ? ? continue; ? ? ? ? ? ? } ? ? ? ? ? ? open(cbd, u, i, j); ? ? ? ? ? ? num++; ? ? ? ? } ? ? ? ? else if(chs == 2) ? ? ? ? { ? ? ? ? ? ? if (u[i][j] == 1) { ? ? ? ? ? ? ? ? printf("該位置已經(jīng)掃描過了!\n"); //只能標(biāo)記未掃描到的 ? ? ? ? ? ? ? ? system("pause"); ? ? ? ? ? ? ? ? continue; ? ? ? ? ? ? } ? ? ? ? ? ? u[i][j] = -1; ? ? ? ? ? ? boom --; ? ? ? ? ? ? ? ? ? ? } ? ? ? ? else if (chs == 3) ? ? ? ? { ? ? ? ? ? ? if (u[i][j] != -1) { ? ? ? ? ? ? ? ? printf("該位置沒有標(biāo)記!\n"); //只能取消標(biāo)記過的 ? ? ? ? ? ? ? ? system("pause"); ? ? ? ? ? ? ? ? continue; ? ? ? ? ? ? } ? ? ? ? ? ? u[i][j] = 0; ? ? ? ? ? ? boom++; ? ? ? ? } ? ? ? ? if (judge(u)) ?//判斷游戲是否通關(guān) ? ? ? ? { ? ? ? ? ? ? printf("Old Fe 666!\n"); //老鐵666!,循環(huán)跳出 ? ? ? ? ? ? break; ? ? ? ? } ? ? } } int main() { ? ? int cbd[10][10] = { 0 }; //保存炸彈信息的二維數(shù)組 ? ? int u[10][10] = { 0 }; ?//保存是否翻開信息的二維數(shù)組 ? ? init(cbd); ? //數(shù)組初始化 ? ? menu(cbd, u); ?//進(jìn)入菜單 ? ? return 0; }
Tips:在掃描到周圍無炸彈的格子時(shí),要將此格子周圍的部分依次打開,直到上下左右都出現(xiàn)炸彈數(shù)字為止,這里要用到遞歸的方法,我的順序?yàn)橐来芜f歸處理上、左、下、右的格子,這里順序可以任意。
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
基于一個(gè)簡單定長內(nèi)存池的實(shí)現(xiàn)方法詳解
本篇文章對(duì)一個(gè)簡單定長內(nèi)存池的實(shí)現(xiàn)方法進(jìn)行了詳細(xì)的分析介紹。需要的朋友參考下2013-05-05淺析結(jié)束程序函數(shù)exit, _exit,atexit的區(qū)別
在一個(gè)程序中最多可以用atexit()注冊(cè)32個(gè)處理函數(shù),這些處理函數(shù)的調(diào)用順序與其注冊(cè)的順序相反,也即最先注冊(cè)的最后調(diào)用,最后注冊(cè)的最先調(diào)用2013-09-09C++中圖片類型的識(shí)別與轉(zhuǎn)換詳解方法
本文簡單的介紹一下C++語言中如何識(shí)別圖片文件的類型,以及各圖片類型之間的轉(zhuǎn)換方法,并提供相關(guān)的源碼供大家參考,感興趣的朋友快來看看吧2021-11-11C語言數(shù)據(jù)結(jié)構(gòu)與算法之單鏈表
單鏈表是一種鏈?zhǔn)酱嫒〉臄?shù)據(jù)結(jié)構(gòu),用一組地址任意的存儲(chǔ)單元存放線性表中的數(shù)據(jù)元素。本文將為大家介紹C語言中單鏈表的基本概念與讀取數(shù)據(jù)元素,需要的可以參考一下2021-12-12深入C++浮點(diǎn)數(shù)無效值定義與判定的解決辦法
本篇文章是對(duì)C++中浮點(diǎn)數(shù)無效值定義與判定進(jìn)行了介紹,需要的朋友參考下2013-05-05C語言將數(shù)組中元素的數(shù)排序輸出的相關(guān)問題解決
這篇文章主要介紹了C語言將數(shù)組中元素的數(shù)排序輸出的相關(guān)問題解決,文中的題目是將元素連接起來排成一個(gè)數(shù)并要求出這類結(jié)果中數(shù)最小的一個(gè),需要的朋友可以參考下2016-03-03