【C语言】经典小游戏-扫雷

  1. 前言
  2. 项目思路:
  3. 项目展示:
  4. 项目源码:
    1. game.h:
    2. game.c:
    3. test.c
  5. 结语

前言

扫雷,是一个Windows平台下一个经典的小游戏,今有兴趣玩了几把后,就利用所学二维数组的相关知识模拟实现了一个“扫雷游戏”。由于学识浅薄,界面有点简陋,尽请谅解!

项目思路:

  • 首先想一想扫雷游戏在Windows平台下是如何实现的。
  • 其次通过观察游戏,我们可以想到需要用两个二维数组来实现扫雷的功能。
  • 游戏刚开始,需要需要显示棋盘,用“*”遮盖雷的坐标,所以要有一个填充棋盘的函数。
  • 通过rand()函数,随机生成雷的坐标,埋雷的函数。
  • 每次扫过后,都要显示新的棋盘,显示棋盘的函数。
  • 如果要想第一次踩不到雷的,需要把该坐标下得雷移动到其他不是雷的坐标,并且点击不是雷,还要满足一点击一片的效果。
  • 最后需要一个函数判断是否扫雷成功。

项目展示:

图片加载

图片加载
是不是很有意思?当然重中之重的是:

要注意需要用二维数组来打印两个棋盘,假如我们要打印10X10的棋盘,那我们的二维数组元素也要为10X10个吗?,不能,因为我们在设计算法时需要统计坐标周围8个方位雷的个数,假如要统计边界坐标周围雷的个数,那么就会有数组越界的问题,那我们就要在10X10的边界多上一圈元素,也就要定义12X12的数组元素,这些元素我们不要打印出来,心里有数就行。

项目源码:

game.h:

/*********************************************************************************************
*                     项目名称:扫雷游戏                                                       *
*             编译环境:Vs 2013                                                *
*                     创建日期:2018.4.18                                                      *
*                     项目编辑:Mr.Yao                                                         *  
***********************************************************************************************/  
 //知识点:  
//1.数组  
//2.函数  
//3.循环  
//4.扩展内容: 递归 (内存换取时间)  

#ifndef __GAME_H_  
#define __GAME_H_  

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

enum opp  
{  
    EXIT,  
    PLAY  
};  

#define EASY 10  
#define HARD 30  

#define ROW 10  
#define COL 10  

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

void InitMap(char arr[ROWS][COLS], int row,int col, char set); //创建初始化棋盘  
void PrintMap(char arr[ROWS][COLS], int row, int col);  //打印棋盘  
void SetMy(char arr[ROWS][COLS], int row, int col, int count); //布雷  
void SweepMap(char my_map[ROWS][COLS], char player_map[ROWS][COLS], int row, int cow, int sum); //扫雷  
void MoveLei(char my_map[ROWS][COLS], int x, int y); //若第一次扫到雷,则移动雷的位置  
void GetCount(char my_map[ROWS][COLS], char player_map[ROWS][COLS], int x, int y);//统计雷数  


#endif  

game.c:

#define _CRT_SECURE_NO_WARNINGS 1  

#include "game.h"  
//初始化棋盘
void InitMap(char arr[ROWS][COLS], int row, int col, char set)  
{  
    memset(arr, set, col*row*sizeof(arr[0][0]));  
}  
//打印棋盘
void PrintMap(char arr[ROWS][COLS], int row, int col)  
{  
        int i = 0;  
        int j = 0;  
        printf("   ");  
        for (i = 1; i<=row ; i++)  
        {  
            printf("%3d", i);  
        }  
        printf("\n");  
        for (i = 0; i<=row; i++)  
        {  
            printf("---");  
        }  
        printf("\n");  
        for (i = 1; i <= row; i++)  
        {                                  
            printf("%2d|", i);  
            for (j = 1; j <= col ; j++)  
            {  
                printf("%3c", arr[i][j]);  
            }  
            printf("\n");  
        }  

}  
//布雷
void SetMy(char arr[ROWS][COLS], int row, int col, int sum)  
{  
    int count = sum;  
    int x = 0;  
    int y = 0;  
    while (count)  
    {  
        x = rand() % row + 1;  
        y = rand() % col + 1;  
        if (arr[x][y] == '0')  
        {  
            arr[x][y] = '1';  
            count--;  
        }  
    }  
}  
//扫雷
void SweepMap(char my_map[ROWS][COLS],char player_map[ROWS][COLS], int row, int col, int sum)  
{  
    int x = 0;  
    int y = 0;  
    int count = 0;  
    int temp = 0;  
    int win = 0;  

    while (win < (row * col - sum))  
    {  
        printf("请输入你扫雷坐标:>");  
        scanf("%d%d", &x, &y);  
        temp++;  
        if (x >= 1 && x <= row&&y >= 1 && y <= col)  
        {  

            while ((my_map[x][y] == '1') && (temp == 1))  
            {  
                //保证玩家第一次不死  
                MoveLei(my_map, x, y);  
                //对周围的雷数进行遍历  
                GetCount(my_map, player_map, x, y);  
            }  

            if (my_map[x][y] == '1')  
            {  
                printf("\n恭喜你,壮烈牺牲\n");  
                PrintMap(my_map, ROW, COL);  
                break;  
            }  
            else  
            {  
                GetCount(my_map, player_map, x, y);  
                printf("\n");  
                win++;  
            }  
            PrintMap(player_map, ROW, COL);  
        }  
        else  
        {  
            printf("坐标输入有误\n");  
        }  

    }  
    if(win == (row * col - sum))  
    {  
        printf("恭喜你,排完了\n");  
    }  

}  

