扫雷游戏的编写

我们都玩过一款名为扫雷的游戏,而利用我们所学的C语言也可以模拟实现扫雷的功能。通过对扫雷的了解,明白其原理。首先在一块区域上,选取一个坐标点,如果该坐标点是雷点,游戏结束;如果是安全区,而且周围都为安全区,则会进行扩展,雷区的附近会有坐标显示雷存在的颗数。
根据C语言所学,大致思路是:系统布雷,玩家选取坐标,是安全区,游戏继续,扩展或者显示周围雷数;如果雷区,则游戏结束。用随机数的生成,在一个10X10的二维数组布雷,雷数为10颗,用递归的方法对安全区进行扩展和对周围雷数的探测。
我们将程序分为3个模块,首先为头文件:函数的声明,宏的定义,头文件的引入;然后是测试文件:主函数部分;最后是游戏主要程序的编写。

1.头文件(game.h)

#ifndef __GAME_H__

#define __GAME_H__


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

extern void meun();
extern void Map(char a[][10]);
extern char Discorn(char a[][10],int x,int y);
extern void Extend(char a[][10], char b[][10],int x,int y);
extern void Judgement(char a[][10]);
extern void Set();
extern void game();


#endif //__GAME_H__

2.测试程序(test.c)

#include"game.h"

int main()
{
    srand((unsigned)time(NULL));        //随机数种子产生
    int a;
    do
    {
        meun();
        scanf_s("%d", &a);
        switch (a)
        {
        case 1:
            game();
            break;
        case 0:
            break;
        default:
            printf("输入错误\n11");
            system("cls");
            break;
        }
    } while (a);
    return 0;
}

3.主要游戏程序部分(game.h)

 //游戏程序
void game()                                 
{
    printf("--------------------------------------------------------------------\n");
    Set();                                 
    char mine[10][10];                    
    memset(mine, ' ', sizeof(mine));         //对雷区进行初始化
    int i = 0;
    while (i < 10)
    {
        int x = rand() % 10 ;               //随机数的接受(产生0-9的随机数)
        int y = rand() % 10 ;
        if (mine[y][x] == ' ')              //布置地雷(不能重复) 
        {
            mine[y][x] = 'X';
            i++;
        }
    }
    //Map(mine);                            //雷区的显示
    Judgement(mine);                        //输赢的判断
}

//游戏界面
void meun()                               
{
    printf("*************************************************************\n");
    printf("************       Welcome to Minesweeper      **************\n");
    printf("*************************************************************\n");
    printf("************      -       1. Play        -     **************\n");
    printf("************      -       0. Exit        -     **************\n");
    printf("*************************************************************\n");
}


//游戏地图的初始化
void Set()                                  
{
    char set[10][10];
    memset(set, '*', sizeof(set));
    Map(set);
}



//打印地图
void Map(char m[10][10])                  
{
    int i, j;
    printf("\n\n");
    for (j = 1; j < 11; j++)
    {
        if (j == 1)
            printf("  ");
        printf("%3d", j);
    }
    printf("\n");
    for (i = 0; i < 10; i++)
    {
        printf("%2d", i + 1);
        for (j = 0; j < 10; j++)
        {
            printf("%3c", m[i][j]);
        }
        printf("\n");

    }
    printf("\n");
    printf("\n--------------------------------------------------------------------\n");
}


