1. 程式人生 > >掃雷思想及主函數

掃雷思想及主函數

arr 菜鳥 是否 ase endif 直接 %d test isp

1.建雷盤(9*9雷盤)

2.初始化雷盤,雷盤1每個位置初始化為字符0,雷盤2每個位置初始化為字符*。

3.為了檢驗,輸出我們初始化好的雷盤。

4.向棋盤放雷,這塊我們可以以雷數設計難度。擺雷是以隨機數放入的,下面會附上代碼,詳見代碼

5.掃雷。

詳細說明一下掃雷的思想:

5.1.先定義int win = 0(用來判斷結束的條件)當我們向控制臺輸入坐標後,先判斷輸入坐標是否合法,不合法繼續執行5.1,合法執行5.2。

5.2.判斷輸入坐標是否是雷?如果是雷,直接輸出“菜鳥,你踩雷了”,否則,執行5.3。

5.3.統計該位置周圍八個的雷數,如果雷數不為0,將雷數轉換成字符賦給該位置,否則執行5.4。

5.4.將上述坐標的周圍八個坐標放入一個二維數組,遞歸判斷,將周圍不是雷全部置空,周圍有雷的置為雷數(字符型)操作完之後執行5.5(詳見下面代碼)

5.5一遍輸入後輸出本次雷盤1,以便下次輸入,執行5.6

5.6標記雷數,(我們用字符m表示該位置有雷)標記一次輸出一次雷盤1,執行5.7(詳見下面代碼)

5.7轉到5.1繼續執行,結束條件就是(雷盤上m和*的個數之和小於等於雷數並且win == 9 *9 - 雷數),然後輸出挑戰成功

