/* 一个C语言编写的推箱子游戏源代码*//* 本游戏是字符模式的,请不要在中文dos下运行。
本游戏在TURBO C下调试通过*/程序预处理部分包括加载头文件、定义全局变量和定义数据结构,并对它们进行初始化工作。
#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,每一个字符占2个字节(第一个字节为ASCII值,第二个字节为颜色值),字符模式下屏幕宽80像素,高25像素,一屏可以写80*25个字符。
void putchxy(int y,int x,char ch,char fc,char bc)Putchxy()函数在屏幕上的指定位置输出指定的字符。
其中,x、y指明输出的位置,ch表示输出的字符,fc表示输出的字符颜色,bc 表示背景色。
{screen[(x*160)+(y<<1)+0]=ch; /*屏幕输出字符*/screen[(x*160)+(y<<1)+1]=(bc*16)+fc; /*指定字符颜色fc,背景色bc*/}/* 定义判断是否胜利的数据结构*/typedef struct winer {int x,y;struct winer *p;}winer;定义结构体struct winer用于判断每一关是否已完成。
其中x用于存放目的地的横坐标,y用于存放目的地的纵坐标。
如果所有表示目的地坐标对应的状态都为“i”,即箱子在目的地,则表示已经过关,可以进入下一关。
该结构体的初始化在每一关的初始化时进行。
/* 箱子位置的数据结构*/typedef struct boxs {int x,y;struct boxs *next;}boxs;/* 在特定的坐标上画墙壁并用数组记录状态的函数*/void printwall(int x,int y)printwall()用于画墙传入参数x、y指明位置。
该函数调用putoutChar()进行输出,以黑色为背景画绿色墙,用小方块表示墙(ASCII值为219)。
{ /*以黑色为背景画绿色墙,用小方块表示*/putchxy(y-1,x-1,219,GREEN,BLACK);/*记录状态为墙*/ghouse[x][y]='w';}/* 在特定的坐标上画箱子并用数组记录状态的函数*/void printbox(int x,int y) 用于在非目的地画箱子printBox()函数用于在非目的地画箱子,传入参数x、y指明位置。
该函数调用putchxy()进行输出,以黑色为背景白色箱子,用ASCII值为10的字符表示箱子。
{putchxy(y-1,x-1,10,WHITE,BLACK);ghouse[x][y]='b';}/* 在特定的坐标上画目的地并用数组记录状态的函数*/void printwhither1(int x,int y,winer **win,winer **pw) 画目的地函数,并记录每个目的地的位置。
void printwhither1()函数与printwhither1()函数功能基本相同,都是画目的地函数,但是printDestination1()增加了记录每一个目的地位置的功能。
其中x、y指明目的地的位置,每一关的所有目的地位置存放在结构体struct winer中,形成一条链表,**winer返回链表的头,**pw则指向链表的尾部。
{winer *qw;putchxy(y-1,x-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;qw->p=NULL;}}/* 在特定的坐标上画目的地并用数组记录状态的函数*/void printwhither(int x,int y) 画目的地函数Printwhither()函数用于画目的地,传入参数x、y指明位置。
该函数调用putoutChar()进行输出,以黑色为背景画黄色目的地,用‘*’型表示(ASCII值为003)。
{putchxy(y-1,x-1,'*',YELLOW,BLACK);ghouse[x][y]='m';}/* 在特定的坐标上画人的函数*/void printman(int x,int y)printman()函数用于画小人。
X、y指明画的位置。
该函数通过软中断来实现,首先设置寄存器AX的高位和低位,设置高位0xa表示在光标位置显示字符;设置低位02(ASCII值),表示输出的字符;然后设置寄存器CX为01,表示重复输出的次数,这里只输出一次;最后产生类型为0x10的中断,表示显示器输出。
{gotoxy(y,x);_AL=02;_CX=01;_AH=0xa;geninterrupt(0x10);}/* 在特定的坐标上画箱子在目的地上并用数组记录状态的函数*/void printboxin(int x,int y) 在目的地画箱子printboxin()函数用于在目的地画箱子,传入参数x、y指明位置。
该函数调用putchxy()进行输出,以黑色为背景画黄色箱子,仍用ASCII值为10的字符表示箱子。
{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;_AL=3; /*设置寄存器AX低位,80*25彩色方式显示*/_AH=0; /*设置寄存器AX高位*/geninterrupt(0x10);/*移动光标到指定位置输出屏幕信息*/gotoxy(40,4);printf("Welcome to come box world!"); 欢迎参加推箱子游戏gotoxy(40,6);printf("Press up,down,left,right to play.");/*按上下左右玩游戏*/gotoxy(40,8);printf("Press Esc to quit it."); /*按Esc退出游戏*/gotoxy(40,10);printf("Press space to reset the game.");/*按空格键重新开始游戏*/gotoxy(40,12);printf("Producer : wangdehao."); /*玩家玩的好*/gotoxy(40,14);printf("Mar. 30th 2003."); /*日期2003年3月30日*/}/* 第一关的图象初始化*/winer *inithouse1(){int x,y;winer *win=NULL,*pw;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);return win;}/* 第三关的图象初始化*/winer *inithouse3(){int x,y;winer *win=NULL,*pw;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 *inithouse2(){int x,y;winer *win=NULL,*pw;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;}/* 第四关的图象初始化*/winer *inithouse4(){int x,y;winer *win=NULL,*pw;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;}/* 移动在空地上的箱子到空地上*/movebox(int x,int y,char a) 把箱子从空地移动到空地。