当前位置:文档之家› 推箱子游戏

推箱子游戏

陕西师范大学C语言课程设计推箱子院(系)别计科院班级信息管理与信息系统指导教师何秀青时间2015-6参与者:王杰王启星贾臻孙楠1.设计目的本程序涉及软中断,二维数组,键盘操作,图形化函数等方面的知识。

通过本程序的训练,能基本掌握显示器中断寄存器的设置,二维数组及结构体的应用,图形方式下光标的显示和定位,以及部分图形函数。

2.功能描述本游戏共有五关,由易到难,每关都有初始化,按键处理,充值和退出功能。

(1)初始化包括屏幕初始化和每一关关卡的初始化,屏幕被初始化为宽80像素,高25像素。

(2)按键处理包括移动小人和推动箱子,通过移动上下左右键控制小人移动,从而推动箱子,以把箱子推到指定的目的地为通关。

(3)每一关都可以重置,按空格键可以重置当前关卡。

(4)按Esc键可以在任何时候退出游戏。

3.总体设计(1)系统模块图初始化模块:该模块包括屏幕初始化和游戏每关的初始化,屏幕初始化用于输出欢迎信息和操作提示,游戏每关的初始化是构建每一关的关卡。

画图模块:画图模块主要被其他模块调用,用于画墙,在空地画箱子,在目的地画箱子,画小人和画目的地。

移动箱子模块:该模块用于移动箱子,包括目的地之间,空地之间和目的地与空地之间的箱子移动。

移动小人模块:该模块用于控制小人移动,从而推动箱子到目的地。

功能控制模块:该模块是几个功能函数的集合,包括屏幕输出功能,指定位置状态判断功能和关卡重置功能。

(2)任务执行流程图推箱子游戏初始化模块画图模块移动箱子模块移动小人模块功能控制模块否是否有 否是是 否(3)小人移动流程图小人移动方向有四个,move()函数(处理小人移动的函数)对这四个方向移动的处理都一致,只是调用函数时的参数有所不同。

首先判断小人的移动方向,然后根据小人所处的当前状态,下一步状态或者下下一步的状态进行适当的处理。

开始第一任务开始 是否继续完成 有无成功希望 是否成功 是否第六关进入下一任务 显示通关信息提示结束按Esc 键退出按空格键回到开始是否 否 是 是 否是 否 否否 是 是否是是 否 否否 是 是否是判断移动方向 下一步状态为w下一步状态为m 或0当前状态为m ? 输出空字符,调用PrintMan()调用PrintMan()和printDestination() 下一步状态为b?下下一步状态为0 下下一步状态为mmoveBoxSpacetoSpace() moveBoxSpacetoDes() 当前状态为m ? printDestination() 光标移动到下一步处下一步状态为i?下下一步状态为0 下下一步状态为mmoveBoxSpacetoSpace() moveBoxSpacetoDes() 当前状态为m ? printDestination()光标移动到下一步处读取下一键4.函数功能描述void printwall(int x,int y)在特定的坐标上画墙壁并用数组记录状态的函数void printbox(int x,int y)在特定的坐标上画箱子并用数组记录状态的函数void printwhither1(int x,int y,winer **win,winer **pw)在特定的坐标上画目的地并用数组记录目的地箱子状态的函数void printwhither(int x,int y)在特定的坐标上画目的地并用数组记录状态的函数void printman(int x,int y)在特定的坐标上画人的函数void printboxin(int x,int y)在特定的坐标上画箱子在目的地上并用数组记录状态的函数movebox(int x,int y,char a)移动在空地上的箱子到空地上moveinbox(int x,int y,char a)移动在目的地上的箱子到空地上moveboxin(int x,int y,char a)移动在空地上的箱子到目的地上moveinboxin(int x,int y,char a)移动在目的地上的箱子到目的地move(int x,int y,char a)处理按下键盘后,人物移动的主函数winer*initStep1(),winer*initStep2(),winer*initStep3()初始化游戏judge(intx,inty)根据结构体status[x][y]中存储的值来判断改点的状态5. 程序的实现#include <dos.h>#include <stdio.h>#include <ctype.h>#include <conio.h>#include <bios.h>#include <alloc.h>/* 定义二维数组ghouse来记录屏幕上各点的状态,其中:0表示什么都没有,'b'表示箱子,'w'表示墙壁,'m'表示目的地,'i'表示箱子在目的地。

