金贝壳蛋糕:求个 俄罗斯的源代码

来源:百度文库 编辑:杭州交通信息网 时间:2024/04/28 08:08:49

#include <graphics.h>
#include <stdio.h>
#include <dos.h>
#include <conio.h>
#include <time.h>
#include <math.h>
#include <stdlib.h>

/*定义左上角点在屏幕上的位置*/
#define MAPXOFT 9
#define MAPYOFT 5

/*定义下一个方块显示的位置*/
#define MAPXOFT1 13
#define MAPYOFT1 -2

#define LEFT 0x4b00
#define RIGHT 0x4d00
#define DOWN 0x5000 /*此键为加速键*/
#define UP 0x4800 /*此键为变形键*/
#define ESC 0x011b /*此键为退出键*/
#define ENTER 0x1c0d

#define TIMER 0x1c /* 时钟中断的中断号 */

/* 中断处理函数在C和C++中的表示略有不同。
如果定义了_cplusplus则表示在C++环境下,否则是在C环境下。 */

#ifdef __cplusplus
#define __CPPARGS ...
#else
#define __CPPARGS
#endif

int TimerCounter=0; /* 计时变量,每秒钟增加18。 */

/* 指向原来时钟中断处理过程入口的中断处理函数指针(句柄) */
void interrupt ( *oldhandler)(__CPPARGS);

/* 新的时钟中断处理函数 */
void interrupt newhandler(__CPPARGS)
{
/* increase the global counter */
TimerCounter++;

/* call the old routine */
oldhandler();
}

/* 设置新的时钟中断处理过程 */
void SetTimer(void interrupt (*IntProc)(__CPPARGS))
{
oldhandler=getvect(TIMER);
disable(); /* 设置新的时钟中断处理过程时,禁止所有中断 */
setvect(TIMER,IntProc);
enable(); /* 开启中断 */
}

/* 恢复原有的时钟中断处理过程 */
void KillTimer()
{
disable();
setvect(TIMER,oldhandler);
enable();
}

struct shape
{
int xy[8],next;
};

struct shape shapes[19]=
{
/*x1,y1,x2,y2,x3,y3,x4,y4 指四个小方块的相对坐标,next指此方块变形后应变为哪个小方块
{ x1,y1,x2,y2,x3,y3,x4,y4,next}*/
{ 0,-2, 0,-1, 0, 0, 1, 0, 1},
{-1, 0, 0, 0, 1,-1, 1, 0, 2},
{ 0,-2, 1,-2, 1,-1, 1, 0, 3},
{-1,-1,-1, 0, 0,-1, 1,-1, 0},
{ 0,-2, 0,-1, 0, 0, 1,-2, 5},
{-1,-1, 0,-1, 1,-1, 1, 0, 6},
{ 0, 0, 1,-2, 1,-1, 1, 0, 7},
{-1,-1,-1, 0, 0, 0, 1, 0, 4},
{-1, 0, 0,-1, 0, 0, 1, 0, 9},
{ 0,-2, 0,-1, 0, 0, 1,-1,10},
{-1,-1, 0,-1, 1,-1, 0, 0,11},
{ 0,-1, 1,-2, 1,-1, 1, 0, 8},
{-1, 0, 0,-1, 0, 0, 1,-1,13},
{ 0,-2, 0,-1, 1,-1, 1, 0,12},
{-1,-1, 0,-1, 0, 0, 1, 0,15},
{ 0,-1, 0, 0, 1,-2, 1,-1,14},
{ 0,-3, 0,-2, 0,-1, 0, 0,17},
{-1, 0, 0, 0, 1, 0, 2, 0,16},
{ 0,-1, 0, 0, 1,-1, 1, 0,18}
};

int board[10][20]={0};/*定义游戏板初始化为0*/
char sp[]="0",le[]="0",sc[]="00000";
int speed,speed0,level,score;
int sign,flag;
int style,style1; /*style为当前方块的种类,style1为即将输出的方块的种类*/

void draw_block(int x,int y,int style,int way);
void draw_little_block(int x,int y);
void init();
void initialize();
void speed_change(void);
void score_change(int);
void kill_line(int y);
void fill_board(int x,int y, int style);
int change(int *i,int *j,int key);
void renovate(void);
void ajustment(void);
void level_change(void);

