C语言如何实现自定义扫雷游戏
C语言如何实现自定义扫雷游戏
这篇“C语言如何实现自定义扫雷游戏”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“C语言如何实现自定义扫雷游戏”文章吧。
实现过程
对于用C语言实现扫雷游戏得实现,可将游戏过程分为两个板块。
实现游戏关键功能得函数
搭建合理得游戏过程
实现游戏关键功能
为了将游戏功能方便管理和键入,首先我们创建一个头文件,mine.h
对游戏功能进行声明。
然后创建对应的源文件mine.c
对这些函数进行定义。
对于游戏功能,我们首先想到的是构建一个目标规格的雷盘,也就是二维数组。
为了使游戏更具可玩性,所以雷盘的规格应可以自定义。所以在mine.h
头文件中,应先用define定义ROW(行)和列(列)的标识符便于自定义。
#defineROW15//先将他们的规格定义为15*15#defineCOL15#defineROWSROW+2#defineCOLSCOL+2
为什么要定义后面两个宏?
对于雷盘的的核心功能实现,必然是能够当玩家选择坐标以后(若该位置不是雷)能够精确的统计以该坐标为核心周围九宫格雷的个数,那么处于边界的地方该如何精准的判断呢?
所以将真正的雷盘数组规格定义ROW+2,COL+2大小,在ROW,COL规格的雷盘中随机置雷,使得游戏结果准确。
定义雷盘和显示盘的初始化
定义两同规格的二维数组,前者是真正的雷区,用‘1’和‘0’来表示雷和无雷,后者是显示区,用于玩家操作和结果显示。
voidinit(chararr[ROWS][COLS],introws,intcols,chartype)//memset批量操作时传入的是指针,即数组开始地址{memset(arr,type,rows*cols*sizeof(mine[0][0]));}
在显示区随机放置雷
voidsetmine(charmine[ROWS][COLS],intcount){srand((unsigned)time(NULL));inti=0;intj=0;while(count){i=(rand()%ROW)+1;//让随机值0-9变成1-10实现操作区随机放雷j=(rand()%COL)+1;if(mine[i][j]=='0'){mine[i][j]='1';count--;}}}
打印界面
voiddisplay(charboard[ROWS][COLS]){//从第一行一列开始打因元素inti=0;intj=0;printf("\n|");for(i=1;i<=COL;i++)//打印操作区的列号{printf("%4d",i);//打印序号}printf("\n");printf("------|------------------------------------------\n");for(i=1;i<=ROW;i++){printf("%4d|",i);//打印序号for(j=1;j<=COL;j++){printf("%4c",board[i][j]);}printf("\n\n");}}
统计目标点周围雷的个数
intcal_mine(charmine[ROWS][COLS],intx,inty){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]-(7*'0'));//这里减7而不是8。因为这样直接可以表示出数字字符//此处的目的是统计周围雷的个数,又因为是ASCII码,'1'和'0'只相差1,然后进去'0'的ASCII值得到1的个数}
如果目标点周围无雷向外扩展
在扫雷游戏过程中必然会出来一点一大片凹陷的强烈快感,但自己实现的过程中这是如何做到的呢?
原则是如果该点周围无雷,那么将用空格替代,然后向四周伸展将周围的“周围无雷点”继续用空格替代,若四周存在“周围有雷点”,那么停止向周围延伸。
在苦思冥想后,想到了用递归的方法来实现这个一点一大片功能。
voidexpand(charmine[ROWS][COLS],charboard[ROWS][COLS],intx,inty){if(x>=1&&x<=ROW&&y>=1&&y<=COL)//递归防止越界{/*if(mine[x][y]=='0')*/{charcount=cal_mine(mine,x,y);if(count=='0'){board[x][y]='';if(board[x-1][y-1]=='*'){expand(mine,board,x-1,y-1);}if(board[x-1][y]=='*'){expand(mine,board,x-1,y);}if(board[x-1][y+1]=='*'){expand(mine,board,x-1,y+1);}if(board[x][y-1]=='*'){expand(mine,board,x,y-1);}if(board[x][y+1]=='*'){expand(mine,board,x,y+1);}if(board[x+1][y-1]=='*'){expand(mine,board,x+1,y-1);}if(board[x+1][y]=='*'){expand(mine,board,x+1,y);}if(board[x+1][y+1]=='*'){expand(mine,board,x+1,y+1);}}else{board[x][y]=count;}}}}
判断胜利
若显示区最终剩下的*等于雷数,那么玩家胜利
intis_win(charboard[ROWS][COLS]){intcount=0;inti=0,j=0;for(i=1;i<=ROW;i++){for(j=1;j<=COL;j++){if('*'==board[i][j]){count++;}}}returncount;}
玩家操作
intplayer(charmine[ROWS][COLS],charboard[ROWS][COLS],intcount){intx=0,y=0;while(1)//检测输入错误区{while(2!=scanf("%d%d",&x,&y)){while((getchar()!='\n'))//如果玩家输入了很多非法字符,那么将他们全部吸收{NULL;}printf("输的是啥玩意?\n");}if(x<1||x>ROW||y<1||y>COL){printf("输入越界\n");}elseif(board[x][y]!='*'){printf("你踩过了!\n");}else{if(count==1&&(mine[x][y]=='1'))//!mine[x][y]=='1'这个条件特别重要!!如果玩家没有踩到雷那么将会使这个位置变成雷!!//虽然这样并不影响程序完整运行,因为检验雷点是通过存在的*来计数的,这个值附上去以后肯定恒为1占去了*,但是严谨的玩家肯定说你有BUG//所以我们还是尽量写通俗易懂的逻辑程序下面的while循环会让人感觉是检测,其实是赋值转换{inti=0,j=0;while(mine[x][y]=='1'){i=(rand()%10)+1;j=(rand()%10)+1;mine[x][y]=mine[i][j];//将值为符号零的元素赋给操作数,}mine[i][j]='1';//赋值如果成功那么便让他成为1}}break;}if(mine[x][y]=='1')//检验开始{printf("\n新时代的董存瑞!\n");return1;}else{expand(mine,board,x,y);}returnis_win(board);}
最后将这些声明和定义转入到mine.h
和mine.c
搭建合理的游戏过程
将这些函数功能合理的整个在一起后,在mian函数存在的源文件中创建定义game()函数,将每一步连接在一起。创建menu()函数显示菜单。
game()
voidgame(){printf("欢\n");Sleep(250);printf("迎\n");Sleep(250);printf("来\n");Sleep(250);printf("到\n");Sleep(250);printf("caco\n");Sleep(250);printf("的\n");Sleep(250);printf("扫\n");Sleep(250);printf("雷!\n");Sleep(250);printf("村");Sleep(250);printf("!");Sleep(150);printf("!");Sleep(150);charmine[ROWS][COLS]={0};charboard[ROWS][COLS]={0};init(mine,ROWS,COLS,'0');init(board,ROWS,COLS,'*');intnum=0;printf("\n要几个雷\n?");scanf("%d",&num);setmine(mine,num);display(mine);intcount=1;intret=0;while(1){display(board);ret=player(mine,board,count);count++;if(ret==num)//和玩家输入得雷数要保持一致{printf("炸不死得诺贝尔~!\n");break;}if(ret==1){break;//表示直接菜到雷退出}}}
munu()
voidmenu(){printf("*******************************************\n");printf("------我可以大口吞下炸弹而不伤身体--------\n");//label1.originaltest.printf("------1.进村-------------------------\n-------------------------\n");printf("------0.撤退!-------------------------\n");printf("*******************************************\n");}intmain(){inta=0;menu();do{scanf("%d",&a);switch(a){case1:game();menu();break;case0:return0;default:printf("\n进村还是不进?\n");}}while(a);}
main()函数
intmain(){inta=0;menu();do{scanf("%d",&a);switch(a){case1:game();menu();break;case0:return0;default:printf("\n进村还是不进?\n");}}while(a);}
程序展示
mine.h
#pragmaonce#defineROW15#defineCOL15#defineROWSROW+2#defineCOLSCOL+2voidinit(charmine[ROWS][COLS],introws,intcols,chartype);//初始化数组voidsetmine(charmine[ROWS][COLS],intcount);//放置随机雷voiddisplay(charboard[ROWS][COLS]);//显示界面intcal_mine(charmine[ROWS][COLS],intx,inty);//统计周围雷的个数intplayer(charmine[ROWS][COLS],charboard[ROWS][COLS],intcount);//玩家操作voidexpand(charmine[ROWS][COLS],charboard[ROWS][COLS],intx,inty);//递归展开intis_win(charboard[ROWS][COLS]);//判断胜利
mine.c
前文已展示定义
main.h
#define_CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<Windows.h>#include"mine.h"voidgame(){printf("欢\n");Sleep(250);printf("迎\n");Sleep(250);printf("来\n");Sleep(250);printf("到\n");Sleep(250);printf("caco\n");Sleep(250);printf("的\n");Sleep(250);printf("扫\n");Sleep(250);printf("雷!\n");Sleep(250);printf("村");Sleep(250);printf("!");Sleep(150);printf("!");Sleep(150);charmine[ROWS][COLS]={0};charboard[ROWS][COLS]={0};init(mine,ROWS,COLS,'0');init(board,ROWS,COLS,'*');intnum=0;printf("\n要几个雷\n?");scanf("%d",&num);setmine(mine,num);display(mine);intcount=1;intret=0;while(1){display(board);ret=player(mine,board,count);count++;if(ret==num)//和玩家输入得雷数要保持一致{printf("炸不死得诺贝尔~!\n");break;}if(ret==1){break;//表示直接菜到雷退出}}}voidmenu(){printf("*******************************************\n");printf("------我可以大口吞下炸弹而不伤身体--------\n");//label1.originaltest.printf("------1.进村-------------------------\n-------------------------\n");printf("------0.撤退!-------------------------\n");printf("*******************************************\n");}intmain(){inta=0;menu();do{scanf("%d",&a);switch(a){case1:game();menu();break;case0:return0;default:printf("\n进村还是不进?\n");}}while(a);}
程序运行
以上就是关于“C语言如何实现自定义扫雷游戏”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注恰卡编程网行业资讯频道。