*/char ghouse[20][20];/* 以下函数为直接写屏函数*/char far *screen=(char far* )0xb8000000;/* 彩色显示器的字符缓冲区首地址为0xB8000000 */ void putchxy(int y,int x,char ch,char fc,char bc){screen[(x*160)+(y<<1)+0]=ch;/* 赋值字符ascii码*/screen[(x*160)+(y<<1)+1]=(bc*26)+fc;/* 赋值字符颜色*/}/* 定义判断是否胜利的数据结构*/typedef struct winer{int x,y;struct winer *p;}winer;/* 箱子位置的数据结构*/typedef struct boxs{int x,y;struct boxs *next;}boxs;/* 在特定的坐标上画墙壁并用数组记录状态的函数*/void printwall(int x,int y){putchxy(y-1,x-1,8,YELLOW,BLACK);/* 8是显示墙的外型*/ghouse[x][y]='w';}/* 在特定的坐标上画箱子并用数组记录状态的函数*/void printbox(int x,int y){putchxy(y-1,x-1,10,GREEN,BLACK);/* 10是代表箱子外型的ascii码*/ghouse[x][y]='b';}/* 在特定的坐标上画目的地并用数组记录目的地箱子状态的函数*/void printwhither1(int x,int y,winer **win,winer **pw){winer *qw;putchxy(y-1,x-1,1,YELLOW,BLACK);ghouse[x][y]='m';if(*win==NULL)/* 如果当前是第一个点*/{*win=*pw=qw=(winer* )malloc(sizeof(winer));/* 为第一个点分配存储空间*/(*pw)->x=x;(*pw)->y=y;(*pw)->p=NULL;}else{qw=(winer* )malloc(sizeof(winer));/* 为以后的目的地分配存储空间*/qw->x=x;qw->y=y;(*pw)->p=qw;/* (*pw)指向qw所指向的节点*/(*pw)=qw;qw->p=NULL;}}/* 在特定的坐标上画目的地并用数组记录状态的函数*/void printwhither(int x,int y){putchxy(y-1,x-1,1,YELLOW,BLACK);ghouse[x][y]='m';}/* 在特定的坐标上画人的函数*/void printman(int x,int y){gotoxy(y,x);_AL=2;_CX=1;_AH=0xa;/* 设置寄存器_CX(小人)字符重复数为1 */ geninterrupt(0x10);/* 产生软中断,显示器输出,画出小人*/}/* 在特定的坐标上画箱子在目的地上并用数组记录状态的函数*/void printboxin(int x,int y){putchxy(y-1,x-1,10,YELLOW,BLACK);ghouse[x][y]='i';}/* 初始化函数,初始化数组和屏幕*/void init(){int i,j;for(i=0;i<20;i++)for(j=0;j<20;j++)/* 屏幕20*20范围内状态初始化为0,表示什么都没有*/ghouse[i][j]=0;/* 设置寄存器AX低位,80*25彩色方式显示*/_AL=3;/* 设置寄存器AX高位*/_AH=0;geninterrupt(0x10);/* 移动光标到指定位置输出屏幕信息*/gotoxy(41,4);printf(" --------- W/up");gotoxy(41,6);printf(" --------- S/down");gotoxy(41,8);printf(" --------- A/left");gotoxy(41,10);printf(" --------- D/right");gotoxy(40,12);printf("reset ----- R/space");gotoxy(40,14);printf("quit ------ Esc");gotoxy(18,24);/* 设置文本颜色*/textcolor(1);cprintf("jiege 7stars lanlan xibei");gotoxy(40,4);_CX=01;_AH=0xa;_AL=24;/* 画出向上箭头*/geninterrupt(0x10);gotoxy(40,6);_CX=01;_AH=0xa;_AL=25;/* 画出向下箭头*/geninterrupt(0x10);gotoxy(40,8);_CX=01;_AH=0xa;_AL=27;/* 画出向左箭头*/geninterrupt(0x10);gotoxy(40,10);_CX=01;_AH=0xa;_AL=26;/* 画出向右箭头*/geninterrupt(0x10);}/* 第一关的图象初始化*/ winer *inithouse1(){int x,y;winer *win=NULL,*pw;gotoxy(25,2);printf("Level 1");/* 在指定位置画墙*/for(x=1,y=5;y<=9;y++)printwall(x+4,y+10);for(y=5,x=2;x<=5;x++)printwall(x+4,y+10);for(y=9,x=2;x<=5;x++)printwall(x+4,y+10);for(y=1,x=3;x<=8;x++)printwall(x+4,y+10);for(x=3,y=3;x<=5;x++)printwall(x+4,y+10);for(x=5,y=8;x<=9;x++)printwall(x+4,y+10);for(x=7,y=4;x<=9;x++)printwall(x+4,y+10);for(x=9,y=5;y<=7;y++)printwall(x+4,y+10);for(x=8,y=2;y<=3;y++)printwall(x+4,y+10);printwall(5+4,4+10);printwall(5+4,7+10);printwall(3+4,2+10);/* 在指定位置画箱子*/printbox(3+4,6+10);printbox(3+4,7+10);printbox(4+4,7+10);/* 在指定位置画目的地*/printwhither1(4+4,2+10,&win,&pw);/* 返回目标位置的状态*/printwhither1(5+4,2+10,&win,&pw);printwhither1(6+4,2+10,&win,&pw);/* 在指定位置画小人*/printman(2+4,8+10);/* 返回win的值*/return win;}/* 第二关的图象初始化*/winer *inithouse2(){int x,y;winer *win=NULL,*pw;gotoxy(25,2);printf("Level 2");/* 在指定位置画墙*/for(x=1,y=4;y<=7;y++)printwall(x+4,y+10);for(x=2,y=2;y<=4;y++)printwall(x+4,y+10);for(x=2,y=7;x<=4;x++)printwall(x+4,y+10);for(x=4,y=1;x<=8;x++)printwall(x+4,y+10);for(x=8,y=2;y<=8;y++)printwall(x+4,y+10);for(x=4,y=8;x<=8;x++)printwall(x+4,y+10);for(x=4,y=6;x<=5;x++)printwall(x+4,y+10);for(x=3,y=2;x<=4;x++)printwall(x+4,y+10);for(x=4,y=4;x<=5;x++)printwall(x+4,y+10);printwall(6+4,3+10);/* 在指定位置画箱子*/printbox(3+4,5+10);printbox(6+4,6+10);printbox(7+4,3+10);/* 在指定位置画目的地*/printwhither1(5+4,7+10,&win,&pw);/* 返回目标位置的状态*/ printwhither1(6+4,7+10,&win,&pw);printwhither1(7+4,7+10,&win,&pw);/* 在指定位置画小人*/printman(2+4,6+10);return win;/* 返回win的值*/}/* 第三关的图象初始化*/winer *inithouse3(){int x,y;winer *win=NULL,*pw;gotoxy(25,2);printf("Level 3");/* 在指定位置画墙*/for(x=1,y=2;y<=8;y++)printwall(x+4,y+10);for(x=2,y=2;x<=4;x++)printwall(x+4,y+10);for(x=4,y=1;y<=3;y++)printwall(x+4,y+10);for(x=5,y=1;x<=8;x++)printwall(x+4,y+10);for(x=8,y=2;y<=5;y++)printwall(x+4,y+10);for(x=5,y=5;x<=7;x++)printwall(x+4,y+10);for(x=7,y=6;y<=9;y++)printwall(x+4,y+10);for(x=3,y=9;x<=6;x++)printwall(x+4,y+10);for(x=3,y=6;y<=8;y++)printwall(x+4,y+10);printwall(2+4,8+10);printwall(5+4,7+10);/* 在指定位置画箱子*/printbox(6+4,3+10);printbox(4+4,4+10);printbox(5+4,6+10);/* 在指定位置画目的地*/printwhither1(2+4,5+10,&win,&pw);printwhither1(2+4,6+10,&win,&pw);printwhither1(2+4,7+10,&win,&pw);/* 在指定位置画小人*/printman(2+4,4+10);return win;}/* 第四关的图象初始化*/winer *inithouse4(){int x,y;winer *win=NULL,*pw;gotoxy(25,2);printf("Level 4");/* 在指定位置画墙*/for(x=1,y=1;y<=6;y++)printwall(x+4,y+10);for(x=2,y=7;y<=8;y++)printwall(x+4,y+10);for(x=2,y=1;x<=7;x++)printwall(x+4,y+10);for(x=7,y=2;y<=4;y++)printwall(x+4,y+10);for(x=6,y=4;y<=9;y++)printwall(x+4,y+10);for(x=3,y=9;x<=5;x++)printwall(x+4,y+10);for(x=3,y=3;y<=4;y++)printwall(x+4,y+10);printwall(3+4,8+10);/* 在指定位置画箱子*/printbox(3+4,5+10);printbox(4+4,4+10);printbox(4+4,6+10);printbox(5+4,5+10);printbox(5+4,3+10);/* 在指定位置画目的地*/ printwhither1(3+4,7+10,&win,&pw); printwhither1(4+4,7+10,&win,&pw);printwhither1(5+4,7+10,&win,&pw); printwhither1(4+4,8+10,&win,&pw); printwhither1(5+4,8+10,&win,&pw); /* 在指定位置画小人*/ printman(2+4,2+10);return win;}/* 第五关的图象初始化*/winer *inithouse5(){int x,y;winer *win=NULL,*pw;gotoxy(25,2);printf("Level 5");/* 在指定位置画墙*/for(x=1,y=7;y<=11;y++)printwall(x+4,y+10);for(x=2,y=1;y<=7;y++)printwall(x+4,y+10);for(x=5,y=1;y<=2;y++)printwall(x+4,y+10);for(x=7,y=8;y<=11;y++)printwall(x+4,y+10);for(x=8,y=1;y<=8;y++)printwall(x+4,y+10);printwall(2+4,11+10);printwall(3+4,1+10);printwall(3+4,5+10);printwall(3+4,11+10);printwall(4+4,1+10);printwall(4+4,8+10);printwall(4+4,11+10);printwall(5+4,8+10);printwall(5+4,11+10);printwall(6+4,1+10);printwall(6+4,5+10);printwall(6+4,8+10);printwall(6+4,11+10);printwall(7+4,1+10);/* 在指定位置画箱子*/printbox(3+4,8+10);printbox(4+4,5+10);printbox(5+4,3+10);printbox(5+4,7+10);printbox(6+4,4+10);printbox(6+4,6+10);/* 在指定位置画目的地*/printwhither1(4+4,9+10,&win,&pw);printwhither1(4+4,10+10,&win,&pw);printwhither1(5+4,9+10,&win,&pw);printwhither1(5+4,10+10,&win,&pw);printwhither1(6+4,9+10,&win,&pw);printwhither1(6+4,10+10,&win,&pw);/* 在指定位置画小人*/printman(6+4,3+10);return win;}/* 移动在空地上的箱子到空地上*/ movebox(int x,int y,char a){switch(a){case 'u':/* 重设((x-1),y)位置的状态为0 */ghouse[x-1][y]=0;/* 清空(x,y)处原有的小人*/printf(" ");/* 在((x-2),y)处重新画箱子*/printbox(x-2,y);/* 在((x-1),y)处重新画小人*/printman(x-1,y);ghouse[x-2][y]='b';break;case 'd':/* 重设((x+1),y)位置的状态为0 */ghouse[x+1][y]=0;/* 清空(x,y)处原有的小人*/printf(" ");/* 在((x+2),y)处重新画箱子*/printbox(x+2,y);/* 在((x+1),y)处重新画小人*/printman(x+1,y);ghouse[x+2][y]='b';break;case 'l':/* 重设(x,(y-1))位置的状态为0 */ghouse[x][y-1]=0;/* 清空(x,y)处原有的小人*/printf(" ");/* 在(x,(y-2))处重新画箱子*/printbox(x,y-2);/* 在(x,(y-1))处重新画小人*/printman(x,y-1);ghouse[x][y-2]='b';break;case 'r':/* 重设(x,(y+1))位置的状态为0 */ghouse[x][y+1]=0;/* 清空(x,y)处原有的小人*/printf(" ");/* 在(x,(y+2))处重新画箱子*/printbox(x,y+2);/* 在(x,(y+1))处重新画小人*/printman(x,y+1);ghouse[x][y+2]='b';break;default: break;}}/* 移动在目的地上的箱子到空地上*/ moveinbox(int x,int y,char a){switch(a){case 'u':/* 重设((x-1),y)位置的状态为0 */ghouse[x-1][y]='m';/* 清空(x,y)处原有的小人*/printf(" ");/* 在((x-2),y)处重新画箱子*/printbox(x-2,y);/* 在((x-1),y)处重新画小人*/printman(x-1,y);ghouse[x-2][y]='b';break;case 'd':/* 重设((x+1),y)位置的状态为0 */ghouse[x+1][y]='m';/* 清空(x,y)处原有的小人*/printf(" ");printbox(x+2,y);/* 在((x+1),y)处重新画小人*/printman(x+1,y);ghouse[x+2][y]='b';break;case 'l':/* 重设(x,(y-1))位置的状态为0 */ghouse[x][y-1]='m';/* 清空(x,y)处原有的小人*/printf(" ");/* 在(x,(y-2))处重新画箱子*/printbox(x,y-2);/* 在(x,(y+1))处重新画小人*/printman(x,y-1);ghouse[x][y-2]='b';break;case 'r':/* 重设(x,(y+1))位置的状态为0 */ghouse[x][y+1]='m';/* 清空(x,y)处原有的小人*/printf(" ");/* 在(x,(y+2))处重新画箱子*/printbox(x,y+2);/* 在(x,(y+1))处重新画小人*/printman(x,y+1);ghouse[x][y+2]='b';break;default: break;}}/* 移动在空地上的箱子到目的地上*/ moveboxin(int x,int y,char a){switch(a){case 'u':/* 重设((x-1),y)位置的状态为0 */ghouse[x-1][y]=0;/* 清空(x,y)处原有的小人*/printf(" ");printboxin(x-2,y);/* 在((x-1),y)处重新画小人*/printman(x-1,y);ghouse[x-2][y]='i';break;case 'd':/* 重设((x+1),y)位置的状态为0 */ghouse[x+1][y]=0;/* 清空(x,y)处原有的小人*/printf(" ");/* 在(x,(y-2))处重新画箱子*/printboxin(x+2,y);/* 在(x,(y+1))处重新画小人*/printman(x+1,y);ghouse[x+2][y]='i';break;case 'l':/* 重设(x,(y-1))位置的状态为0 */ghouse[x][y-1]=0;/* 清空(x,y)处原有的小人*/printf(" ");/* 在(x,(y-2))处重新画箱子*/printboxin(x,y-2);/* 在(x,(y+1))处重新画小人*/printman(x,y-1);ghouse[x][y-2]='i';break;case 'r':/* 重设(x,(y+1))位置的状态为0 */ghouse[x][y+1]=0;/* 清空(x,y)处原有的小人*/printf(" ");/* 在(x,(y+2))处重新画箱子*/printboxin(x,y+2);/* 在(x,(y+1))处重新画小人*/printman(x,y+1);ghouse[x][y+2]='i';break;default: break;}}/* 移动在目的地上的箱子到目的地*/moveinboxin(int x,int y,char a){switch(a){case 'u':/* 重设((x-1),y)位置的状态为0 */ghouse[x-1][y]='m';/* 清空(x,y)处原有的小人*/printf(" ");/* 在((x-2),y)处重新画箱子*/printboxin(x-2,y);/* 在((x-1),y)处重新画小人*/printman(x-1,y);ghouse[x-2][y]='i';break;case 'd':/* 重设((x+1),y)位置的状态为0 */ghouse[x+1][y]='m';/* 清空(x,y)处原有的小人*/printf(" ");/* 在(x,(y+2))处重新画箱子*/printboxin(x+2,y);/* 在(x,(y+1))处重新画小人*/printman(x+1,y);ghouse[x+2][y]='i';break;case 'l':/* 重设(x,(y-1))位置的状态为0 */ghouse[x][y-1]='m';/* 清空(x,y)处原有的小人*/printf(" ");/* 在(x,(y-2))处重新画箱子*/printboxin(x,y-2);/* 在(x,(y+1))处重新画小人*/printman(x,y-1);ghouse[x][y-2]='i';break;case 'r':/* 重设(x,(y+1))位置的状态为0 */ghouse[x][y+1]='m';/* 清空(x,y)处原有的小人*/printf(" ");/* 在(x,(y+2))处重新画箱子*/printboxin(x,y+2);/* 在(x,(y+1))处重新画小人*/printman(x,y+1);ghouse[x][y+2]='i';break;default: break;}}/* 判断特定的坐标上的状态*/int judge(int x,int y){int i;switch(ghouse[x][y]){case 0: i=1;break;/* 0是空地*/case 'w': i=0;break;/* 1是墙*/case 'b': i=2;break;/* 2是箱子*/case 'i': i=4;break;/* 3是箱子在目的地*/case 'm': i=3;break;/* 4是目的地*/default: break;}return i;/* i是返回的此时小人的状态*/}/* 处理按下键盘后,人物移动的主函数*/move(int x,int y,char a){switch(a){/* 如果按下向上键*/case 'u':/* 如果(x-1,y)即小人下一步为墙*/if(!judge(x-1,y)){/*则跳转到(y,x),并跳出循环*/gotoxy(y,x);break;}/*如果小人的下一步状态为目的地或者什么都没有*/ else if(judge(x-1,y)==1||judge(x-1,y)==3){/*如果当前状态为目的地*/if(judge(x,y)==3){/*画目的地*/printwhither(x,y);/*在新位置重新画小人*/printman(x-1,y);break;}/*如果下一步状态为0*/else{/*输出空字符,覆盖当前状态的小人*/printf(" ");/*在下一步重新画小人*/printman(x-1,y);break;}}/*如果下一步状态是箱子*/else if(judge(x-1,y)==2){/*如果下下一步为空*/if(judge(x-2,y)==1){/*则将箱子从空地向上移动到空地*/movebox(x,y,'u');/*如果当前状态为目的地*/if(judge(x,y)==3)/*画目的地*/printwhither(x,y);gotoxy(y,x-1);}/*如果下下一步为目的地*/else if(judge(x-2,y)==3){/*则将箱子从空地向上移动到目的地*/moveboxin(x,y,'u');if(judge(x,y)==3) printwhither(x,y);gotoxy(y,x-1);}else gotoxy(y,x);break;}/*如果下一步状态是箱子在目的地*/else if(judge(x-1,y)==4){/*如果下下一步为空地*/if(judge(x-2,y)==1){moveinbox(x,y,'u');if(judge(x,y)==3) printwhither(x,y);gotoxy(y,x-1);}/*如果下下一步为目的地*/else if(judge(x-2,y)==3){moveinboxin(x,y,'u');if(judge(x,y)==3) printwhither(x,y);gotoxy(y,x-1);}else gotoxy(y,x);break;}/* 如果按下向下键*/case 'd':/* 如果(x+1,y)即小人下一步为墙*/if(!judge(x+1,y)){gotoxy(y,x);break;}/*如果小人的下一步状态为目的地或者什么都没有*/ else if(judge(x+1,y)==1||judge(x+1,y)==3){/*如果当前状态为目的地*/if(judge(x,y)==3){/*画目的地*/printwhither(x,y);/*在下一步重新画小人*/printman(x+1,y);break;}/*如果下一步状态为0*/else{/*输出空字符,覆盖当前状态的小人*/printf(" ");/*在下一步重新画小人*/printman(x+1,y);break;}}/*如果下一步状态是箱子*/else if(judge(x+1,y)==2){/*如果下下一步为空*/if(judge(x+2,y)==1){movebox(x,y,'d');/*如果当前状态为目的地*/if(judge(x,y)==3) printwhither(x,y);gotoxy(y,x+1);}/*如果下下一步为目的地*/else if(judge(x+2,y)==3){moveboxin(x,y,'d');/*如果当前状态为目的地*/if(judge(x,y)==3) printwhither(x,y);gotoxy(y,x+1);}else gotoxy(y,x);break;}/*如果下一步状态是箱子在目的地*/ else if(judge(x+1,y)==4){/*如果下下一步为空*/if(judge(x+2,y)==1){moveinbox(x,y,'d');if(judge(x,y)==3) printwhither(x,y);gotoxy(y,x+1);}/*如果下下一步为目的地*/else if(judge(x+2,y)==3){moveinboxin(x,y,'d');if(judge(x,y)==3) printwhither(x,y);gotoxy(y,x+1);}else gotoxy(y,x);break;}case 'l':/* 如果(x,y-1)即小人下一步为墙*/if(!judge(x,y-1)){gotoxy(y,x);break;}/*如果小人的下一步状态为目的地或者什么都没有*/ else if(judge(x,y-1)==1||judge(x,y-1)==3){/*如果当前状态为目的地*/if(judge(x,y)==3){/*画目的地*/printwhither(x,y);/*在下一步重新画小人*/printman(x,y-1);break;}/*如果下一步状态为0*/else{/*输出空字符,覆盖当前状态的小人*/printf(" ");/*在下一步重新画小人*/printman(x,y-1);break;}}/*如果下一步状态是箱子*/else if(judge(x,y-1)==2){/*如果下下一步为空*/if(judge(x,y-2)==1){movebox(x,y,'l');/*如果当前状态为目的地*/if(judge(x,y)==3) printwhither(x,y);gotoxy(y-1,x);}/*如果下下一步为目的地*/else if(judge(x,y-2)==3){moveboxin(x,y,'l');if(judge(x,y)==3) printwhither(x,y);gotoxy(y-1,x);}else gotoxy(y,x);break;}/*如果下一步状态是箱子在目的地*/else if(judge(x,y-1)==4){/*如果下下一步为空*/if(judge(x,y-2)==1){moveinbox(x,y,'l');if(judge(x,y)==3) printwhither(x,y);gotoxy(y-1,x);}/*如果下下一步为目的地*/else if(judge(x,y-2)==3){moveinboxin(x,y,'l');if(judge(x,y)==3) printwhither(x,y);gotoxy(y-1,x);}else gotoxy(y,x);break;}case 'r':/* 如果(x,y+1)即小人下一步为墙*/if(!judge(x,y+1)){gotoxy(y,x);break;}/*如果小人的下一步状态为目的地或者什么都没有*/ else if(judge(x,y+1)==1||judge(x,y+1)==3){/*如果当前状态为目的地*/if(judge(x,y)==3){printwhither(x,y);printman(x,y+1);break;}/*如果下一步状态为0*/else{printf(" ");printman(x,y+1);break;}}/*如果下一步状态是箱子*/else if(judge(x,y+1)==2){if(judge(x,y+2)==1){movebox(x,y,'r');/*如果当前状态为目的地*/if(judge(x,y)==3) printwhither(x,y);gotoxy(y+1,x);}else if(judge(x,y+2)==3){moveboxin(x,y,'r');/*如果当前状态为目的地*/if(judge(x,y)==3) printwhither(x,y);gotoxy(y+1,x);}else gotoxy(y,x);break;}/*如果下一步状态是箱子在目的地*/else if(judge(x,y+1)==4){if(judge(x,y+2)==1){moveinbox(x,y,'r');/*如果当前状态为目的地*/if(judge(x,y)==3) printwhither(x,y);gotoxy(y+1,x);}/*如果下下一步为目的地*/else if(judge(x,y+2)==3){moveinboxin(x,y,'r');/*如果当前状态为目的地*/if(judge(x,y)==3) printwhither(x,y);gotoxy(y+1,x);}else gotoxy(y,x);break;}default: break;}}/* 按下空格键或R后,回到本关开头的函数*/void reset(int i){switch(i){case 0: init();/* 第1关的重置*/inithouse1();break;case 1: init();/* 第2关的重置*/inithouse2();break;case 2: init();/* 第3关的重置*/inithouse3();break;case 3: init();/* 第4关的重置*/inithouse4();break;case 4: init();/* 第5关的重置*/inithouse5();break;default:break;}}/* 主函数main */void main(){int key,x,y,s,i=0;/* s记录未被推到目的地箱子的数量,i记录已经过了几关*/winer *win,*pw;_AL=3;_AH=1;/* 读取光标位置*/geninterrupt(0x10);/* 产生软中断,显示器输出*/init();/* 初始化状态*/win=inithouse1();do{_AH=3;geninterrupt(0x10);/* 软中断,显示屏幕*//* 读取光标所在行,列加1 */x=_DH+1;y=_DL+1;while(bioskey(1)==0);/* 循环检测按键返回0,直到有键按下*/key=bioskey(0);switch(key)/* 记录按下的键*/{case 0x4800:case 0x1177:move(x,y,'u');break; /* 按下W键或向上键后*/case 0x5000:case 0x1f73:move(x,y,'d');break; /* 按下S键或向下键后*/case 0x4b00:case 0x1e61:move(x,y,'l');break; /* 按下A键或向左键后*/case 0x4d00:case 0x2064:move(x,y,'r');break; /* 按下D键后或向右键*/case 0x3920:case 0x1372:reset(i);break; /* 按下R键后游戏重新开始*/default:break;}s=0;pw=win;while(pw)/* 如果指针为非空*/{/* 如果目的地的状态为m,不是i,表示还有箱子未被推到目的地,该关还未完成*/if(ghouse[pw->x][pw->y]=='m')/* 未被推到目的地的箱子数*/s++;/* 判断下一个目的地的状态*/pw=pw->p;}/* 该关完成*/if(s==0){free(win); /* 释放分配的空间*/gotoxy(280,22); /* 显示祝贺语位置!*/printf("congratulate! you did a good job!");getch(); /* 提示按任意键退出*/i++; /* 加关*/switch(i){case 1: init();/* 进入第二关*/win=inithouse2();break;case 2: init();/* 进入第三关*/win=inithouse3();break;case 3: init();/* 进入第四关*/win=inithouse4();break;case 4: init();/* 进入第五关*/win=inithouse5();break;case 5: gotoxy(220,22);printf("My dear Friend, Ho smart you are! Welcome to play again!");key=0x011b;getch();break;default: break;}}}while(key!=0x011b);/*按下Esc退出*/_AL=3;_AH=0;geninterrupt(0x10);}5.运行结果(1)游戏第一关(2)游戏第二关(3)游戏第三关(4)游戏第四关(5)游戏第五关(6)游戏通关。

相关主题