文章目錄
- 前言
- 一、游戲規則介紹
- 二、基本思路流程介紹
- 三、代碼實作
- 1.用戶互動選單(Menu函式)
- 2. Game函式
- 3.放雷函式(SetMines函式)
- 4.掃雷展示面板(ShowBoard函式和ShowLine函式)
- 5.統計周圍雷的個數(CountMines函式)
- 6.mine函式
- 四、總代碼
前言
一、游戲規則介紹
掃雷是一個十分經典的游戲,一張棋盤中有很多個不確定是雷還是安全區域的格子,當點擊之后若沒有雷則會在該區域顯示周圍八個格子雷的數目,若有雷則游戲結束,今天我就跟大家分享一下如何用c語言實作初階版掃雷,
二、基本思路流程介紹
1.創建一個用戶互動選單
2.創建一個Show_Mines棋盤用來埋雷并初始化
3.創建一個Show_Table 棋盤用來和用戶互動并初始化
4.玩家選擇想要掃描的坐標
5.判定游戲是否結束
6.若沒有踩雷則在剛掃描的區域上顯示周圍八個區域的地雷數目并繼續游戲
7.繼續掃雷
8.判定游戲是否結束
…
9.若全部掃描完非雷區域則游戲結束
效果展示




三、代碼實作
1.用戶互動選單(Menu函式)
Menu(){
printf("########################\n");
printf("# 1. Play 0.Exit #\n");
printf("########################\n");
}
2. Game函式
void Game()
{
srand((unsigned long)time(NULL)); //生成亂數種子
char show_board[ROW][COL];
char mines_board[ROW][COL];
memset(show_board, WHAT, sizeof(show_board));//生成并且初始化用戶顯示棋盤
memset(mines_board, '0', sizeof(mines_board));//生成并且初始化掃雷棋盤
SetMines(mines_board, ROW, COL);//放雷
int count = (ROW - 2)*(COL - 2) - NUM; //若掃完這些次 不觸雷則勝利
while (count){
system("cls");
ShowBoard(show_board, ROW, COL);
printf("請選擇你要掃描的區域坐標 ");
int x = 0;
int y = 0;
scanf("%d %d", &x, &y);
if (x < 1 || x > ROW-2 || y < 1 || y > COL-2){ //非法性輸入判斷
printf("輸入錯誤!\n");
continue;
}
if (show_board[x][y] != WHAT){
printf("此處已經被掃過了,請從新輸出\n");
continue;
}
if (mines_board[x][y] == '1'){
system("cls");
ShowBoard(mines_board, ROW, COL);
printf("踩雷了!游戲結束!\n");
break;
}
show_board[x][y] = CountMines(mines_board, x, y);
count--;
}
}
1.memset函式直接定義show_board函式并且初始化二維陣列為全WHAT宏定義的*,
2.先向用戶展示用戶展示棋盤,用戶輸入一個坐標進行非法性判斷,
3.把用戶輸入的坐標拿給放置雷的棋盤中,若該區域有雷則游戲結束,反之則繼續
4.游戲勝利條件為掃描完所有非雷區域
3.放雷函式(SetMines函式)
void SetMines(char board[][COL], int row, int col){ //放雷函式
int count = NUM;
while (count){
int x = rand() % (row - 2) + 1;
int y = rand() % (col - 2) + 1;
if (board[x][y] == '0'){
board[x][y] = '1';
count--;
}
}
}
使用亂數種子生成1到 棋盤大小長寬-2的隨機數,這些隨機陣列成的坐標放雷,回圈次數就是雷的數目,因為亂數可能生成一樣的,所以要進行一次非法性判斷,當棋盤這個位置沒有雷的情況下才能往里面放雷,
4.掃雷展示面板(ShowBoard函式和ShowLine函式)
void ShowBoard(char board[][COL], int row, int col){//掃雷展示面板
printf(" ");
for (int i = 1; i <= (col - 2); i++){ //列印表頭數字
printf("%d ", i);
}
printf("\n");
ShowLine(col);//顯示行線
for (int i = 1; i <= (row - 2); i++){
printf("%-3d|", i);
for (int j = 1; j <= (col - 2); j++){
printf(" %c |", board[i][j]);
}
printf("\n");
ShowLine(col);
}
}
void ShowLine(int col){ //顯示橫著的虛線,作為行間隔
for (int i = 0; i <= (col - 2); i++){
printf("----");
}
printf("\n");
}
5.統計周圍雷的個數(CountMines函式)
CountMines(char board[][COL], int x, int y){ //統計周圍雷的個數
return board[x - 1][y - 1] + board[x - 1][y] + board[x - 1][y + 1] + \
board[x][y + 1] + board[x + 1][y + 1] + board[x + 1][y] + \
board[x + 1][y - 1] + board[x][y - 1] - 7 * '0';//本來減八個零,但是整形轉字符加一個‘0’
}
由于陣列中存放的是字符’0’,周圍是8個數字,所以-8*'0’才能回傳雷數的int值,為了把數字也能列印出來,所以+‘0’,否則列印的是數字作為的ASCLL碼的值,最終的結果為-7*‘0’.
6.mine函式
int main()
{
int quit = 0;
int select = 0;
while (!quit){
Menu();
printf("請輸入 ");
scanf("%d", &select);
switch (select){
case 1:
Game();
break;
case 0:
quit = 1;
break;
default:
printf("輸入錯誤,請重試!\n");
break;
}
}
printf("byebye!\n");
system("pause");
return 0;
}
四、總代碼
#ifndef __Test_H__
#define __Test_H__
#include<stdio.h>
#include<Windows.h>
#include <stdlib.h>
#include <time.h>
#define WHAT '*'
#define NUM 20
#define COL 10
#define ROW 10
void Game();
#pragma warning(disable:4996)
#endif //以上都是頭檔案
int main()
{
int quit = 0;
int select = 0;
while (!quit){
Menu();
printf("請輸入 ");
scanf("%d", &select);
switch (select){
case 1:
Game();
break;
case 0:
quit = 1;
break;
default:
printf("輸入錯誤,請重試!\n");
break;
}
}
printf("byebye!\n");
system("pause");
return 0;
}
void Game()
{
srand((unsigned long)time(NULL)); //生成亂數種子
char show_board[ROW][COL];
char mines_board[ROW][COL];
memset(show_board, WHAT, sizeof(show_board));
memset(mines_board, '0', sizeof(mines_board));
SetMines(mines_board, ROW, COL);
int count = (ROW - 2)*(COL - 2) - NUM; //若掃完這些次 不觸雷則勝利
while (count){
system("cls");
ShowBoard(show_board, ROW, COL);
printf("請選擇你要掃描的區域坐標 ");
int x = 0;
int y = 0;
scanf("%d %d", &x, &y);
if (x < 1 || x > ROW-2 || y < 1 || y > COL-2){ //非法性輸入判斷
printf("輸入錯誤!\n");
continue;
}
if (show_board[x][y] != WHAT){
printf("此處已經被掃過了,請從新輸出\n");
continue;
}
if (mines_board[x][y] == '1'){
system("cls");
ShowBoard(mines_board, ROW, COL);
printf("踩雷了!游戲結束!\n");
break;
}
show_board[x][y] = CountMines(mines_board, x, y);
count--;
}
}
CountMines(char board[][COL], int x, int y){ //統計周圍雷的個數
return board[x - 1][y - 1] + board[x - 1][y] + board[x - 1][y + 1] + \
board[x][y + 1] + board[x + 1][y + 1] + board[x + 1][y] + \
board[x + 1][y - 1] + board[x][y - 1] - 7 * '0';//本來減八個零,但是整形轉字符加一個‘0’
}
void ShowBoard(char board[][COL], int row, int col){//掃雷展示面板
printf(" ");
for (int i = 1; i <= (col - 2); i++){
printf("%d ", i);
}
printf("\n");
ShowLine(col);//顯示行線
for (int i = 1; i <= (row - 2); i++){
printf("%-3d|", i);
for (int j = 1; j <= (col - 2); j++){
printf(" %c |", board[i][j]);
}
printf("\n");
ShowLine(col);
}
}
oid SetMines(char board[][COL], int row, int col){ //放雷函式
int count = NUM;
while (count){
int x = rand() % (row - 2) + 1;
int y = rand() % (col - 2) + 1;
if (board[x][y] == '0'){
board[x][y] = '1';
count--;
}
}
}
void ShowLine(int col){
for (int i = 0; i <= (col - 2); i++){
printf("----");
}
printf("\n");
}
Menu(){ //用戶互動函式
printf("########################\n");
printf("# 1. Play 0.Exit #\n");
printf("########################\n");
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/286488.html
標籤:其他
上一篇:python模擬大話骰小游戲
下一篇:2021-06-08 購物車
