C語言練習之掃雷小遊戲

掃雷

一、功能介紹:

1.掃雷的基本功能
2.第一次掃,不被炸死
3.當週圍沒有雷的時候可以向外延伸擴展。

二、代碼實現

1、首先創建一個頭文件

# ifndef __game_h_
# define __game_h_

# define ROW 10
# define COL 10
# define ROWS (ROW + 2)
# define COLS  (COL + 2)

//初始化雷
void InitBoard(char board[ROWS][COLS], int row, int col, char type);
//設置雷
void SetMine(char board[ROWS][COLS], int NUM);
//顯示
void PrintBoard(char board[ROWS][COLS], int row, int col);
//統計周圍的字符之和
int SumAround(char board[ROWS][COLS], int i, int j);
//第一次踩中雷,更改雷的位置,將此處置換爲非雷空
void BoomCountMine1(char board[ROWS][COLS], char board1[ROWS][COLS]);
//判斷是否踩中雷
int BoomCountMine2(char board[ROWS][COLS], char board1[ROWS][COLS]);
//如果周圍沒有雷,向四周擴展,如果周圍有雷,統計雷的個數
void ExpendBlock(char board[ROWS][COLS], char board1[ROWS][COLS], int i, int l);
//判斷輸贏
int IsWin(char board1[ROWS][COLS], int i, int j, int NUM);

# endif

2、然後建立一個源文件,寫入各個函數

#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>


void InitBoard(char board[ROWS][COLS], int row, int col, char type)//初始化棋盤數據
{
    memset(board, type, row*col*sizeof(board[0][0]));
}

void SetMine(char board[ROWS][COLS], int NUM)//佈置一定數目的雷
{
    int i = 0;
    int j = 0;
    int count = NUM;

    while (count)
    {
        i = rand() % (ROWS - 1);
        j = rand() % (COLS - 1);
        if ((i > 0) && (j > 0) && (board[i][j] == '0'))
        {
            board[i][j] = '1';
            count--;
        }
    }
}

void PrintBoard(char board[ROWS][COLS], int row, int col)//打印棋盤
{
    int i = 0;
    int j = 0;

    printf("     ");
    for (j = 0; j < col - 2; j++)
    {
        printf("%2d ", j + 1);
    }
    printf("\n");

    for (i = 1; i < row - 1; i++)
    {
        printf("  %2d  ", i);
        for (j = 1; j < col - 1; j++)
        {
            printf("%c  ", board[i][j]);
        }
        printf("\n");
    }
}

void BoomCountMine1(char board[ROWS][COLS], char board1[ROWS][COLS])//第一次踩中雷,更改雷的位置,將此處置換爲非雷空
{
    int i = 0;
    int j = 0;
    int I = 0;
    int J = 0;
    int sum = 0;

    printf("請輸入座標:>例:1 1\n");
    scanf("%d %d", &i, &j);
    I = i;
    J = j;

    if (board[i][j] == '1')
    {
        while (1)
        {
            i = rand() % (ROWS - 1);
            j = rand() % (COLS - 1);
            if ((i > 0) && (j > 0) && (board[i][j] == '0'))
            {
                board[i][j] = '1';
                break;
            }
        }
        board[I][J] = '0';
        sum = (board[I - 1][J - 1] + board[I][J - 1] + board[I + 1][J - 1]
            + board[I + 1][J] + board[I + 1][J + 1] + board[I][J + 1]
            + board[I - 1][J + 1] + board[I - 1][J] - 7 * '0');

        board1[I][J] = sum;
        ExpendBlock(board, board1, I, J);

    }
    else
    {
        ExpendBlock(board, board1, i, j);
    }
}

int BoomCountMine2(char board[ROWS][COLS], char board1[ROWS][COLS])//判斷是否踩中雷
{
    int i = 0;
    int j = 0;
    int I = 0;
    int J = 0;
    int tmp = 1;

    printf("請輸入座標:>例:1 1\n");
    scanf("%d %d", &i, &j);

    while (tmp)
    {
        if (board1[i][j] == ' ')
        {
            printf("此處已經排過雷,請重新輸入!\n");
            scanf("%d %d", &i, &j);
        }
        else
        {
            tmp = 0;
        }
    }


    if (board[i][j] == '1')
    {
        for (I = 1; I < ROWS - 1; I++)
        {
            for (J = 1; J < COLS - 1; J++)
            {
                if (board[I][J] == '1')
                {
                    board1[I][J] = 'M';
                }
            }
        }
        board1[i][j] = 'X';
        return 1;
    }

    else
    {
        ExpendBlock(board, board1, i, j);
        return 0;
    }
    return 0;
}

int SumAround(char board[ROWS][COLS], int i, int j)//統計周圍的字符之和
{
    int sum = 0;

    sum = (board[i - 1][j - 1] + board[i][j - 1] + board[i + 1][j - 1]
        + board[i + 1][j] + board[i + 1][j + 1] + board[i][j + 1]
        + board[i - 1][j + 1] + board[i - 1][j] - 7 * '0');

    return sum;
}

