扫雷游戏

来源:互联网 发布:肿泡眼双眼皮知乎 编辑:程序博客网 时间:2024/05/20 19:49

注:本扫雷游戏完全由C语言编写

1.游戏界面为15*15格子状地图2.根据菜单界面 选择进入游戏或退出3.选择难度界面 分为easy   hard   hell 3种难度,地图对应随机生成203045颗地雷4.首次排雷不会触雷5.每次输入排雷坐标后,若未触雷则检测周围8个方格的地雷总数,为0则翻开,非0则在该坐标处输出8个方格中地雷总数,并对周围的方格递归遍历6.每次选择排雷坐标后,自动清屏7.当排完雷或者触雷后,保留最后操作界面,提示排雷成功或失败,并输出雷区答案8.选择再来一把或者退出游戏

game.h

#ifndef __GAME_H__#define __GAME_H__      //放置头文件,声明函数#include<stdio.h>#include<stdlib.h>#include<string.h>#include<time.h>#include<windows.h>#define ROWS 17 #define COLS 17#define ROW ROWS-1#define COL COLS-1void menu();//主菜单int game();//游戏主体函数,在此函数中调用以下函数void level_board();//选择难度菜单int select_level(int n);//选择难度int check_correct(int *px,int *py);//检测落点合法性void first_step(char mine[ROWS][COLS],int *px,int *py);//规避首次触雷int check_lose(char mine[ROWS][COLS],int *px,int *py);//判断是否触雷void Init_board(char mine[ROWS][COLS],char show [ROWS][COLS]);//初始化雷区void Input_mine(char mine[ROWS][COLS],int mine_num);//布雷void show_board(char show[ROWS][COLS],int row,int col);//输出玩家用排雷图void check_round(char mine[ROWS][COLS],char show[ROWS][COLS],int x,int y);//递归检测周围地雷个数int count_num(char mine[ROWS][COLS],int x,int y);//检测周围8个方格有多少颗雷int check_win(char mine[ROWS][COLS],char show[ROWS][COLS]);//检查是否排完雷#endif

game.c

