1. 程式人生 > >c語言實現:掃雷

c語言實現:掃雷

spa ret 出現 過程 rand() min i++ *** splay

問題描述:相信大多數人都很熟悉掃雷遊戲,在n*n的雷盤上隨機埋上一些雷,玩家翻開一個非地雷格時,該格將會出現一個數字——提示周圍格子中有多少個是地雷格。遊戲的目標是在不翻出任何地雷格的條件下,找出所有的非地雷格。

遊戲設計:

在test.c裏,完成了遊戲的框架實現

首先,我們寫一個test()函數測試我們寫出的小遊戲

void test()
{
    int input = 0;
    do
    {
        menu();
        srand((unsigned)time(NULL));
        printf("請輸入選項:
"); scanf("%d",&input); switch(input) { case 1: game(); break; case 0: printf("退出遊戲"); break; default: printf("輸入錯誤,請重新輸入:\n"); break; } }while(input); }

接著就是菜單函數,輔助玩家選擇

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

最後就是我們的遊戲實現部分啦

void game()
{
    int ret = 0;
    char mine[ROWS][COLS] = {0};
    char show[ROWS][COLS] = {0
}; InitBoard(mine,ROWS,COLS,0); InitBoard(show,ROWS,COLS,*); DisplayBoard(show,ROWS,COLS); printf("\n"); //DisplayBoard(mine,ROWS,COLS); Setmine(mine,ROW,COL); DisplayBoard(mine,ROWS,COLS); while (1) { int ret=FineMine(mine,show,ROW,COL); if(ret==0) break; else if(ret==1) { printf("被雷炸死\n"); DisplayBoard(show,ROWS,COLS); printf("\n"); DisplayBoard(mine,ROWS,COLS); printf("\n"); break; } DisplayBoard(show,ROWS,COLS); printf("\n"); } }

接著我們就得實現遊戲函數的主要細節實現:

1、函數聲明部分

game.h

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

#define ROWS 10
#define COLS 10
#define ROW 8
#define COL 8
#define COUNT 5

void InitBoard(char board[ROWS][COLS],int rows,int cols, char c);
void DisplayBoard(char board[ROWS][COLS],int row,int col);
void Setmine(char board[ROWS][COLS],int row,int col);
int FineMine(char mine[ROWS][COLS],char show[ROWS][COLS],int row,int col);
int count_show(char board[ROWS][COLS],int row ,int col);

2、函數的細節實現

game.c

首先利用memset函數初始化棋盤

void InitBoard(char board[ROWS][COLS],int rows,int cols, char c)
{
    memset(board,c,rows*cols*sizeof(char));

}

打印棋盤實現

void DisplayBoard(char board[ROWS][COLS],int rows,int cols)
{
    int i = 0;
    int j = 0;
    for (i = 0; i <rows - 1; i++)
    {
        printf("%d ", i);
    }
    printf("\n");
    for (i = 1; i <rows - 2; i++)
    {
        printf("%d ", i);
        for (j = 1; j < cols - 1; j++)
        {
            printf("%c ", board[i][j]);
        }
        printf("\n");
    }
    printf("%d ",rows-2);
    for (i = 1; i < rows - 1; i++)
    {
        printf("%c ", board[rows-2][i]);
    }
    printf("\n");
}

利用rand()函數隨機埋雷

void Setmine(char board[ROWS][COLS],int row,int col)
{
    int x = 0;
    int y = 0;
    int count = COUNT;
    while (count)
    {
        int x = rand() % row + 1;
        int y = rand() % row + 1;
        if (board[x][y] == 0)
        {
            board[x][y] = 1;
            count--;
        }
    }
}

掃雷過程(判斷輸贏):

int FineMine(char mine[ROWS][COLS],char show[ROWS][COLS],int row,int col)
{
    int x = 0;
    int y = 0;
    int count = 0;
    printf("輸入坐標掃雷\n");
    scanf("%d %d", &x, &y);
    if ((x >= 1 && x <= row) && (y >= 1 && y <= row))
        {
            if (mine[x][y] == 0)
            {
                char ch = count_mine(mine,x,y);
                show[x][y] = ch+0;
                open_mine(mine,show,x, y);
                if (count_show(show,row,col) == COUNT)
                {
                    DisplayBoard(show,ROWS,COLS);
                    printf("玩家贏!\n\n");
                    DisplayBoard(mine,ROWS,COLS);
                    printf("\n");
                    return 0;
                }
            }
            else if (mine[x][y]==1)
            {
                return 1;
            }

        }
    else
    {
        printf("輸入錯誤重新輸入\n");    
    } 
}

在掃雷函數中我們需要一些功能函數地輔助。

判斷周圍雷的個數

static char count_mine(char board[ROWS][COLS],int x, int y)
{
    int count = 0;
    if (board[x - 1][y - 1] == 1)
        count++;
    if (board[x - 1][y] == 1)
        count++;    
    if (board[x - 1][y + 1] == 1)
        count++;
    if (board[x][y - 1] == 1)
        count++;    
    if (board[x][y + 1] == 1)
        count++;    
    if (board[x + 1][y - 1] == 1)
        count++;    
    if (board[x + 1][y] == 1)
        count++;    
    if (board[x + 1][y + 1] == 1)
        count++;
    return count;
}

展開掃雷

static void open_mine(char mine[ROWS][COLS],char show[ROWS][COLS],int x, int y)
{
    if (mine[x - 1][y - 1]== 0)
    {
        show[x - 1][y - 1] = count_mine(mine,x - 1, y - 1) + 0;
    }
    if (mine[x - 1][y] == 0)
    {
        show[x - 1][y] = count_mine(mine,x - 1, y) + 0;
    }
    if (mine[x - 1][y + 1] == 0)
    {
        show[x - 1][y + 1] = count_mine(mine,x - 1, y + 1) + 0;
    }
    if (mine[x][y - 1] == 0)
    {
        show[x][y - 1] = count_mine(mine,x, y - 1) + 0;
    }
    if (mine[x][y + 1] == 0)
    {
        show[x][y + 1] = count_mine(mine,x, y + 1) + 0;
    }
    if (mine[x + 1][y - 1] == 0)
    {
        show[x + 1][y - 1] = count_mine(mine,x + 1, y - 1) + 0;
    }
    if (mine[x + 1][y] == 0)
    {
        show[x + 1][y] = count_mine(mine,x + 1, y) + 0;
    }
    if (mine[x + 1][y + 1] == 0)
    {
        show[x + 1][y + 1] = count_mine(mine,x + 1, y + 1) + 0;
    }
}

最後統計是否掃除雷外所有非雷格

int count_show(char board[ROWS][COLS],int row ,int col)
{
    int count = 0;
    int i = 0;
    int j = 0;
    for (i = 1; i <= row; i++)
    {
        for (j = 1; j <= col; j++)
        {
            if (board[i][j] == *)
            {
                count++;
            }
        }

    }
    return count;
}

以上就是我關於掃雷寫的一個簡單的小程序,還很稚嫩,會持續更新改進的。

c語言實現:掃雷