main()
{
int i,j,key,x0=5,y0=1;
randomize();
while(!flag) /*flag为0表示重新开始游戏*/
{
level=score=speed=0;
strcpy(le,"0");
strcpy(sp,"0");
strcpy(sc,"00000");
for(i=0;i<10;i++)
for(j=0;j<20;j++)
board[i][j]=0; /*初始化一些变量为0*/
initialize(); /*初始化进入图形模式*/
init(); /*初始化游戏板记分器等*/
SetTimer(newhandler); /* 修改时钟中断 */
ajustment(); /*开始游戏前调整速度和高度*/

if(level>0)
level_change(); /*根据高度随机确定方块是否存在*/

style=random(19); /*随机确定方块种类*/

while(1)
{
i=x0,j=y0;

style1=random(19); /*随机确定即将出现的方块种类*/
setcolor(WHITE);
sign=1;
draw_block(MAPXOFT1,MAPYOFT1,style1,1);
/*画出即将出现的方块*/

for(j=y0;j<=20;j++) /*使方块下降*/
{

if(!check_block(i,j,style))
break;
draw_block(i,j,style,1);

while(1)
{
if(speed0==0) /*未按下加速键时的处理*/

{
if (TimerCounter>18/(speed+1))
{
/* 恢复计时变量 */
TimerCounter=0;
break;
}
}
else if(TimerCounter>18/(9+1))/*按下加速键时的处理*/
{
/* 恢复计时变量 */
TimerCounter=0;
speed0=0;
break;
}
if(bioskey(1))
{
key=bioskey(0);
if(change(&i,&j,key))/*根据按键值做调整*/
{
flag=1;
goto end;
}

}

}

draw_block(i,j,style,0);
renovate(); /*刷新屏幕*/

}

if(j==y0)
break;
j--;

draw_block(i,j,style,1);

fill_board(i,j,style);

sign=1;
draw_block(MAPXOFT1,MAPYOFT1,style1,0);
style=style1;
kill_line(j); /*消去的函数,消去若干行并改变分数和速度*/

while(bioskey(1)) /*清除内存中的按键*/
key=bioskey(0);
}
setcolor(CYAN);
settextstyle(0,0,2);
TimerCounter=0;

while(1)
if(TimerCounter>54)
{
TimerCounter=0;
break;
}
while(bioskey(1)) /*清除内存中的按键*/
key=bioskey(0);
outtextxy(400,340,"Game over!");
outtextxy(360,360,"Enter to replay.");
outtextxy(360,380,"Esc to quit.");
while(bioskey(1)==0);
key=bioskey(0);

end:;
closegraph();
KillTimer();
if(key==ESC||flag)
break;
}

}

void initialize()/*初始化进入图形模式*/
{
int gdriver = DETECT, gmode/*=VGAHI*/, errorcode;

/* initialize graphics mode */

initgraph(&gdriver, &gmode, "");

/* read result of initialization */
errorcode = graphresult();

if (errorcode != grOk) /* an error occurred */

{
printf("Graphics error: %s\n", grapherrormsg(errorcode));
printf("Press any key to halt:");
getch();
exit(1); /* return with error code */
}
}

void init(void)/*初始化游戏板记分器等*/
{
int x1;
x1=5+MAPXOFT;
setcolor(GREEN);
circle((x1+0.5)*16,(MAPYOFT-2)*16,3*16);
setcolor(WHITE);
line((x1-0.6)*16,(MAPYOFT-3.2)*16,x1*16,(MAPYOFT-3.2)*16);
line((x1+1.4)*16,(MAPYOFT-3.2)*16,(x1+2.0)*16,(MAPYOFT-3.2)*16);
line((x1+0.5)*16,(MAPYOFT-2)*16,(x1+0.5)*16,(MAPYOFT-1.7)*16);
circle((x1+0.5)*16,(MAPYOFT-0.9)*16,0.3*16);
setcolor(CYAN);
line((MAPXOFT+3)*16,(MAPYOFT+21)*16,MAPXOFT*16,(MAPYOFT+23.5)*16);
line((MAPXOFT+5.5)*16,(MAPYOFT+21)*16,MAPXOFT*16,(MAPYOFT+26)*16);
line((MAPXOFT+9)*16,(MAPYOFT+21)*16,(MAPXOFT+12)*16,(MAPYOFT+23.5)*16);
line((MAPXOFT+6.5)*16,(MAPYOFT+21)*16,(MAPXOFT+12)*16,(MAPYOFT+26)*16);
setcolor(MAGENTA);
ellipse((MAPXOFT+1)*16,(MAPYOFT+11)*16,90,270,7*16,7*16);
ellipse((MAPXOFT+11)*16,(MAPYOFT+11)*16,-90,90,7*16,7*16);
circle((MAPXOFT+24)*16,(MAPYOFT+6)*16,6*16);
setcolor(WHITE);
rectangle((x1-0.5)*16,(MAPYOFT-2.9)*16,(x1-0.1)*16,(MAPYOFT-2.5)*16);
rectangle((x1+1.5)*16,(MAPYOFT-2.9)*16,(x1+1.9)*16,(MAPYOFT-2.5)*16);
setcolor(YELLOW);
rectangle(10*16,6*16,20*16,26*16);
settextstyle(0,0,2);
outtextxy(5*16,13.5*16,"level");
outtextxy(20.4*16,13.5*16,"speed");
outtextxy((MAPXOFT+22)*16,(MAPYOFT+3)*16,"score");
settextstyle(0,0,4);
outtextxy(6.5*16,15*16,"0");
outtextxy(21.9*16,15*16,"0");
settextstyle(0,0,3);
outtextxy((MAPXOFT+21)*16,(MAPYOFT+6)*16,sc);
}