#define _CRT_SECURE_NO_WARNINGS 1 //游戏的核心代码#include"game.h"//菜单void menu(){  printf("************************************\n");  printf("**********欢迎来到扫雷游戏************\n");  printf("****  1.play            0.exit  ****\n");  printf("************************************\n");}//初始化面板void Init_board(char mine[ROWS][COLS],char show [ROWS][COLS]){     memset(mine ,'0',(ROWS)*(COLS)*sizeof (char));     memset(show ,'*',(ROWS)*(COLS)*sizeof(char));}void level_board(){    printf("*********勇士,请选择你要挑战的难度:***********\n");    printf("1.easy              2.hard              3.hell\n");}int select_level(int m){   int x=0;    switch (m){    case 1:        x = 20;        break;    case 2:        x = 30;        break;    case 3:        x = 45;        break;    default:        printf("你输入的有误,请重新输入!\n\n");        break;    }     return x;}//布雷void Input_mine(char mine[ROWS][COLS],int mine_num){    int n=mine_num;    while (n){    int x=rand()%ROW-1;    int y=rand()%COL-1;    if (x>=1&&y>=1){    if (mine[x][y]=='0'){    mine[x][y]='1';    n--;    }    }    }}//展示面板void show_board(char show[ROWS][COLS],int row,int col){    int i=0;    int j=0;    int m=0;    for (m=1;m<row;m++){        printf("%3d ",m);        }    printf("\n");    for (i=1;i<row;i++){        for (j=1;j<col;j++){    printf(" %c |",show[i][j]);        }        printf(" %d\n",i);        for (j=1;j<col;j++){        printf(" ▔ ");        }        printf("\n");       }    printf("\n\n\n");}int check_correct(int *px,int *py)//检测落子合法性,合法返回1 ,非法返回0{   printf("请输入坐标排雷\n");    scanf("%d%d",px,py);     if ( ((*px)>=1)&&((*px)<ROW)&&((*py)>=1)&&((*py)<COL))     {    return 1;     }     else          return 0;}void first_step(char mine[ROWS][COLS],int *px,int *py){   int a=*px;    int b=*py;   if (mine[(*px)][(*py)]=='1')   {        mine[(*px)][(*py)]='0';        do        {           a=rand()%ROW-1;           b=rand()%COL-1;        }        while ( (mine[a][b]=='1') || ((a)<1)||((b)<1 ));        mine[a][b]='1';    }}int check_lose(char mine[ROWS][COLS],int *px,int *py){    if (mine[(*px)][(*py)]=='1')    {        printf("你踩雷了!游戏结束\n");        printf("下图为雷区,1为雷,0为空\n");        show_board(mine,ROW,COL);        return 1;    }    else     {       return 0;    }}//递归检测周围雷数void check_round(char mine[ROWS][COLS],char show[ROWS][COLS],int x,int y)//应用递归排除周围没有雷的区域  {      int ret;      ret=count_num(mine,x,y);      if (ret==0)      {          show[x][y]=' ';          if ((x-1)>0&&(y-1)>0&&(show[x-1][y-1]=='*'))              check_round(mine,show,x-1,y-1);          if ((x-1)>0&&(y)>0&&(show[x-1][y]=='*'))              check_round(mine,show,x-1,y);          if ((x-1)>0&&(y+1)>0&&(show[x-1][y+1]=='*'))              check_round(mine,show,x-1,y+1);          if ((x)>0&&(y-1)>0&&(show[x][y-1]=='*'))              check_round(mine,show,x,y-1);          if ((x)>0&&(y+1)>0&&(show[x][y+1]=='*'))              check_round(mine,show,x,y+1);          if ((x+1)>0&&(y-1)>0&&(show[x+1][y-1]=='*'))              check_round(mine,show,x+1,y-1);          if ((x+1)>0&&(y)>0&&(show[x+1][y]=='*'))              check_round(mine,show,x+1,y);          if ((x+1)>0&&(y+1)>0&&(show[x+1][y+1]=='*'))              check_round(mine,show,x+1,y+1);      }else          show[x][y]=ret+'0';  }  //统计周围雷数int count_num(char mine[ROWS][COLS],int x,int y)//统计周围的雷数  {      return mine[x-1][y-1]+          mine[x-1][y]+          mine[x-1][y+1]+          mine[x][y-1]+          mine[x][y+1]+          mine[x+1][y-1]+          mine[x+1][y]+          mine[x+1][y+1]-8*'0';  }  //检测是否排完雷int check_win(char mine[ROWS][COLS],char show[ROWS][COLS]){    int i=0;    int j=0;    for (i=1;i<ROW;i++){        for (j=1;j<COL;j++){            if (show[i][j]=='*'){                if (mine[i][j]!='1'){                return 0;                }            }        }    }     return 1;}int game(){    int i=0;    int x=0;    int y=0;    int n=0;    int mine_num=0;    char  mine[ROWS][COLS]={0};    char  show[ROWS][COLS]={0};    srand((unsigned int )time (NULL));    //选择难度    do{       level_board();//选择难度菜单       scanf("%d",&i);       mine_num=select_level(i);//根据输入,选择布置雷的数目    }    while ((i!=1)&&(i!=2)&&(i!=3));    Init_board(mine ,show );//初始化    Input_mine(mine,mine_num);//布雷    system("cls");//清屏    show_board(show,ROW,COL);//输出地图    while (1)    {      if ( (check_correct(&x,&y)) )//检测落子合法性      {            if (n==0)          {     first_step(mine,&x,&y);//判断第一次排雷是否触雷,若触雷则移除该地区地雷并在地图中另外随机生成一个新地雷                check_round(mine,show,x,y);//递归遍历                system("cls");                show_board(show,ROW,COL);                if ( (check_win(mine,show) ) )//判断是否排完雷                {                        printf("恭喜你!排雷成功!\n");                        printf("下图为雷区,1为雷,0为空\n");                        show_board(mine,ROW,COL);                        break;//结束循环                 }             n++;//n增1,下次循环不会执行上述代码             continue;//跳至循环头,输入排雷坐标          }          if ( (check_lose(mine,&x,&y)) )//触雷,游戏结束          {   break;          }          else          {               check_round(mine,show,x,y);               system("cls");               show_board(show,ROW,COL);             if ( (check_win(mine,show) ) )//判断是否排完雷             {               printf("恭喜你!排雷成功!\n");               printf("下图为雷区,1为雷,0为空\n");               show_board(mine,ROW,COL);               break;             }          }      }       else      {        printf("你输入的坐标有误!\n");      }    }   return 0;}

test.c

#define _CRT_SECURE_NO_WARNINGS 1     //放置游戏操作流程,用于测试#include "game.h"int main(){     int i=0;    do {        //打印棋盘        menu();        scanf("%d",&i);        //根据输入选择分支        switch(i){        case 1:            game ();//进入游戏程序            break;        case 0:            //退出程序            break;        default:            printf("输出有误!\n");            break;        }    }        while (i);     return 0;}

结尾:

本来可以加上计时器,记录排雷所花时间,但因为清屏,连同计时器一起删掉了…取舍之下就没有添加。功能较少,多多包涵。有意见建议欢迎留言^_^