void ExpendBlock(char board[ROWS][COLS], char board1[ROWS][COLS], int i, int j)//如果周圍沒有雷,向四周擴展,如果周圍有雷,統計雷的個數
{
    int sum = 0;

    sum = SumAround(board, i, j);

    if (sum == '0')
    {
        board1[i][j] = ' ';
    }
    else if (sum > '0')
    {
        board1[i][j] = sum;
    }

    if ((sum <= '0') && (i>0) && (i<ROWS - 1) && (j>0) && (j<COLS - 1))
    {

        if ((board1[i - 1][j - 1] == '*'))//左上
        {
            ExpendBlock(board, board1, i - 1, j - 1);
        }

        if ((board1[i][j - 1] == '*'))//左方
        {
            ExpendBlock(board, board1, i, j - 1);
        }


        if ((board1[i + 1][j - 1] == '*'))//左下
        {
            ExpendBlock(board, board1, i + 1, j - 1);
        }


        if ((board1[i + 1][j] == '*'))//下方
        {
            ExpendBlock(board, board1, i + 1, j);
        }


        if ((board1[i + 1][j + 1] == '*'))//右下
        {
            ExpendBlock(board, board1, i + 1, j + 1);
        }


        if ((board1[i][j + 1] == '*'))//右方
        {
            ExpendBlock(board, board1, i, j + 1);
        }


        if ((board1[i - 1][j + 1] == '*'))//右上
        {
            ExpendBlock(board, board1, i - 1, j + 1);
        }


        if ((board1[i - 1][j] == '*'))//上方
        {
            ExpendBlock(board, board1, i - 1, j);
        }

        if ((board1[i - 1][j] == '*'))//上方
        {
            ExpendBlock(board, board1, i - 1, j);
        }
    }
}

int IsWin(char board1[ROWS][COLS], int i, int j, int NUM)
{
    int count = 0;
    for (i = 1; i < ROWS - 1; i++)
    {
        for (j = 1; j < COLS - 1; j++)
        {
            if (board1[i][j] == '*')
            {
                count++;
            }
        }
    }

    if (count == NUM)
    {
        for (i = 1; i < ROWS - 1; i++)
        {
            for (j = 1; j < COLS - 1; j++)
            {
                if (board1[i][j] == '*')
                {
                    board1[i][j] = 'M';
                }
            }
        }
        return 1;
    }
    return 0;
}

3、最後寫一個測試代碼 main.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

void menu()
{
    printf("***********************\n");
    printf("    1.paly     0.exit\n");
    printf("***********************\n");
}

void game()
{
    int ret = 0;
    int ret1 = 0;
    int ret2 = 0;
    int input = 0;
    int num = 0;
    printf("請輸入雷的個數:>");
    scanf("%d", &num);
    char Mine[ROWS][COLS] = { 0 };
    char Show[ROWS][COLS] = { 0 };

    InitBoard(Mine, ROWS, COLS, '0');
    InitBoard(Show, ROWS, COLS, '*');

    SetMine(Mine, num);

    PrintBoard(Show, ROWS, COLS);

    while (1)
    {
        int tmp = 2;

        if (input == 1)
        {
            ret = BoomCountMine2(Mine, Show);

            ret1 = IsWin(Show, ROWS, COLS, num);
            if (ret1 == 1)
            {
                printf("\n恭喜你,你贏了!\n");
                PrintBoard(Show, ROWS, COLS);
                break;
            }
            if (ret == 1)
            {
                printf("\n阿喔,你踩到雷了!\n");

                PrintBoard(Show, ROWS, COLS);
                break;
            }
        }
        else
        {
            BoomCountMine1(Mine, Show);
            ret2 = IsWin(Show, ROWS, COLS, num);
            if (ret2 == 1)
            {
                printf("\n恭喜你,你贏了!\n");
                PrintBoard(Show, ROWS, COLS);
                break;
            }
            input++;
        }
        printf("\n");
        PrintBoard(Show, ROWS, COLS);
    }
}
//主函數
int main()
{
    int input = 0;
    srand((unsigned)time(NULL));

    do
    {
        menu();
        scanf("%d", &input);
        switch (input)
        {
        case 1:
            printf("準備好了嗎?遊戲開始!\n");
            game();
            break;
        case 0:
            printf("遊戲結束!\n");
            break;
        default:
            printf("輸入錯誤!\n");
            break;
        }
    } while (input);

    system("pause");
    return 0;
}

三、調試結果

1、開始遊戲

這裏寫圖片描述
2、輸入座標
這裏寫圖片描述
3、踩到雷
這裏寫圖片描述
4、呃呃,老是輸,這裏就不給大家展示贏的截圖啦!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章