//对安全区的扩展
void Extend(char a[10][10], char set[10][10], int x, int y)  
{
    if ((a[y - 1][x - 1] != 'X') && (a[y - 1][x] != 'X') &&
        (a[y - 1][x + 1] != 'X') && (a[y][x + 1] != 'X') &&
        (a[y][x - 1] != 'X') && (a[y + 1][x] != 'X') &&
        (a[y + 1][x + 1] != 'X') && (a[y + 1][x - 1] != 'X'))
    {
        if ((x - 1 > -1) && ((y - 1) > -1) && (a[y - 1][x - 1] ==' ') && (set[y - 1][x - 1] != ' '))
        {
            set[y - 1][x - 1] = ' ';
            char ret1 = Discorn(a, x - 1, y - 1);
            if (ret1 == '0')
                ret1 = ' ';
            else
                set[y - 1][x - 1] = ret1;
            Extend(a, set, x - 1, y - 1);
        }
        if (((x - 1) > -1) && (y < 10) && (y>-1) && (a[y][x - 1] == ' ') && (set[y][x - 1] != ' '))
        {
            set[y][x - 1] = ' ';
            char ret2 = Discorn(a, x - 1, y);
            if (ret2 == '0')
                ret2 = ' ';
            else
                set[y][x - 1] = ret2;
            Extend(a, set, x - 1, y);
        }
        if ((x - 1 >-1) && (y + 1< 10) && (a[y + 1][x - 1] == ' ') && (set[y + 1][x - 1] != ' '))
        {
            set[y + 1][x - 1] = ' ';
            char ret3 = Discorn(a, x - 1, y + 1);
            if (ret3 == '0')
                ret3 = ' ';
            else
                set[y + 1][x - 1] = ret3;
            Extend(a, set, x - 1, y + 1);
        }
        if ((x>-1) && (x < 10) && (y + 1 < 10) && (a[y + 1][x] == ' ') && (set[y + 1][x] != ' '))
        {
            set[y + 1][x] = ' ';
            char ret4 = Discorn(a, x, y + 1);
            if (ret4 == '0')
                ret4 = ' ';
            else
                set[y + 1][x] = ret4;
            Extend(a, set, x, y + 1);
        }
        if ((x>-1) && (x < 10) && (y - 1>-1) && (a[y - 1][x] == ' ') && (set[y - 1][x] != ' '))
        {
            set[y - 1][x] = ' ';
            char ret5 = Discorn(a, x, y - 1);
            if (ret5 == '0')
                ret5 = ' ';
            else
                set[y - 1][x] = ret5;
            Extend(a, set, x, y - 1);
        }
        if ((x + 1 < 10) && (y - 1 >-1) && (a[y - 1][x + 1] == ' ') && (set[y - 1][x + 1] != ' '))
        {
            set[y - 1][x + 1] = ' ';
            char ret6 = Discorn(a, x + 1, y - 1);
            if (ret6 == '0')
                ret6 = ' ';
            else
                set[y - 1][x + 1] = ret6;
            Extend(a, set, x + 1, y - 1);
        }
        if ((x + 1 < 10) && (y<10) && (y>-1) && (a[y][x + 1] == ' ') && (set[y][x + 1] != ' '))
        {
            set[y][x + 1] = ' ';
            char ret7 = Discorn(a, x + 1, y);
            if (ret7 == '0')
                ret7 = ' ';
            else
                set[y][x + 1] = ret7;
            Extend(a, set, x + 1, y);
        }
        if ((x + 1 < 10) && ((y + 1) < 10) && (a[y + 1][x + 1] == ' ') && (set[y + 1][x + 1]))
        {
            set[y + 1][x + 1] = ' ';
            char ret8 = Discorn(a, x + 1, y + 1);
            if (ret8 == '0')
                ret8 = ' ';
            else
                set[y + 1][x + 1] = ret8;
            Extend(a, set, x + 1, y + 1);
        }
    }
}

//对周围雷数进行统计
char Discorn(char a[10][10], int x, int y)
{
    char count = '0';
    if (((x - 1) > -1) && ((y - 1) > -1) && (a[y - 1][x - 1] == 'X'))
        count++;
    if (((x - 1) > -1) && (y < 10) && (y>-1) && (a[y][x - 1] == 'X'))
        count++;
    if (((x - 1) > -1) && ((y + 1) < 10) && (a[y + 1][x - 1] == 'X'))
        count++;
    if ((x>-1) && (x < 10) && ((y + 1) < 10) && (a[y + 1][x] == 'X'))
        count++;
    if ((x>-1) && (x < 10) && ((y - 1)>-1) && (a[y - 1][x] == 'X'))
        count++;
    if (((x + 1) < 10) && ((y - 1) >-1) && (a[y - 1][x + 1] == 'X'))
        count++;
    if (((x + 1) < 10) && (y<10) && (y>-1) && (a[y][x + 1] == 'X'))
        count++;
    if (((x + 1) < 10) && ((y + 1) < 10) && (a[y + 1][x + 1] == 'X'))
        count++;
    return count;
}


//判断输赢
void Judgement(char a[10][10])
{
    int x, y;
    char set[10][10];
    memset(set, '*', sizeof(set));
    while (1)
    {
        int count = 0;
        printf("input coordinate:");
        scanf("%d %d", &x, &y);
        system("cls");                              //对屏幕的刷新
        if (x > 10 || y > 10 || x < 0 || y < 0)
        {
            printf("Please again!!!\n");
            continue;
        }
        x = x - 1;
        y = y - 1;
        if (a[y][x] == 'X')
        {
            Map(a);
            printf("you were dead!!!\n");
            break;
        }
        else
        {

            char ret = Discorn(a, x, y);
            if (ret == '0')
                ret = ' ';
            set[y][x] = ret;
            Extend(a, set, x, y);
            Map(set);
            for (int i = 0; i < 10; i++)
            {
                for (int j = 0; j < 10; j++)
                if (set[i][j] == '*')
                    count++;
            }
        }
        if (count == 10)
        {
            printf("You win this game!!!\n");
            break;
        }
    }
}

图片展示

这里写图片描述

这里写图片描述

这里写图片描述
游戏的扩展部分需要用到函数的递归,本程序的精华所在,通过递归和限制条件的设置,对安全区进行一步步扩展,递归的引入很好的结局了这一问题。
程序还可以进行扩展,对游戏雷数的设置,难度的设置等,新的功能及优化等着进一步的完善。

                                                     Author:yk
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值