void ajustment(void) /*开始游戏前调整速度和高度*/
{
int key,boo=1,left=1;
setcolor(YELLOW);
settextstyle(0,0,2);
outtextxy(500,340,"PRESS");
outtextxy(500,360,"ENTER");
outtextxy(500,380," TO ");
outtextxy(500,400,"START");
while(1)
{
if(TimerCounter>8)
{
TimerCounter=0;
boo*=-1;
if(boo==-1)
setcolor(BLACK);
else
setcolor(YELLOW);
if(left==1)
{
line(6*16,17*16,8.5*16,17*16);
setcolor(BLACK);
line(21.4*16,17*16,23.9*16,17*16);
}

else
{
line(21.4*16,17*16,23.9*16,17*16);
setcolor(BLACK);
line(6*16,17*16,8.5*16,17*16);
}
}
if(bioskey(1))
{
key=bioskey(0);
if(key==UP||key==DOWN)
{
setcolor(BLACK);
settextstyle(0,0,4);
outtextxy(6.5*16,15*16,le);
outtextxy(21.9*16,15*16,sp);
}
if(key==ENTER)
break;
else if(key==UP)
{
if(left==1)
{
level--;
if(level==-1)
level=9;
}
else
{
speed--;
if(speed==-1)
speed=9;
}
}
else if(key==DOWN)
{
if(left==1)
{
level++;
if(level==10)
level=0;

}
else
{
speed++;
if(speed==10)
speed=0;
}
}

else if(key==LEFT||RIGHT)
left*=-1;
setcolor(YELLOW);
sp[0]=speed+'0';
le[0]=level+'0';
settextstyle(0,0,4);
outtextxy(6.5*16,15*16,le);
outtextxy(21.9*16,15*16,sp);
}
}
setcolor(YELLOW);
sp[0]=speed+'0';
le[0]=level+'0';
settextstyle(0,0,4);
outtextxy(6.5*16,15*16,le);
outtextxy(21.9*16,15*16,sp);
setcolor(BLACK);
line(21.4*16,17*16,23.9*16,17*16);
line(6*16,17*16,8.5*16,17*16);
settextstyle(0,0,2);
outtextxy(500,340,"PRESS");
outtextxy(500,360,"ENTER");
outtextxy(500,380," TO ");
outtextxy(500,400,"START");
}

void level_change(void) /*根据高度随机确定方块是否存在*/
{
int i,j;
setcolor(WHITE);
for(i=1;i<=10;i++)
for(j=1;j<=level;j++)
if(random(2))
{
board[i-1][20-j]=1;

draw_little_block(i+MAPXOFT,21-j+MAPYOFT);
}
}

void draw_block(int x,int y,int style,int way)
/*此x,y为虚拟坐标,为19中形式中的一种:0~18中的一个
x,y为10*20的方格的坐标,下标从1开始
way为1表填充,为0表清除*/
{
int x1=x+MAPXOFT,y1=y+MAPYOFT;
int i;
if(way==1)
setcolor(WHITE);
else
setcolor(BLACK);
for(i=0;i<=6;i+=2)
draw_little_block(x1+shapes[style].xy[i],y1+shapes[style].xy[i+1]);
if(sign==1)
sign=0;
}

void draw_little_block(int x,int y)/*此处仅在10*20的游戏版内画小方块,若在外,不画之。*/
{
if((x>=10&&x<20&&y>=6&&y<26)||sign)
{
rectangle(x*16,y*16,x*16+16,y*16+16);
circle(x*16+8,y*16+8,4);
}
}

int check_block(int x,int y,int style)/*此处检查在(x,y)处放置一方块是否可以,若是,则返回1,否则返回0*/
{
int x1=x+MAPXOFT,y1=y+MAPYOFT;
int x2,y2,i;
for(i=0;i<=6;i+=2)
{
x2=x1+shapes[style].xy[i];
y2=y1+shapes[style].xy[i+1];
if(x2>=10&&x2<20&&y2<26&&(y2<6||board[x2-10][y2-6]==0))
continue;
else
break;
}
if(i==8)
return 1;
else
return 0;
}