test.c

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include "game.h"
#include <time.h>
#include <stdlib.h>
void game(){
    char set1 = 
0; char set2 = *; //棋盤 char Mine[Rows][Cols] = { 0 }; //新建棋盤 char Show[Rows][Cols] = { 0 }; //初始化棋盤 Init(Mine, Rows, Cols,set1); Init(Show, Rows, Cols,set2); //展示 Display(Mine, Row, Col); Display(Show, Row, Col); //放雷 printf("請選擇難度:>\n"); printf("1.簡單——10\n
"); printf("2.一般——20\n"); printf("3.困難——30\n"); int input = 0; int countMine = 0; scanf("%d", &input); switch (input){ case 1: countMine = EASY_COUNT; PutMine(Mine, Row, Col, countMine); //檢查Mine printf("檢查\n"); ShowMine(Mine, Row, Col); //掃雷 ClearMine(Mine,Show, Row, Col, countMine); break; case 2: countMine = GENERAL_COUNT; PutMine(Mine, Row, Col, countMine); //檢查Mine printf("檢查\n"); ShowMine(Mine, Row, Col); //掃雷 ClearMine(Mine, Show, Row, Col, countMine); break; case 3: countMine = HARD_COUNT; PutMine(Mine, Row, Col, countMine); //檢查Mine printf("檢查\n"); ShowMine(Mine, Row, Col); //掃雷 ClearMine(Mine, Show, Row, Col, countMine); break; default: printf("請重新輸入:>"); } } void menu(){ printf("1..開始遊戲\n"); printf("0..結束\n"); } void test(){ int input = 1; while (input){ printf("請選擇:\n"); menu(); scanf("%d", &input); switch (input){ case 1: game(); break; case 0: break; default: printf("請重新輸入"); break; } } } int main(){ srand((unsigned int)time(0)); test(); system("pause"); return 0; }

game.c

#define _CRT_SECURE_NO_WARNINGS
#include "game.h"
#include<string.h>
#include <time.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
//初始化
void Init(char arr[Rows][Cols], int rows, int cols,char set){
    int i = 0;
    int j = 0;
    for (i = 0; i < rows; i++){
        for (j = 0; j < cols; j++){
            arr[i][j] = set;
        }
    }
    printf("----------------------------\n");

}
//展示
void Display(char arr[Rows][Cols], int row, int col){
    int i = 0;
    int j = 0;
    for (int k = 0; k <= col; k++){
        printf("%d ", k);
    }
    printf("\n");
    for (i = 1; i <= row; i++){
        printf("%d ", i);
        for (j = 1; j <= col; j++){
            printf("%c ", arr[i][j]);
        }
        printf("\n");
    }
    printf("----------------------------\n");
}
//擺雷
void PutMine(char mine[Rows][Cols], int row, int col,int count){
    int x = 0;
    int y = 0;
    while (count >0 ){
        x = rand() % row + 1;
        y = rand() % col + 1;
        if (mine[x][y] == 0)
        {
            mine[x][y] = 1 + 0;
            count--;
        }
    }
}
//檢查
void ShowMine(char arr[Rows][Cols], int row, int col){
    int i = 0;
    int j = 0;
    for (int k = 0; k <= Col; k++){
        printf("%d ", k);
    }
    printf("\n");
    for (i = 1; i <= row; i++){
        printf("%d ", i);
        for (j = 1; j <= col; j++){
            printf("%c ", arr[i][j]);
        }
        printf("\n");
    }
}

//獲取x,y 坐標周圍八個格子的雷數
int getMine(char mine[Rows][Cols], int x, int y){

    return mine[x - 1][y] +
        mine[x - 1][y - 1] +
        mine[x][y - 1] +
        mine[x + 1][y - 1] +
        mine[x + 1][y] +
        mine[x + 1][y + 1] +
        mine[x][y + 1] +
        mine[x - 1][y + 1] - 8 * 0;
    
}


void OtherIsHaveMine(char mine[Rows][Cols], char show[Rows][Cols], int arr[8][2], int row, int col){
    for (int i = 0; i <8; i++){
        int x = arr[i][0];
        int y = arr[i][1];
        if (x>0 && x <= row&&y > 0 && y <= col&&(show[x][y] == *)){
            if (getMine(mine, x, y) == 0){
                show[x][y] =  ;
                int ch[8][2] = { x - 1, y, x - 1, y - 1,
                    x, y - 1, x + 1, y - 1,
                    x + 1, y, x + 1, y + 1,
                    x, y + 1, x - 1, y + 1 };
                OtherIsHaveMine(mine, show, ch, row, col);
            }
            else{
                show[x][y] = getMine(mine, x, y) + 0;
            }
        }
    }
}
//是否要標記雷:   1代表標記雷(用字符m表示有雷)    0代表不標記繼續掃雷
void SignMine(char show[Rows][Cols], int row, int col){
    int input = 1;
    int x = 0;
    int y = 0;
    while (input){
        printf("是否標記雷\n");
        printf("1.標記\n");
        printf("0.不標記\n");
        scanf("%d", &input);
        switch (input){
            case 0:
                printf("繼續掃雷:\n");
                break;
            case 1:
                while (1){
                    printf("請輸入有雷的坐標:>\n");
                    scanf("%d", &x);
                    scanf("%d", &y);
                    if ((x > 0 && x <= row) && (y > 0 && y <= col) && show[x][y] == *){
                        show[x][y] = m;
                        system("cls");
                        ShowMine(show, row, col);
                        break;
                    }
                    else{
                        printf("請輸入正確的坐標\n");
                    }
                }
                break;
            default:
                printf("請正確輸入;>\n");

        }
    }
    
}
//統計標記雷的個數,如果小於等於雷數,返回1;大於雷數返回0
int TotalSignMine(char show[Rows][Cols], int row, int col, int count){
    int SignMineCount = 0;
    for (int i = 1; i <= row; i++){
        for (int j = 1; j <= col; j++){
            if (show[i][j] == m){
                SignMineCount++;
            }
        }
    }
    if (SignMineCount > count)
        return 0;
    return 1;
}

//掃雷
void ClearMine(char mine[Rows][Cols], char show[Rows][Cols], int row, int col, int count){
    int x = 0;
    int y = 0;
    while (1){
        int win = 0;
        printf("請輸入坐標:\n");
        scanf("%d", &x);
        scanf("%d", &y);
        if ((x > 0 && x <= row) && (y > 0 && y <= col)&&show[x][y]==*){
            //判斷是否有雷
            if(mine[x][y] == 0){
                //沒有雷統計該格子周圍八個格子的雷數
                show[x][y] = getMine(mine, x, y) + 0;
                //如果雷數等於0的話,遞歸判斷其周圍格子
                if (show[x][y] == 0){
                    show[x][y] =  ;
                    //遞歸判斷周圍格子
                    int arr[8][2] = { x - 1, y, x - 1, y - 1,
                        x, y - 1, x + 1, y - 1,
                        x + 1, y, x + 1, y + 1,
                        x, y + 1, x - 1, y + 1 };
                    OtherIsHaveMine(mine, show, arr, row, col);
                }
                for (int i = 1; i <= row; i++){
                    for (int j = 1; j <= col; j++){
                        //if (show[i][j] == ‘ ‘||(show[i][j]-‘0‘ <9&&show[i][j]-‘0‘>0))
                        if (show[i][j] != * || show[i][j] != m && show[i][j] != *){
                            win++;
                        }
                    }
                }
                //標記雷數大於真正的雷數時,返回0
                if (TotalSignMine(show, row, col, count)){
                    if (win == row*col - count){
                        printf("挑戰成功sayoulala\n");
                        ShowMine(mine, row, col);
                        break;
                    }
                }
                else{
                    printf("你標記的雷有可能不是雷,請你在標記的地方找出不是雷的位置");
                }
                system("cls");
                ShowMine(show, row, col);
                //是否標記雷
                SignMine(show, row, col);

            }
            else{
                printf("很遺憾你被炸死了...........菜雞\n");
                ShowMine(mine, row, col);
                break;
            }
        }
        else{
            printf("坐標輸入不正確,");
        }
    }
}

game.h

#ifndef _GAME_H_
#define Row 9
#define Col 9
#define Rows Row+2
#define Cols Col+2
#define EASY_COUNT 10
#define GENERAL_COUNT 20
#define HARD_COUNT 30

//初始化
void Init(char arr[Rows][Cols], int rows, int cols,char Set);
//展示
void Display(char arr[Rows][Cols], int row, int col);
//擺雷
void PutMine(char arr[Rows][Cols], int row, int col, int count);
//檢查
void ShowMine(char arr[Rows][Cols], int row, int col);
//掃雷
void ClearMine(char mine[Rows][Cols], char show[Rows][Cols], int row, int col, int count);
//是否標記雷
void SignMine(char show[Rows][Cols], int row, int col);
//周圍沒雷置空
void OtherIsHaveMine(char mine[Rows][Cols], char show[Rows][Cols], int arr[8][2], int row, int col);
//統計標記雷的個數,如果小於等於雷數,返回1;大於雷數返回0
int TotalSignMine(char show[Rows][Cols], int row, int col, int count);
#endif

在控制臺操作的掃雷代碼就是上面所寫的,我試著玩了幾局沒有發現錯誤,如果被那位讀者發現錯誤,請在評論區指出,我會第一時間修改,謝謝!

掃雷思想及主函數