1. 程式人生 > >【18.7.25】掃雷c語言小遊戲,展開與防第一次炸死功能

【18.7.25】掃雷c語言小遊戲,展開與防第一次炸死功能

遞迴看了N遍終於寫出來了展開功能,心塞。
上效果圖
開啟程式碼,control+F5,走!

這裡寫圖片描述

輸入1開始遊戲

這裡寫圖片描述

密集恐懼症,心裡一萬隻草泥馬路過。。。
未開啟前都是‘*’號,玩家根據行標和列標輸入需要掃雷的位置

這裡寫圖片描述

就快要贏了,當然這個難度可能比較低,但是可以自行設定難度,我自己預設的是20*20的表格,20個大雷子。

Test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void menu()//設計選單
{
    printf("■■■■■■ 掃雷遊戲 ■■■■■■\n");
    printf
("■■■■■■■■■■■■■■■■■\n"); printf("■■■■■■■■■■■■■■■■■\n"); printf("■■■■■■1.開始遊戲■■■■■■\n"); printf("■■■■■■■■■■■■■■■■■\n"); printf("■■■■■■0.退出遊戲■■■■■■\n"); printf("■■■■■■■■■■■■■■■■■\n"); } void game()//遊戲函式 { int i = 0;//迴圈變數 int x = 0;//玩家輸入行標 int y = 0;//玩家輸入列標 char Hidemap[ROW][COL] = {0
};//開發者棋盤; char Showmap[ROW][COL] = {0};//玩家棋盤; srand((unsigned int)time(NULL));//增加隨機性; Initmap(Hidemap,Showmap,ROW,COL);//初始化棋盤; Devicemine(Hidemap,ROW,COL,Mine);//佈置地雷; Printmap(Showmap,ROW,COL);//列印玩家棋盤; for(i=0;i<((ROW-2)*(COL-2)-Mine);i++)//迴圈做多迴圈表格裡除了地雷數的所有地方,但也可提前跳出 { printf
("請輸入需要開啟的座標:"); scanf("%d%d",&x,&y); if(x>=1&&x<=ROW&&y>=1&&y<=COL) { if(i==0) { Savepleyer(Hidemap,ROW,COL,x,y);//增加玩家遊戲體驗,防止第一次就炸死 } if(Open(Hidemap,Showmap,x,y))//開啟座標,如果不是雷繼續,是雷就執行else。 { ; } else { break; } if(Countshowmine(Showmap,ROW,COL)==Mine)//判定條件,全部雷被找出,玩家就贏了 { printf("恭喜玩家獲勝/n"); break; } Printmap(Showmap,ROW,COL); } else { printf("對不起,您的輸入有誤,請重新輸\n"); } } } void test() { int input = 0; do { menu();//列印選單; printf("請輸入指令:"); scanf("%d",&input); switch(input)//玩家是否開始遊戲 { case 0://推出遊戲 printf("即將退出遊戲\n"); Sleep(2000); system("cls"); break; case 1://開始遊戲 printf("遊戲即將開始\n"); Sleep(2000); system("cls"); game();//進入遊戲函式 break; default : printf("輸入錯誤,請您重新輸入\n"); break; } } while(input); } int main()//主函式入口進入 { test(); return 0; }
這裡注意,建立陣列是一個是開發者,顯示的是雷的佈局,為玩家棋盤服務的陣列。
比如我們玩10*10的表格,但是要建立12*12的表格,原因是如果玩家探索邊緣的地方,在統計的時候,統計周圍八個地區,就會存在陣列的越界,但是我們如果多建立2行2列,但是雷都佈置到內10行10列中,就可以避免這個問題。列印同樣也只打印內10行10列。

Game.c

遊戲核心檔案

#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void Initmap(char Hidemap[ROW][COL],char Showmap[ROW][COL],int row,int col)//初始化兩個陣列
{
    memset(Hidemap,'0',row*col*sizeof(Hidemap[0][0]));//開發者棋盤初始化全0
    memset(Showmap,'*',row*col*sizeof(Showmap[0][0]));//玩家棋盤未掃區域為*
}
void Devicemine(char Hidemap[ROW][COL],int row,int col,int mine)
{
    int x = 0;
    int y = 0;
    while(mine)
    {
        x = rand() % (row-2);//產生0-row的餘數
        y = rand() % (col-2);//產生0-col的餘數
        if(Hidemap[x+1][y+1] == '0')//僅在1-(row-1)區域內佈雷
        {
            Hidemap[x+1][y+1] = '1';//僅在1-(col-1)區域內佈雷
            mine--;
        }
    }

}
int Countmine(char Hidemap[ROW][COL],int x,int y)//記雷數函式
{
    int count = 0;
    if(Hidemap[x-1][y-1] == '1')//統計周圍八個地區的雷數
    {
        count++;
    }
    if(Hidemap[x-1][y] == '1')
    {
        count++;
    }
    if(Hidemap[x-1][y+1] == '1')
    {
        count++;
    }
    if(Hidemap[x][y-1] == '1')
    {
        count++;
    }
    if(Hidemap[x][y+1] == '1')
    {       
        count++;   
    }
    if(Hidemap[x+1][y-1] == '1')
    {
        count++;
    }
    if(Hidemap[x+1][y] == '1')
    {
        count++;
    }
    if(Hidemap[x+1][y+1] == '1')
    {
        count++;
    }
    return count;//返回周圍雷的個數
}

int Open(char Hidemap[ROW][COL],char Showmap[ROW][COL],int x,int y)//開啟需要排查地方
{
    if(Showmap[x][y]=='*')
    {
        if(Hidemap[x][y]=='0')
        {
            if(Countmine(Hidemap,x,y)!=0)//如果周圍有雷,就正常顯示周圍雷的個數
            {
                Showmap[x][y] =Countmine(Hidemap,x,y)+'0';
            }
            else
            {
                Unfoldmap(Hidemap,Showmap,x,y);//如果周圍沒雷就得展開這個區域
            }
        }
        else
        {
            printf("你踩到雷了!\n");
            return 0;
        }
    }
    return 1;
}





void Printmap(char arr[ROW][COL],int row,int col)
{

        int i = 0;
        int j = 0;
        printf(" 0 ");
        for(i=1;i<=(col-2);i++)//列印列標
        {
            printf("%   3d ",i);
        }
        printf("\n");
        printf("  ┏");//列印裝飾表格
        for(j=0;j<col-3;j++)
        {
            printf("━┳");
        }
        printf("━┓\n");
        for(i=1;i<=(row-2);i++)
        {
            printf("%2d┃",i);//列印行標
            for(j=1;j<=(col-2);j++)
            {
                printf(" %c",arr[i][j]);
                printf("┃");
            }
            printf("\n");
            if(i<row-2)
            {
                printf("  ┣");
                for(j=0;j<col-3;j++)
                {
                    printf("━╋");
                }
                printf("━┫\n");
            }
        }
        printf("  ┗");
        for(j=0;j<col-3;j++)
        {
            printf("━┻");
        }
        printf("━┛\n");
}
void Savepleyer(char Hidemap[ROW][COL],int row,int col,int x,int y)
{
    int ret = 1;
    if(Hidemap[x][y]=='1')
    {
        Hidemap[x][y] = '0';
        while(ret)
        {
            x = rand() % row;
            y = rand() % col;
            if(Hidemap[x+1][y+1] == '0')
            {
                Hidemap[x+1][y+1] = '1';
                ret--;
            }
        }
    }
}
void Unfoldmap(char Hidemap[ROW][COL],char Showmap[ROW][COL],int x,int y) 
{
    Showmap[x][y] = ' ';//周圍沒雷,直接顯示空格,並且自動開啟周圍的幾個區域
    Open(Hidemap,Showmap,(x+1),(y+1));
    Open(Hidemap,Showmap,(x+1),(y-1));
    Open(Hidemap,Showmap,(x+1),(y));
    Open(Hidemap,Showmap,(x),(y+1));
    Open(Hidemap,Showmap,(x),(y-1));
    Open(Hidemap,Showmap,(x-1),(y+1));
    Open(Hidemap,Showmap,(x-1),(y-1));
    Open(Hidemap,Showmap,(x-1),(y));
}
int Countshowmine(char Showmap[ROW][COL],int row,int col)//判斷剩餘未知區域的個數,個數為雷數時玩家贏
{
    int count = 0;
    int i = 0;
    int j = 0;
    for(i=1;i<=(row-2);i++)
    {
        for(j=1;j<=(col-2);j++)
        {
            if (Showmap[i][j] == '*')
            {
                count++;
            }
        }

    }
    return count;
}
注意這裡的傳參問題。

Game.h標頭檔案

#ifndef __GAME_H__
#define __GAME_H__


#define ROW 22
#define COL 22
#define Mine 20

#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#include<time.h>


void Initmap(char Hidemap[ROW][COL], char Showmap[ROW][COL], int row, int col);
void Devicemine(char Hidemap[ROW][COL], int row, int col, int mine);
int Countmine(char Hidemap[ROW][COL], int x, int y);
int Open(char Hidemap[ROW][COL], char Showmap[ROW][COL], int x, int y);
void Printmap(char arr[ROW][COL], int row, int col);
void Savepleyer(char Hidemap[ROW][COL], int row, int col, int x, int y);
void Unfoldmap(char Hidemap[ROW][COL], char Showmap[ROW][COL], int x, int y);
int Countshowmine(char Showmap[ROW][COL], int row, int col);

#endif //__GAME_H__
整個程式就完了,掃雷是一個不錯的練手題,難度有,但是對於我們這種初學者來說,完全可以解決。