void speed_change(void) /*此为变速函数,当分数超过一级时,即加一。*/
{
if(score>=(sp[0]-'0')*100&&(sp[0]-'0')<9)
{
settextstyle(0,0,4);
setcolor(BLACK);
outtextxy(21.9*16,15*16,sp);
sp[0]++;
speed++;
settextstyle(0,0,4);
setcolor(YELLOW);
outtextxy(21.9*16,15*16,sp);
}
}

void score_change(int count) /*count为消去的行数,据此来改变score的值*/
{
int score_inc[4]={1,3,7,13};
int i;

setcolor(BLACK);
settextstyle(0,0,3);
outtextxy((MAPXOFT+21)*16,(MAPYOFT+6)*16,sc);/*此处将原有的分数盖掉*/

score+=score_inc[count-1];
sc[4]+=score_inc[count-1];
for(i=4;i>=1;i--)
{

sc[i-1]+=(sc[i]-'0')/10;
sc[i]-=(sc[i]-'0')/10*10;
}
setcolor(YELLOW);
settextstyle(0,0,3);
outtextxy((MAPXOFT+21)*16,(MAPYOFT+6)*16,sc); /*输出新分数*/
}

void kill_line(int y)/*消去的函数,消去若干行并改变分数和速度*/
{
int count=0,i,t=1,j,k;
for(;y>=1&&t<=4;y--,t++)
{
for(i=1;i<=10;i++)
if(!board[i-1][y-1])
break;
if(i==11)
{
count++;
for(k=1;k<=10;k++)
{
setcolor(BLACK);
draw_little_block(k+MAPXOFT,y+MAPYOFT);
}
for(j=y-1;j>=1;j--)
for(k=1;k<=10;k++)
{
board[k-1][j]=board[k-1][j-1];
if(board[k-1][j])
{
setcolor(BLACK);
draw_little_block(k+MAPXOFT,j+MAPYOFT);
setcolor(WHITE);
draw_little_block(k+MAPXOFT,j+1+MAPYOFT); }
}
renovate();
delay(10000);
y++;
}

}

if(count>0)
{

setcolor(CYAN);
settextstyle(0,0,3);
outtextxy(500,370,"Good!");
TimerCounter=0;
while(1)
if(TimerCounter>3)
{
TimerCounter=0;
break;
}

setcolor(BLACK);
settextstyle(0,0,3);
outtextxy(500,370,"Good!");

score_change(count);
speed_change();
}
}

void fill_board(int x,int y, int style) /*当一方块停止时,将中相应的值改为1*/
{

int x1,y1,i;
for(i=0;i<=6;i+=2)
{
x1=x+shapes[style].xy[i];
y1=y+shapes[style].xy[i+1];
board[x1-1][y1-1]=1;
}
}

int change(int *i,int *j,int key)/*控制方块移动、变形的函数*/
{
int key1;
if(key==UP&&check_block(*i,*j,shapes[style].next))
{
draw_block(*i,*j,style,0);
style=shapes[style].next;
draw_block(*i,*j,style,1);
}
else if(key==LEFT&&check_block(*i-1,*j,style))
{
draw_block(*i,*j,style,0);
(*i)--;
draw_block(*i,*j,style,1);
}
else if(key==RIGHT&&check_block(*i+1,*j,style))
{
draw_block(*i,*j,style,0);
(*i)++;
draw_block(*i,*j,style,1);
}
else if(key==DOWN&&check_block(*i,*j+1,style))
{
draw_block(*i,*j,style,0);
(*j)++;
draw_block(*i,*j,style,1);
speed0=9;
}
else if(key==ENTER)
{
while(1)
{

if(bioskey(1))
key1=bioskey(0);
if(key1==ENTER)
break;
}
}
else if(key==ESC)
return 1;
else if(key==21040)
{
sign=1;
draw_block(MAPXOFT1,MAPYOFT1,style1,0);
style1=16;
sign=1;
draw_block(MAPXOFT1,MAPYOFT1,style1,1);
}
return 0;
}

void renovate(void) /*刷新屏幕*/
{
int i,j;
setcolor(WHITE);
for(i=1;i<=10;i++)
for(j=1;j<=20;j++)
if(board[i-1][j-1]==1)
draw_little_block(i+MAPXOFT,j+MAPYOFT);

setcolor(YELLOW);
rectangle(10*16,6*16,20*16,26*16);

}
声明本程序并非本人所写,我也是下载的。但是程序运行过,没有错误并且功能也比较完善。如果有什么异常现象,肯定是缺少什么文件或者是设置错误。运行编译器TC2.0。