『楼 主』:
推箱子代碼及註釋
#include <dos.h>
#include <stdio.h>
#include <ctype.h>
#include <conio.h>
#include <bios.h>
#include <alloc.h>
char ghouse[20][20];
/* 用二维数组来表示平面图,0-空、b-箱子、w-墙、m-靶点、i-靶点上的箱子 */
char far* screen = (char far*) 0xb8000000;
/*十六位系统显存起始地址0xB8000000,直接写屏时用到*/
/* =============================================
=============================================== */
void putchxy(int x, int y, char ch, char fc, char bc)
{ /*处理写屏,各参数为坐标值、字符、前景色、背景色*/
screen[(x * 160) + (y * 2) + 0] = ch;
screen[(x * 160) + (y * 2) + 1] = (bc * 16) + 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(x - 1, y - 1, 10, BROWN, BLACK);
ghouse[x][y] = 'w';
}
/* =============================================
=============================================== */
void printbox(int x, int y) /*画箱子*/
{
putchxy( x- 1, y - 1, 20, WHITE, BLACK);
ghouse[x][y] = 'b';
}
/* =============================================
=============================================== */
void printwhiter0(int x, int y, winer ** win, winer ** pw) /*初始化靶点*/
{
/*~~~~~~~*/
winer* qw;
/*~~~~~~~*/
putchxy(x - 1, y - 1, 127, YELLOW, CYAN);
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) /*重画靶点*/
{
putchxy(x - 1, y - 1, 127, YELLOW, CYAN);
ghouse[x][y] = 'm';
}
/* =============================================
=============================================== */
void printman(int x, int y) /*画人*/
{
gotoxy(y, x);
_AL = 02; /*笑脸的ascii码是2*/
_CX = 01;
_AH = 0xa;
geninterrupt(0x10);
}
/* =============================================
=============================================== */
void printboxin(int x, int y) /*箱子推到目标后的处理*/
{
putchxy(x - 1, y - 1, 20, YELLOW, CYAN);
ghouse[x][y] = 'i';
}
/* =============================================
=============================================== */
void init()
{
/*~~~~~*/
int i, j;
/*~~~~~*/
for(i = 0; i < 20; i++) /*清零*/
for(j = 0; j < 20; j++) ghouse[i][j] = 0;
_AL = 3;
_AH = 0; /*设置显示方式80×25彩色方式*/
geninterrupt(0x10);
gotoxy(40, 5); /*以下在屏幕右侧显示常规信息*/
printf("Welcome to come box world!");
gotoxy(40, 8);
printf("Press up,down,left,right to play.");
gotoxy(40, 10);
printf("Press Esc to quit it.");
gotoxy(40, 12);
printf("Press space to reset the game.");
gotoxy(40, 14);
printf("Written by Lv Mingtao");
gotoxy(40, 16);
printf("Modifier bush@CDU");
}
/* =============================================
=============================================== */
winer* inithouse1() /*画第一关*/
{
/*~~~~~~~~~~~~~~~~~~~~*/
int x, y;
winer* win = NULL, *pw;
/*~~~~~~~~~~~~~~~~~~~~*/
/*下面的“+4”和“+10”目的是使画出的图形尽量居中*/
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(y = 3, x = 3; x <= 5; x++) printwall(x + 4, y + 10);
for(y = 8, x = 5; x <= 9; x++) printwall(x + 4, y + 10);
for(y = 4, x = 7; 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);
printwhiter0(4 + 4, 2 + 10, &win, &pw);
printwhiter0(5 + 4, 2 + 10, &win, &pw);
printwhiter0(6 + 4, 2 + 10, &win, &pw);
printman(2 + 4, 8 + 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(y = 7, x = 2; x <= 4; x++) printwall(x + 4, y + 10);
for(y = 1, x = 4; x <= 8; x++) printwall(x + 4, y + 10);
for(x = 8, y = 2; y <= 8; y++) printwall(x + 4, y + 10);
for(y = 8, x = 4; x <= 8; x++) printwall(x + 4, y + 10);
for(y = 6, x = 4; x <= 5; x++) printwall(x + 4, y + 10);
for(y = 2, x = 3; x <= 4; x++) printwall(x + 4, y + 10);
for(y = 4, x = 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);
printwhiter0(5 + 4, 7 + 10, &win, &pw);
printwhiter0(6 + 4, 7 + 10, &win, &pw);
printwhiter0(7 + 4, 7 + 10, &win, &pw);
printman(2 + 4, 6 + 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(y = 2, x = 2; x <= 4; x++) printwall(x + 4, y + 10);
for(x = 4, y = 1; y <= 3; y++) printwall(x + 4, y + 10);
for(y = 1, x = 5; x <= 8; x++) printwall(x + 4, y + 10);
for(x = 8, y = 2; y <= 5; y++) printwall(x + 4, y + 10);
for(y = 5, x = 5; x <= 7; x++) printwall(x + 4, y + 10);
for(x = 7, y = 6; y <= 9; y++) printwall(x + 4, y + 10);
for(y = 9, x = 3; 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);
printwhiter0(2 + 4, 5 + 10, &win, &pw);
printwhiter0(2 + 4, 6 + 10, &win, &pw);
printwhiter0(2 + 4, 7 + 10, &win, &pw);
printman(2 + 4, 4 + 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(y = 1, x = 2; 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(y = 9, x = 3; 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);
printwhiter0(3 + 4, 7 + 10, &win, &pw);
printwhiter0(4 + 4, 7 + 10, &win, &pw);
printwhiter0(5 + 4, 7 + 10, &win, &pw);
printwhiter0(4 + 4, 8 + 10, &win, &pw);
printwhiter0(5 + 4, 8 + 10, &win, &pw);
printman(2 + 4, 2 + 10);
return win;
}
/* =============================================
=============================================== */
winer* inithouse5() /*画第五关*/
{
/*~~~~~~~~~~~~~~~~~~~~*/
int x, y;
winer* win = NULL, *pw;
/*~~~~~~~~~~~~~~~~~~~~*/
for(x = 1, y = 1; y <= 5; y++) printwall(x + 6, y + 7);
for(y = 2, x = 4; x <= 6; x++) printwall(x + 6, y + 7);
for(y = 1, x = 2; x <= 4; x++) printwall(x + 6, y + 7);
for(x = 2, y = 5; y <= 12; y++) printwall(x + 6, y + 7);
for(x = 6, y = 3; y <= 12; y++) printwall(x + 6, y + 7);
for(y = 12, x = 3; x <= 5; x++) printwall(x + 6, y + 7);
printbox(3 + 6, 3 + 7);
printbox(4 + 6, 3 + 7);
for(y = 10, x = 3; x <= 5; x++) printbox(x + 6, y + 7);
printbox(4 + 6, 9 + 7);
for(x = 3; x <= 5; x++)
for(y = 6; y <= 7; y++) printwhiter0(x + 6, y + 7, &win, &pw);
printman(4 + 6, 11 + 7);
return win;
}
winer* inithouse6() /*第六关*/
{
int x,y;
winer* win=0,*pw;
for(x=5,y=5;y<=9;y++)printwhiter0(x,y,&win,&pw);
for(x=6,y=5;y<=9;y++)printwhiter0(x,y,&win,&pw);
printbox(11,6);
printbox(14,6);
printbox(10,7);
printbox(14,9);
printbox(13,10);
printbox(15,10);
printbox(13,11);
printbox(15,11);
printbox(11,11);
printbox(8,11);
printman(11,8);
for(x=4,y=4;x<=15;x++)printwall(x,y);
for(x=4,y=5;y<=10;y++) printwall(x,y);
for(x=5,y=10;x<=9;x++)printwall(x,y);
for(x=11,y=7;x<=14;x++)printwall(x,y);
for(x=6,y=13;x<=16;x++)printwall(x,y);
for(x=17,y=5;y<=13;y++)printwall(x,y);
printwall(6,11);
printwall(6,12);
printwall(15,5);
printwall(16,5);
printwall(9,5);
printwall(9,6);
printwall(9,7);
printwall(9,9);
printwall(13,8);
printwall(14,8);
printwall(11,9);
printwall(16,9);
printwall(11,10);
printwall(12,10);
printwall(11,12);
return win;
}
/* =============================================
=============================================== */
movebox(int x, int y, char a) /*推箱子到空地*/
{
switch(a) /*分别按上下左右处理*/
{
case 'u':
ghouse[x - 1][y] = 0; /*箱子推开后露出空地*/
printf(" ");
printbox(x - 2, y); /*箱子推到上面第二格*/
printman(x - 1, y); /*人向上一格*/
ghouse[x - 2][y] = 'b'; /*箱子挪动后要更改状态数组数据*/
break;
case 'd':
ghouse[x + 1][y] = 0;
printf(" ");
printbox(x + 2, y);
printman(x + 1, y);
ghouse[x + 2][y] = 'b';
break;
case 'l':
ghouse[x][y - 1] = 0;
printf(" ");
printbox(x, y - 2);
printman(x, y - 1);
ghouse[x][y - 2] = 'b';
break;
case 'r':
ghouse[x][y + 1] = 0;
printf(" ");
printbox(x, y + 2);
printman(x, y + 1);
ghouse[x][y + 2] = 'b';
break;
default:
break;
}
}
/* =============================================
=============================================== */
moveinbox(int x, int y, char a) /*将箱子从靶点推到空地*/
{
switch(a)
{
case 'u':
ghouse[x - 1][y] = 'm';
printf(" ");
printbox(x - 2, y);
printman(x - 1, y);
ghouse[x - 2][y] = 'b';
break;
case 'd':
ghouse[x + 1][y] = 'm';
printf(" ");
printbox(x + 2, y);
printman(x + 1, y);
ghouse[x + 2][y] = 'b';
break;
case 'l':
ghouse[x][y - 1] = 'm';
printf(" ");
printbox(x, y - 2);
printman(x, y - 1);
ghouse[x][y - 2] = 'b';
break;
case 'r':
ghouse[x][y + 1] = 'm';
printf(" ");
printbox(x, y + 2);
printman(x, y + 1);
ghouse[x][y + 2] = 'b';
break;
default:
break;
}
}
/* =============================================
=============================================== */
moveboxin(int x, int y, char a) /*推箱子到靶点*/
{
switch(a) /*分别按上下左右处理*/
{
case 'u':
ghouse[x - 1][y] = 0;
printf(" ");
printboxin(x - 2, y);
printman(x - 1, y);
ghouse[x - 2][y] = 'i';
break;
case 'd':
ghouse[x + 1][y] = 0;
printf(" ");
printboxin(x + 2, y);
printman(x + 1, y);
ghouse[x + 2][y] = 'i';
break;
case 'l':
ghouse[x][y - 1] = 0;
printf(" ");
printboxin(x, y - 2);
printman(x, y - 1);
ghouse[x][y - 2] = 'i';
break;
case 'r':
ghouse[x][y + 1] = 0;
printf(" ");
printboxin(x, y + 2);
printman(x, y + 1);
ghouse[x][y + 2] = 'i';
break;
default:
break;
}
}
/* =============================================
=============================================== */
moveinboxin(int x, int y, char a)
{ /*将箱子从一个靶点推到另一个靶点*/
switch(a)
{
case 'u':
ghouse[x - 1][y] = 'm';
printf(" ");
printboxin(x - 2, y);
printman(x - 1, y);
ghouse[x - 2][y] = 'i';
break;
case 'd':
ghouse[x + 1][y] = 'm';
printf(" ");
printboxin(x + 2, y);
printman(x + 1, y);
ghouse[x + 2][y] = 'i';
break;
case 'l':
ghouse[x][y - 1] = 'm';
printf(" ");
printboxin(x, y - 2);
printman(x, y - 1);
ghouse[x][y - 2] = 'i';
break;
case 'r':
ghouse[x][y + 1] = 'm';
printf(" ");
printboxin(x, y + 2);
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 'w': i = 0; break;
case 0: i = 1; break;
case 'b': i = 2; break;
case 'm': i = 3; break;
case 'i': i = 4; break;
default: break;
}
return i;
}
/* =============================================
=============================================== */
move(int x, int y, char a) /*走动*/
{
unsigned int tmp;
switch(a)
{
case 'u': /*向上走*/
tmp=judge(x-1,y);
if(!tmp)/*下一步是墙,放弃此次移动*/
{
gotoxy(y, x);
break;
}
else if(tmp == 1 || tmp == 3)
{ /*下一步是空格或靶点,可以移动*/
if(judge(x, y) == 3)/*当前位是靶点*/
{
printwhither(x, y); /*靶点重现*/
printman(x - 1, y); /*在新的位置画人*/
break;
}
else /*当前位是空地*/
{
printf(" ");
printman(x - 1, y);
break;
}
}
else if(tmp == 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(tmp == 4) /*下一步是靶点上的箱子*/
{
if((tmp=judge(x - 2, y)) == 1)
{
moveinbox(x, y, 'u');
if(judge(x, y) == 3) printwhither(x, y);
gotoxy(y, x - 1);
}
else if(tmp == 3)
{
moveinboxin(x, y, 'u');
if(judge(x, y) == 3) printwhither(x, y);
gotoxy(y, x - 1);
}
else
gotoxy(y, x);
break;
}
case 'd': /*下*/
tmp=judge(x+1,y);
if(!tmp)
{
gotoxy(y, x);
break;
}
else if(tmp == 1 || tmp == 3)
{
if(judge(x, y) == 3)
{
printwhither(x, y);
printman(x + 1, y);
break;
}
else
{
printf(" ");
printman(x + 1, y);
break;
}
}
else if(tmp == 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(tmp == 4)
{
if((tmp=judge(x + 2, y)) == 1)
{
moveinbox(x, y, 'd');
if(judge(x, y) == 3) printwhither(x, y);
gotoxy(y, x + 1);
}
else if(tmp == 3)
{
moveinboxin(x, y, 'd');
if(judge(x, y) == 3) printwhither(x, y);
gotoxy(y, x + 1);
}
else
gotoxy(y, x);
break;
}
case 'l': /*左*/
tmp=judge(x, y - 1);
if(!tmp)
{
gotoxy(y, x);
break;
}
else if(tmp == 1 || tmp == 3)
{
if(judge(x, y) == 3)
{
printwhither(x, y);
printman(x, y - 1);
break;
}
else
{
printf(" ");
printman(x, y - 1);
break;
}
}
else if(tmp == 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(tmp == 4)
{
if((tmp=judge(x, y - 2)) == 1)
{
moveinbox(x, y, 'l');
if(judge(x, y) == 3) printwhither(x, y);
gotoxy(y - 1, x);
}
else if(tmp == 3)
{
moveinboxin(x, y, 'l');
if(judge(x, y) == 3) printwhither(x, y);
gotoxy(y - 1, x);
}
else
gotoxy(y, x);
break;
}
case 'r': /*右*/
tmp=judge(x, y + 1);if(!tmp)
{
gotoxy(y, x);
break;
}
else if(tmp == 1 || tmp == 3)
{
if(judge(x, y) == 3)
{
printwhither(x, y);
printman(x, y + 1);
break;
}
else
{
printf(" ");
printman(x, y + 1);
break;
}
}
else if(tmp == 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(tmp == 4)
{
if((tmp=judge(x, y + 2)) == 1)
{
moveinbox(x, y, 'r');
if(judge(x, y) == 3) printwhither(x, y);
gotoxy(y + 1, x);
}
else if(tmp == 3)
{
moveinboxin(x, y, 'r');
if(judge(x, y) == 3) printwhither(x, y);
gotoxy(y + 1, x);
}
else
gotoxy(y, x);
break;
}
default:
break;
}
}
/* =============================================
=============================================== */
void reset(int i)
{ /* 按下空格键后,回到本关初始 */
switch(i)
{
case 0: init(); inithouse1(); break;
case 1: init(); inithouse2(); break;
case 2: init(); inithouse3(); break;
case 3: init(); inithouse4(); break;
case 4: init(); inithouse5(); break;
case 5: init(); inithouse6(); break; default: break;
}
}
/* =============================================
=============================================== */
int main()
{
/*~~~~~~~~~~~~~~~~~~~~~~~~*/
int key, x, y, s, i = 0;
winer* win, *pw;
/*~~~~~~~~~~~~~~~~~~~~~~~~*/
init();
win = inithouse1();
do
{
_AH = 3;
geninterrupt(0x10); /*读取光标位置,并存于x,y*/
x = _DH + 1;
y = _DL + 1;
while(bioskey(1) == 0);
key = bioskey(0); /*等待玩家按下一个键*/
switch(key) /*根据按下的上下左右或空格键做出反应*/
{
case 0x4800: move(x, y, 'u'); break;
case 0x5000: move(x, y, 'd'); break;
case 0x4b00: move(x, y, 'l'); break;
case 0x4d00: move(x, y, 'r'); break;
case 0x3920: reset(i); break;
default: break;
}
s = 0;
pw = win;
while(pw)
{ /*遍历链表,统计有几个靶点还没有箱子*/
if(ghouse[pw->x][pw->y] == 'm') s++;
pw = pw->p;
}
if(s == 0)/*过关*/
{
pw=win;
while(pw)
{
win=pw->p;
free(pw);
pw=win;
}
gotoxy(25, 2);
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:
init();
win = inithouse6();
break;
case 6:
gotoxy(15, 21);
printf("My dear Friend, How smart you are!\
Welcome to play again!");
key = 0x011b; /*预设一个键值从而跳出循环*/
getch();
break;
default:
break;
}
}
} while(key != 0x011b);
_AL = 3;
_AH = 0;
geninterrupt(0x10);
return 0;
}
[ Last edited by bush on 2005-11-25 at 17:13 ]
|