扫雷游戏

用c语言编写扫雷游戏:
1.扫雷的基本功能
2.第一次扫,不被炸死
3.当周围没有雷的时候可以向外延伸扩展。

完成这个游戏需要构造几个函数:
a.初始化雷盘;
b.打印雷盘;
c.设雷的数目;
d.统计点击之处雷的个数;
e.重新布雷;
f.扩展式排雷

game.h //头文件部分

#ifndef __GAME_H__
#define __GAME_H__


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

#define ROW 12 //实际行数
#define COL 12 //实际列数
#define ROWS (ROW-2)//雷盘行数
#define COLS (COL-2)//雷盘列数

#define  MINE 10 //雷数


void init_board(char arr[ROW][COL],char set,int row,int col);//初始化棋盘
void print_board(char arr[ROW][COL],int row,int col);//打印棋盘
void set_mine(char arr[ROW][COL],int row,int col);//布雷
int get_count(char arr[ROW][COL],int x,int y);//统计点击之处雷的个数
void reset_mine(char arr[ROW][COL],int x,int y,int row,int col);//重新布雷
void expend(char arr1[ROW][COL], int x, int y, int *ret, char arr2[ROW][COL]);//扩展排雷



#endif //__GAME_H__

game.c //游戏部分

#define _CRT_SECURE_NO_WARNINGS 1

#include "game.h"


void init_board(char arr[ROW][COL],char set,int row,int col)//初始化棋盘
{
        memset(arr,set,row*col*sizeof(arr[0][0]));//memset初始化,括号内为:数组名,初始化目标,初始化字节数
}
void print_board(char arr[ROW][COL],int row,int col)//打印棋盘
{
    int i = 0;
    int j = 0;
    printf("   ");
    for(i=1;i<row-1;i++)//打印列号
    {
        printf("%d  ",i);
    }
     printf("\n");
    for(i=1;i<row-1;i++)
    {
        printf("%2d ",i);
        for(j=1;j<col-1;j++)
        {
            printf("%c  ",arr[i][j]);
        }
        printf("\n");
    }
}
void set_mine(char arr[ROW][COL],int row,int col)
{
    int count = MINE;
    int x = 0;
    int y = 0;
    while(count>0)
    {
        x = rand() % ROWS+1;//产生随机数
        y = rand() % COLS+1;
        if(arr[x][y]=='0')
        {
            arr[x][y]='1';
            count--;
        }

    }
}
void reset_mine(char arr[ROW][COL],int x,int y,int row,int col)
{
    int count = 1;;
    arr[x][y] = '0';
    while (count)
    {
        int i = rand() % ROWS + 1;
        int j = rand() % COLS + 1;
        if ((arr[i][j] != '1') && (i != x) && (j != y))
        {
            arr[i][j] = '1';
            count--;
        }
    }

}

int get_count(char arr[ROW][COL],int x,int y)
{
    return arr[x-1][y-1]
    +arr[x+1][y+1]+arr[x][y-1]
    +arr[x][y+1]+arr[x-1][y]
    +arr[x+1][y-1]+arr[x+1][y]
    +arr[x-1][y+1]-8*'0';//雷周围8个数,返回雷数int值

}


void expend(char arr1[ROW][COL],int x,int y,int* ret,char arr2[ROW][COL])
{
    int i = 0;
    int j = 0;
    int count = 0;//点击之处周围雷数
    if(arr2[x][y]=='*')//未被排雷
    {
        (*ret)++;
        count = get_count(arr1,x,y);
        if(count!=0)//周围雷数不为0
        {
            arr2[x][y]=count+'0';//显示雷数

        }
        else // 周围八个位置扩展排雷
        {
            arr2[x][y]='0';
            for(i=-1;i<=1;i++)
            {
                for(j=-1;j<=1;j++)
                {
                    if((x+i>=1)&&(x+i<=ROWS)&&(y+j>=1)&&(y+j<=COLS))
                    {
                        if(i!=0||j!=0)
                            expend(arr1,x+i,y+j,ret,arr2);
                    }
                }
            }

        }
    }

}

test.c //测试部分

#define _CRT_SECURE_NO_WARNINGS 1

#include "game.h"


void menu()
{
    printf("***********************\n");
    printf("*****    1.play   *****\n");
    printf("*****    0.exit   *****\n");
    printf("***********************\n");
}
void game()
{
    int x = 0;
    int y = 0;
    int ret = 0;//找到非雷的次数
    char mine[ROW][COL] = {0};
    char show[ROW][COL] = {0};

    init_board(mine,'0',ROW,COL);
    init_board(show,'*',ROW,COL);

    set_mine(mine,ROW,COL);//布雷
    print_board(show,ROW,COL);
    printf("\n");
    print_board(mine,ROW,COL);//打印棋盘
    while(ret<(ROWS*COLS-MINE))    //开始排雷
    {
        printf("请输入坐标(x,y)-> ");
        scanf("%d%d",&x,&y);
        if(((x>=1)&&(x<=ROWS))&&(y>=1)&&(y<=COLS))//输入有效坐标
        {
            if(mine[x][y]=='1')//所选位置有雷
            {
                if(ret!=0)
                {

                    printf("很遗憾,你被炸死了!\n");
                    print_board(mine,ROW,COL);

                    return;
                }
                else
                {
                    mine[x][y]='0';
                    reset_mine(mine,x,y,ROWS,COLS);//重新布雷
                    expend(mine,x,y,&ret,show);
                }
            }
            else
            {
                expend(mine,x,y,&ret,show);
            }
            print_board(show,ROW,COL);
        }
        else
        {
            printf("输入的坐标无效,请重新输入!\n");
        }
    }
    if(ret=(ROWS*COLS-MINE))
    {
        printf("恭喜你,排雷成功!\n");

    }
}

    void test()
    {
        int input = 0;
        srand((unsigned)time(NULL));//初始化时间种子
        do
        {
            menu();
            printf("请输入->");
            scanf("%d",&input);
            switch(input)
            {
            case 1:game();
                break;
            case 0:
                break;
            default:printf("输入错误,请重新输入!\n");
                break;
            }
        }while(input);
   }

   int main()
   {
       test();
       system("pause");
       return 0;
   }

游戏结果为:

这里写图片描述

这里写图片描述

#ifndef _GAME_H_

#endif // _GAME_H_

作用:防止头文件被重复引用

代码中用 memset函数初始化雷盘,
这里扩展一下此函数 memset函数原型为:

void *memset( void *dest,int c,size_t count );//扩号中分别为要初始化的目标,初始化内容,初始化个数

更多内容可以在MSDN上查询。

如代码:

#include <stdio.h>

int main( void )
{
   char buffer[] = "This is a test of the memset function";

   printf( "Before: %s\n", buffer );
   memset( buffer, '*', 4 );
   printf( "After:  %s\n", buffer );
}

结果如图:
这里写图片描述

当我们写代码的时候会或多或少的遇到编译上的问题,这是我们不要急着去问老师或者度娘,应该自己先试着调试,这样下次就会避免再犯同类错误。vs2008上调试方法有:快捷键f5开始调试,f10 逐过程调试,f11逐语句调试。同样可以在窗口里看不同变量的变化,这些编译器里都有,我们应该熟练使用。

最后祝大家天天开心,下次再会!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值