//若输入的坐标无雷,则要遍历周围,统计雷数    
//若周围无雷,则递归遍历,统计周围雷数    
void GetCount(char my_map[ROWS][COLS], char player_map[ROWS][COLS], int x, int y)  
{  


    if ((my_map[x][y] == '0'))  
    {  
        int count = 0;  

        if (my_map[x - 1][y - 1] == '1')  
            count++;  

        if (my_map[x - 1][y] == '1')  
            count++;  

        if (my_map[x - 1][y + 1] == '1')  
            count++;  

        if (my_map[x][y - 1] == '1')  
            count++;  

        if (my_map[x][y + 1] == '1')  
            count++;  
        if (my_map[x + 1][y - 1] == '1')  
            count++;  

        if (my_map[x + 1][y] == '1')  
            count++;  

        if (my_map[x + 1][y + 1] == '1')  
            count++;  

        player_map[x][y] = (count + '0');  
    }  

    if (player_map[x][y] == '0')  
    {  
        if (player_map[x - 1][y - 1] == '*')  
            GetCount(my_map, player_map, x - 1, y - 1);  

        if (player_map[x - 1][y] == '*')  
            GetCount(my_map, player_map, x - 1, y);  

        if (player_map[x - 1][y + 1] == '*')  
            GetCount(my_map, player_map, x - 1, y + 1);  

        if (player_map[x][y - 1] == '*')  
            GetCount(my_map, player_map, x, y - 1);  

        if (player_map[x][y + 1] == '*')  
            GetCount(my_map, player_map, x, y + 1);  

        if (player_map[x + 1][y - 1] == '*')  
            GetCount(my_map, player_map, x + 1, y - 1);  

        if (player_map[x + 1][y] == '*')  
            GetCount(my_map, player_map, x + 1, y);  

        if (player_map[x + 1][y + 1] == '*')  
            GetCount(my_map, player_map, x + 1, y + 1);  
    }  
}  

//为提高游戏体验,设置玩家第一次无论如何都不会被炸死    
void MoveLei(char my_map[ROWS][COLS], int x, int y)  
{  
    int ret = 1;  
    do  
    {  
        my_map[x][y] = '0';  
        while (ret)  
        {  
            x = rand() % ROW + 1;  
            y = rand() % COL + 1;  
            if (my_map[x][y] == '0')  
            {  
                my_map[x][y] = '1';  
            }  
            ret--;  
        }  
    } while (ret);  
}  

test.c

#define _CRT_SECURE_NO_WARNINGS 1  


#include "game.h"  

void GotoXY(int x, int y) //设定输出位置  
{  
    COORD c;  
    c.X = x - 1;  
    c.Y = y - 1;  
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);  
}  

void meau()  
{  
    GotoXY(10, 5); printf("开始游戏\n         Let's Go!");  
    Sleep(1500);  
    system("cls");  
    printf("****    《扫雷》    ****\n");  
    printf("************************\n");  
    printf("*******  1.play  *******\n");  
    printf("*******  0.exit  *******\n");  
    printf("************************\n");  
}  

void game()  
{  
    int input = 0;  
    int sum = 0;  
    char my_map[ROWS][COLS];  
    char player_map[ROWS][COLS];  

    InitMap(my_map,ROWS,COLS,'0');  
    InitMap(player_map, ROWS, COLS, '*');  

    printf("**** 1.Easy 0.Hard *****\n");  
    scanf("%d", &input);  
    switch (input)  
    {  
        case PLAY:  
            sum = EASY;  
            break;  
        case EXIT:  
            sum = HARD;  
            break;  
        default:  
            printf("输入有误\n");  
            break;  
    }  
    printf("\n这个棋盘有%d个雷。\n", sum);  
    SetMy(my_map,ROW,COL,sum);  

    PrintMap(player_map, ROW, COL);  
    //PrintMap(my_map, ROW, COL);  
    SweepMap(my_map,player_map ,ROW, COL, sum);  
    system("pause");  
}  



void test()  
{      
    int input = 0;  
    do  
    {  
        meau();  
        printf("请选择:>");  
        scanf("%d", &input);  
        switch (input)  
        {  
        case PLAY:  
            game();  
            break;  
        case EXIT:  
            break;  
        default:  
            printf("输出有误\n");  
        }  

    } while (input);  
}

int main()  
{  
    srand((unsigned)time(NULL));  
    test();  
    system("pause");  
    return 0;  
}   

结语

简单利用C语言做了一个小游戏,如有不正之处,欢迎双击评论!


部分资料来源于网络,版权属其原著者所有,只供学习交流之用。如有侵犯您的权益,请联系【公众号:码农印象】删除,可在下方评论,亦可邮件至ysluckly.520@qq.com。互动交流时请遵守宽容、换位思考的原则。

×

喜欢就点赞,疼爱就打赏

(function(){ var bp = document.createElement('script'); bp.src = '//push.zhanzhang.baidu.com/push.js'; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();
休闲小游戏