利用C語言實現簡易版掃雷
我和我的父親都是掃雷的狂熱粉,小時候我常常因為技術不好而被父親嘲笑,那麼今天我要來做一個簡易版掃雷,回頭也給他玩一玩。
首先我們要構建好雷盤的樣子,我們理所當然想到利用二維數組。那麼請註意:因為我們每一次隨機生成的雷盤不能展示給用戶,所以顯示盤與雷盤要分開,那麼我們在這裡要用到兩個二維數組。一個是雷盤,用來記錄隨機生成雷的佈局,另一個是顯示盤,初始化全為*,讓用戶來掃雷。
具體功能:
- 先由電腦隨機生成雷的分佈。
- 玩傢通過輸入坐標來選擇點。
- 玩傢選擇對應點後,對應點將顯示周圍雷的個數(以該點為中心的一個九宮格)。
- 玩傢需要根據這個個數,自己推斷出有雷的地方,不能輸入有雷的對應坐標,隻能輸入沒雷的對應坐標。
- 當輸入坐標對應點有雷時,炸“死”,遊戲結束。當剩下未選中的點的個數等於總共佈下的雷的個數時,遊戲勝利。
實現功能的函數:
1.菜單函數,必不可少,是展示給用戶的第一界面,這個比較簡陋,後期可以考慮做一些fashion一點的。
void Menu() { printf("##########################\n"); printf("#####choose 1 to play#####\n"); printf("#####choose 0 to exit#####\n"); printf("Please input your select here:>\n"); }
2.隨機生成雷函數,那麼對應雷的橫豎坐標就是需要隨機生成的數。如果大傢看過我之前的三子棋就知道,在這裡關於隨機生成用到瞭函數GetIndex,算是一個小優化。
void SetMine(char mine_board[][COL], int row, int col) { srand((unsigned long)time(NULL)); int mine_num = MINES; while (mine_num) { int i_index = GetIndex(1,col-2);//生成1~10的隨機數 int j_index = GetIndex(1,col-2); if (mine_board[i_index][j_index] == '0') { mine_board[i_index][j_index] = '1'; mine_num--; } } }
3.GetIndex函數,這裡要註意start和end表示的是生成的隨機數的范圍。之前我們 如果用rand生成0~10的隨機數,就直接rand%10,但是如果是5 ~10呢?所以我們用(end-start+1)得到的是0 ~end的范圍,再加一個start,就能到到start ~end的范圍。
static int GetIndex(int start, int end)//static修飾 代表該函數隻能在本文件內部使用 { return rand() % (end - start + 1) + start; }
4.得到一個點周圍雷的數量函數,這裡要註意,我寫的這個函數的返回值是整型,但得到的mine_board的和是字符型,那麼要通過8-‘0’來轉換一下。
int GetMineNum(char mine_board[][COL], int i, int j) { return mine_board[i-1][j-1]+mine_board[i-1][j]+ mine_board[i-1][j+1]+ \ mine_board[i][j-1]+ mine_board[i][j+1]+ \ mine_board[i+1][j-1]+mine_board[i+1][j]+ mine_board[i+1][j+1]-8*'0';//整型 }
5.顯示雷盤函數
void ShowBoard(char show_board[][COL], int row, int col) { int i = 0; int j = 0; printf(" "); for (i = 1; i <= col-2; i++) { printf("%d ", i); } printf("\n"); for (i = 1; i <= col - 1; i++) { printf("----"); } printf("\n"); for (i = 1; i <=row - 2; i++) { printf("%-2d|", i); for (j = 1; j <=col - 2; j++) { printf(" %c |", show_board[i][j]); } printf("\n"); int k = 1; for (k = 1; k <= col - 1; k++) { printf("----"); } printf("\n"); } }
6.進行遊戲函數,以total作為一個衡量標準。輸入坐標,判斷是否為雷的位置,是則遊戲結束,不是則總的方塊數減1,繼續輸入坐標。
void PlayGame(char show_board[][COL], char mine_board[][COL], int row, int col) { int i = 0; int j = 0; int total = (ROW - 2)*(COL - 2); while (1) { ShowBoard(show_board, row, col); printf("Please enter your pos<x,y>"); scanf("%d%d", &i, &j); if (i >= 1 && i < row - 2 && j >= 1 && j < col - 2) { if (mine_board[i][j] == '0') { int num = GetMineNum(mine_board, i, j); show_board[i][j] = num + '0'; total--; } else { ShowBoard(mine_board, row, col); printf("Game over!you lose!:(\n"); break; } } else { printf("Error!Try again!\n"); continue; } if (total == MINES) { printf("You win:)!\n"); break; } } }
7.Game函數,初始化兩個盤,主要調用瞭前面的函數,對函數的一個整合,來貫穿一下整個流程。
void Game() { char show_board[ROW][COL]; char mine_board[ROW][COL]; memset(show_board, '*', sizeof(show_board)); memset(mine_board, '0', sizeof(mine_board)); SetMine(mine_board, ROW, COL); PlayGame(show_board, mine_board, ROW, COL); }
這裡還是采用瞭文件的形式,分為函數聲明,函數定義,主函數。
函數聲明 Mine.h
#ifndef _MINE_H_ #define _MINE_H_ #include<stdio.h> #include<stdlib.h> #include<string.h> #include<time.h> #define ROW 12 #define COL 12 #define MINES 20 void Menu(); void Game(); int GetIndex(int start, int end); void SetMine(char mine_board[][COL], int row, int col); int GetMineNum(char mine_board[][COL], int i, int j); void ShowBoard(char show_board[][COL], int row, int col); void PlayGame(char show_board[][COL], char mine_board[][COL], int row, int col); #endif
函數定義 Mine.c
#include"Mine.h" void Menu() { printf("##########################\n"); printf("#####choose 1 to play#####\n"); printf("#####choose 0 to exit#####\n"); printf("Please input your select here:>\n"); } static int GetIndex(int start, int end)//static修飾 代表該函數隻能在本文件內部使用 { return rand() % (end - start + 1) + start; } //隨機生成雷 void SetMine(char mine_board[][COL], int row, int col) { srand((unsigned long)time(NULL)); int mine_num = MINES; while (mine_num) { int i_index = GetIndex(1,col-2); int j_index = GetIndex(1,col-2); if (mine_board[i_index][j_index] == '0') { mine_board[i_index][j_index] = '1'; mine_num--; } } } //得到一個點周圍雷的數量 int GetMineNum(char mine_board[][COL], int i, int j) { return mine_board[i-1][j-1]+mine_board[i-1][j]+ mine_board[i-1][j+1]+ \ mine_board[i][j-1]+ mine_board[i][j+1]+ \ mine_board[i+1][j-1]+mine_board[i+1][j]+ mine_board[i+1][j+1]-8*'0';//整型 } //顯示雷盤 void ShowBoard(char show_board[][COL], int row, int col) { int i = 0; int j = 0; printf(" "); for (i = 1; i <= col-2; i++) { printf("%d ", i); } printf("\n"); for (i = 1; i <= col - 1; i++) { printf("----"); } printf("\n"); for (i = 1; i <=row - 2; i++) { printf("%-2d|", i); for (j = 1; j <=col - 2; j++) { printf(" %c |", show_board[i][j]); } printf("\n"); int k = 1; for (k = 1; k <= col - 1; k++) { printf("----"); } printf("\n"); } } void PlayGame(char show_board[][COL], char mine_board[][COL], int row, int col) { int i = 0; int j = 0; int total = (ROW - 2)*(COL - 2); while (1) { ShowBoard(show_board, row, col); printf("Please enter your pos<x,y>"); scanf("%d%d", &i, &j); if (i >= 1 && i < row - 2 && j >= 1 && j < col - 2) { if (mine_board[i][j] == '0') { int num = GetMineNum(mine_board, i, j); show_board[i][j] = num + '0'; total--; } else { ShowBoard(mine_board, row, col); printf("Game over!you lose!:(\n"); break; } } else { printf("Error!Try again!\n"); continue; } if (total == MINES) { printf("You win:)!\n"); break; } } } void Game() { char show_board[ROW][COL]; char mine_board[ROW][COL]; memset(show_board, '*', sizeof(show_board)); memset(mine_board, '0', sizeof(mine_board)); SetMine(mine_board, ROW, COL); PlayGame(show_board, mine_board, ROW, COL); }
主函數 main.c
#include"Mine.h" int main() { int select = 0; int quit = 0; while (!quit) { Menu(); scanf("%d", &select); switch (select) { case 1: Game(); break; case 0: printf("OK,byebye!\n"); quit = 1; break; default: printf("Error!input again!\n"); break; } } system("pause"); return 0; }
運行展示界面:
這是簡易版的掃雷,過過幹癮還是可以,但和電腦裡的掃雷還是有一定的差別,後期還要做一些優化。
以上就是本文的全部內容,希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。