C语言小游戏---扫雷

将整个代码分装在三个文件中,分别为源文件:test.c game.c game.h 。
代码如下:
game.h

#ifndef __GAME_H__
#define __GAME_H_
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define MINE_NUM 20
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<string.h>
void Menu();//游戏菜单
void Game();//游戏主体函数
void Mine(char mine_map[ROWS][COLS]);//设置雷的位置
void Print(char mine_map[ROWS][COLS]);//打印游戏中的雷盘
void Init(char mine_map[ROWS][COLS],char mine_map_show[ROWS][COLS]);//初始化雷盘
void Clear_Mine(char mine_map[ROWS][COLS], char mine_map_show[ROWS][COLS]);//玩家进行扫雷的函数
int Go_on(char mine_map_show[ROWS][COLS]);//判断游戏是否继续进行下去
int Mine_num(char mine_map[ROWS][COLS], int row, int col);//判断玩家选择的位置周围有几颗雷
int Is_win(char mine_map_show[ROWS][COLS]);//判断玩家是否获胜
#endif//game.h

game.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void Print(char mine_map[ROWS][COLS])
{
    int i = 0;
    int j = 0;
    for (i = 0; i < ROWS; i++)
    {
        for (j = 0; j < COLS; j++)
        {
            printf("%c ", mine_map[i][j]);
        }
        printf("\n");
    }
}
void Init(char mine_map[ROWS][COLS],char mine_map_show[ROWS][COLS])
{
    int num = (ROWS)*(COLS);
    int i = 0;
    int j = 0;
    memset(mine_map, '0',num);//把mine_map这个雷盘全部初始化为字符‘0’
    memset(mine_map_show, '*', num);//把mine_map_show这个雷盘全部初始化为字符‘*’
    for (i = 0; i < ROWS; i++)
    {
        for (j = 0; j < COLS; j++)
        {//把定义好的雷盘的第一行和第一列都初始化为1 2 3 4 5 6 7 8 9,这样用于让玩家方便选择要查看的位置
            if (0 == i)
            {
                mine_map[i][j] = 47 + j;
                mine_map_show[i][j] = 47 + j;
            }
            else if (0 == j)
            {
                mine_map[i][j] = 47 + i;
                mine_map_show[i][j] = 47 + i;
            }
        }
    }

}
void Mine(char mine_map[ROWS][COLS])
{
    int row = 0;
    int col = 0;
    int i = 0;
    int row_s = 0;
    int col_s = 0;
    row_s = ROWS;
    col_s = COLS;
    srand((unsigned int)time(NULL));//设置随机数种子
    for (i = 0; i < MINE_NUM; i++)
    {//定义一个宏用来设置雷的个数 

        do
        {
            row = 0;
            col = 0;
            while (row < 1 || col < 1)
            {
                row = rand() % row_s;           
                col = rand() % col_s;//让电脑随机生成一个位置

            }//因为雷盘的第一行或第一列用于让玩家明确位置,所以当电脑生成的位置指向雷盘的第一行或第一列时,让电脑重新生成一个随机位置      
        } while (mine_map[row][col] != '0');//要保证随机生成的的位置是一个合法位置
        mine_map[row][col] = 36;//把所有合法位置改为字符‘$’,用来表示雷所在的位置
    }
}
void Clear_Mine(char mine_map[ROWS][COLS], char mine_map_show[ROWS][COLS])
{
    int row = 0;
    int col = 0;
    int i = 0;
    int j = 0;
    int mine_num = 0;
    int open = 0;
    printf("请输入要查看的坐标:");
    flag:
    scanf("%d %d", &row, &col);
    if (row >= 10 || col >= 10)
    {//确保玩家所输入的位置是一个合法位置
        printf("非法输入,请重新输入:");
        goto flag;
    }
    mine_num = Mine_num(mine_map, row, col);//查找玩家所选位置周围雷的个数
    if (36 == mine_map[row + 1][col + 1])
    {
        printf("你踩到地雷了,游戏结束\n");
        for (i = 0; i < ROWS; i++)
        {
            for (j = 0; j < COLS; j++)
            {
                if (mine_map[i][j] == 36)
                {
                    mine_map_show[i][j] = 36;//当玩家选中的位置是雷时,让雷盘中所有的雷的位置都展示在显示给玩家的雷盘中
                }
            }
        }
        Print(mine_map_show);
        return;
    }
    else if ('0' == mine_map[row + 1][col + 1])
    {
        for (open = 0; open < rand() % 9; open++)
        {
            for (i = row; i < row + 2; i++)
            {
                for (j = col; j < col + 2; j++)
                {
                    if ('0' == mine_map[i][j])
                    {
                        mine_map_show[i][j] = '0';//当玩家所选的位置不是雷,让电脑随机判断所选位置的周围,让不是雷的地方随机展开
                    }
                }
            }
        }
        mine_map_show[row + 1][col + 1] = '0'+mine_num;//让玩家所选择的位置显示周围雷的个数
    }

}
int Go_on(char mine_map_show[ROWS][COLS])
{
    int i = 0;
    int j = 0;
    int count = Is_win(mine_map_show);//用count来接收Is_win函数的返回值
    for (i = 1; i < ROWS; i++)
    {
        for (j = 1; j < COLS; j++)
        {
            if (mine_map_show[i][j] ==36)//判断如果展示给玩家的雷盘中出现字符‘$’时,就证明玩家被雷炸死
            {
                return 0;
            }
            else if (MINE_NUM==count)//当count=MINE_NUM时说明玩家已经把所有不是雷的位置排除
            {
                return 0;
            }
        }
    }
    return 1;//return 1 证明游戏继续
}
int Mine_num(char mine_map[ROWS][COLS],int row,int col)
{//当玩家所选位置不是雷时,让电脑查找所选位置雷的个数
    int i = 0;
    int j = 0;
    int mine_num = 0;
    for (i = row; i <= row + 2; i++)
    {
        for (j = col ; j <= col + 2; j++)
        {
            if (mine_map[i][j] == 36)
            {
                mine_num++;
            }
        }
    }
    return mine_num;
}
int Is_win(char mine_map_show[ROWS][COLS])
{
    int i = 0;
    int j = 0;
    int count = 0;//设置一个计数器
    for (i = 1; i < ROWS; i++)
    {
        for (j = 1; j < COLS; j++)
        {//因为用于游戏的雷盘不包括所定义的第一行和第一列,所以设置for循环从第二行的第二列开始          
            if (mine_map_show[i][j] == '*')
            {
                count++;
            }//如果遇到字符‘*’计数器就+1,当所有的不是雷的位置都让玩家排掉之后,count就等于所设置的雷的个数
        }
    }

    return count;
}
void Game()
{
    int ret = 0;
    char mine_map[ROWS][COLS] = { 0 };//定义一个没有隐藏雷所在位置的雷盘
    char mine_map_show[ROWS][COLS] = { 0 };//定义一个专门展示给玩家的雷盘
    Init(mine_map,mine_map_show);
    Mine(mine_map);//把雷存进mine_map这个雷盘中
    Print(mine_map);//打印一次mine_map这个雷盘,仅用于测试
    printf("\n");
    while (Go_on(mine_map_show))//Go_on返回1时不跳出循环,返回0时跳出循环
    {
        Print(mine_map_show);
        Clear_Mine(mine_map, mine_map_show);
        if (Is_win(mine_map_show) == MINE_NUM)
        {
            printf("恭喜你排出了所有雷\n");
        }
    }
}

test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void Menu()
{
    printf("***********************************************\n");
    printf("********      1.play      0. exit     *********\n");
    printf("***********************************************\n");
}
int main()
{
    int i = 1;
    while (i)
    {
        Menu();
        printf("请选择:");
        scanf("%d", &i);
        switch (i)
        {
        case 0:printf("退出游戏\n");
            break;
        case 1: printf("开始游戏\n");
            Game();
            break;
        default:printf("选择错误,请重新开始\n");
            break;

        }
    }
    system("pause");
    return 0;
}

以上即为扫雷小游戏的所有代码。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值