/*the two must be even numbers and H_BLOCK_NUM must above
or equal 18,V_BLOCK_NUM must above or equal 12*/
#define LEFT 0x4b00
#define RIGHT 0x4d00
#define UP 0x4800
#define DOWN 0x5000
#define SPACE 0x3920
#define ESC 0x11b
#define TIMER 0x1c /*the code of timer-interrupt*/
unsigned short X=H_BLOCK_NUM*1/3-2,Y=0,
min_Hight=V_BLOCK_NUM,
TimerCounter=0,speed=8,
grade=1,total_del_line=0;
unsigned long total_scores=0;
void *block_image;
void interrupt (*oldhandler)();
void interrupt newhandler()
{
TimerCounter++;
oldhandler();
}
void start_timer(void interrupt(*IntProc)())
{
oldhandler=getvect(TIMER);
disable();
setvect(TIMER,IntProc);
enable();
}
void kill_timer()
{
disable();
setvect(TIMER,oldhandler);
enable();
}
unsigned short int shape[7][4][3]=/*shape,chahged_shape,can_down*/
{
0x00f0,0xee03,0x00f0,/* 0 I_shape*/
0x2222,0xccd1,0x0,/*must do special deal*/
0x00f0,0xee03,0x00f0,
0x2222,0xccd1,0x0,
0622,0154,0600,/* 1 L_shape*/
0170,0603,0160,
0223,0154,0201,
0074,0603,0070,
0071,0606,0070,/* 2 J_shape*/
0226,0550,0204,
0470,0303,0430,
0322,0055,0300,
0262,0514,0240,/* 3 T_shape*/
0270,0503,0250,
0232,0145,0210,
0072,0605,0070,
0066,0777,0060,/* 4 O_shape*/
0066,0777,0060,
0066,0777,0060,
0066,0777,0060,
0036,0301,0034,/* 5 S_shape*/
0231,0106,0210,
0036,0301,0034,
0231,0106,0210,
0132,0641,0120,/* 6 Z_shape*/
0063,0710,0061,
0132,0641,0120,
0063,0710,0061,
};
void init_block()
{
unsigned long size;
setcolor(WHITE);
setlinestyle(SOLID_LINE,0,NORM_WIDTH);
setfillstyle(6,RED);
rectangle(0,0,BLOCK_LEN-1,BLOCK_LEN-1); /*reduce 1 pixel is of the exist of NORM_WIDTH border*/
floodfill(3,3,WHITE);
size=imagesize(0,0,BLOCK_LEN+1,BLOCK_LEN+1);
block_image=malloc(size);
getimage(0,0,BLOCK_LEN,BLOCK_LEN,block_image);
putimage(0,0,block_image,XOR_PUT);
}
void main_frame()/*the basic frameset*/
{
int view_x0=MAX_X/2-H_BLOCK_NUM/2*BLOCK_LEN,
view_y0=MAX_Y/2-V_BLOCK_NUM/2*BLOCK_LEN,
view_x1=MAX_X/2+H_BLOCK_NUM/2*BLOCK_LEN,
view_y1=MAX_Y/2+V_BLOCK_NUM/2*BLOCK_LEN;
int line_x=BLOCK_LEN*(H_BLOCK_NUM-6);
char str[30]={0};
randomize();
setcolor(RED);
setlinestyle(SOLID_LINE,0,THIC_WIDTH);
setfillstyle(random(10)+2,random(15)+1);/*set rand fillstyle,but except EMPTY_FILL,SOLID_FILL and USER_FILL*/
rectangle(-3,-3,MAX_X+3,MAX_Y+3);/*draw it from (-1,-1)to(MAX_X+3,MAX_Y+3)can hidden the outside border*/
rectangle(view_x0-THIC_WIDTH+1,view_y0-THIC_WIDTH+1,/*as the border with 3 pixel*/
view_x1+1,view_y1+1); /*so let the rectangle extend 2 pixel in each direction*/
floodfill(0,0,RED); /*fill the backgroud those area that around the rectangle*/
setviewport(view_x0,view_y0,view_x1,view_y1,CLIP_OFF);
setlinestyle(SOLID_LINE,0,NORM_WIDTH);
line(line_x+1,0,line_x+1,view_y1);
line(line_x+10,0,line_x+10,view_y1);
setfillstyle(CLOSE_DOT_FILL,WHITE);
floodfill(line_x+4,4,RED);
settextstyle(0,0,1);
setcolor(0xff0033);
outtextxy((H_BLOCK_NUM-4)*BLOCK_LEN-5,6*BLOCK_LEN+10,"Scores");
setcolor(YELLOW);
outtextxy((H_BLOCK_NUM-4)*BLOCK_LEN-5,8*BLOCK_LEN+10,"Delline");
setcolor(WHITE);
outtextxy((H_BLOCK_NUM-4)*BLOCK_LEN-5,10*BLOCK_LEN+10,"Grade");
setcolor(BLUE);
outtextxy((H_BLOCK_NUM-5)*BLOCK_LEN-5,14*BLOCK_LEN,"Designer:Moon:)");
outtextxy((H_BLOCK_NUM-4)*BLOCK_LEN,15*BLOCK_LEN,"Fr:ECIT");
setcolor(BLUE);
rectangle((H_BLOCK_NUM-5)*BLOCK_LEN,7*BLOCK_LEN,(H_BLOCK_NUM-1)*BLOCK_LEN,8*BLOCK_LEN);
rectangle((H_BLOCK_NUM-5)*BLOCK_LEN,9*BLOCK_LEN,(H_BLOCK_NUM-1)*BLOCK_LEN,10*BLOCK_LEN);
rectangle((H_BLOCK_NUM-5)*BLOCK_LEN,11*BLOCK_LEN,(H_BLOCK_NUM-1)*BLOCK_LEN,12*BLOCK_LEN);
setcolor(0xff0033);
sprintf(str,"%9ld",total_scores);/*covert number to string*/
outtextxy((H_BLOCK_NUM-5)*BLOCK_LEN+2,7*BLOCK_LEN+10,str);
setcolor(YELLOW);
sprintf(str,"%9d",total_del_line);
outtextxy((H_BLOCK_NUM-5)*BLOCK_LEN+2,9*BLOCK_LEN+10,str);
setcolor(WHITE);
sprintf(str,"%5d",grade);
outtextxy((H_BLOCK_NUM-5)*BLOCK_LEN+2,11*BLOCK_LEN+10,str);
}
void ready_text()
{
setcolor(GREEN);
settextstyle(0,0,3);
outtextxy((H_BLOCK_NUM-6)/2*BLOCK_LEN-70,(V_BLOCK_NUM/2-2)*BLOCK_LEN,"Ready!");
sleep(3);
setfillstyle(SOLID_FILL,BLACK);
floodfill(5,5,RED);
}
void fill()
{
int i=0,j=0;
for(i=0;i
{
for(j=0;j
{
putimage(j*BLOCK_LEN,i*BLOCK_LEN,block_image,COPY_PUT);
}
}
}
void draw_image(unsigned short x,unsigned short y,unsigned short n,unsigned short N)
{
int i,j;
for(i=0;i
{
for(j=0;j>=1)
{
if(n&1)
{
putimage((x+j)*BLOCK_LEN,(y+i)*BLOCK_LEN,block_image,XOR_PUT);
}
}
}
}
int can_down(int A,int B,unsigned short N)
{
int i,j,n=shape[A][B][2];
if((A==0)&&(B==1||B==3))/*I shape*/
{
if(getpixel((X+1)*BLOCK_LEN,(Y+4)*BLOCK_LEN+2)!=BLACK)
return 0;
return 1;
}
for(i=1;i<=N;i++)
{
for(j=0;j>=1)
{
if(n&1)
{
if(getpixel((X+j)*BLOCK_LEN,(Y+i)*BLOCK_LEN+2)!=BLACK)
return 0;
}
}
}
return 1;
}
int can_up(unsigned short n,unsigned short N)
{
int i,j;
for(i=0;i
{
for(j=0;j>=1)
{
if(n&1)
{
if(getpixel((X+j)*BLOCK_LEN+1,(Y+i)*BLOCK_LEN+1)!=BLACK)
return 0;
}
}
}
return 1;
}
int can_left(int A,int B,unsigned short N)
{
int i,j,flag=1;
unsigned short n=shape[A][B][0];
if((A==0)&&(B==0||B==2))/* - shape*/
{
if(getpixel(X*BLOCK_LEN-1,(Y+1)*BLOCK_LEN)!=BLACK)
return 0;
return 1;
}
for(i=0;i
{
for(j=0;j>=1)
{
if((n&1)&&flag)
{
if(getpixel((X+j)*BLOCK_LEN-1,(Y+i)*BLOCK_LEN)==BLACK)
flag=0;
else
return 0;
}
}
flag=1;
}
return 1;
}
int can_right(int A,int B,unsigned short N)
{
int i,j;
unsigned short n=shape[A][B][0];
if((A==0)&&(B==0||B==2))/* - shape*/
{
if(getpixel((X+4)*BLOCK_LEN+1,(Y+1)*BLOCK_LEN+1)!=BLACK)
return 0;
return 1;
}
for(i=0;i>=1)
{
for(j=1;j>=1)
{
if(n&1)
{
if((n>>1)&1)
continue;
else if(getpixel((X+j)*BLOCK_LEN+1,(Y+i)*BLOCK_LEN+1)!=BLACK)
return 0;
}
}
if((n&1)&&getpixel((X+j)*BLOCK_LEN+1,(Y+i)*BLOCK_LEN+1)!=BLACK)/*the last block of a line is not blank*/
return 0;
}
return 1;
}
void eat_block(unsigned short N)
{
int i,j,k;
void *image;
unsigned int size;
short del_line_num=0;
char str[30]={0};
for(i=0;i
{
for(j=0;j
if(getpixel(j*BLOCK_LEN+2,(Y+i)*BLOCK_LEN)!=WHITE)
break;
if(j==H_BLOCK_NUM-6)/*this block_line can be eaten*/
{
size=imagesize(0,min_Hight*BLOCK_LEN,(H_BLOCK_NUM-6)*BLOCK_LEN,(Y+i)*BLOCK_LEN);
image=malloc(size);
getimage(0,min_Hight*BLOCK_LEN,(H_BLOCK_NUM-6)*BLOCK_LEN,(Y+i)*BLOCK_LEN-1,image);
putimage(0,min_Hight*BLOCK_LEN,image,XOR_PUT);
putimage(0,(min_Hight+1)*BLOCK_LEN,image,COPY_PUT);
free(image);
del_line_num++;
min_Hight++;
}
}
if(del_line_num)
{
switch(del_line_num)
{
case 1:total_scores+=100;total_del_line+=1;break;
case 2:total_scores+=200;total_del_line+=2;break;
case 3:total_scores+=400;total_del_line+=3;break;
case 4:total_scores+=800;total_del_line+=4;break;
}
setfillstyle(SOLID_FILL,BLACK);
floodfill((H_BLOCK_NUM-5)*BLOCK_LEN+2,7*BLOCK_LEN+10,BLUE);
floodfill((H_BLOCK_NUM-5)*BLOCK_LEN+2,9*BLOCK_LEN+10,BLUE);
settextstyle(0,0,1);
setcolor(WHITE);
sprintf(str,"%9ld",total_scores);
outtextxy((H_BLOCK_NUM-5)*BLOCK_LEN+2,7*BLOCK_LEN+10,str);
setcolor(YELLOW);
sprintf(str,"%9d",total_del_line);
outtextxy((H_BLOCK_NUM-5)*BLOCK_LEN+2,9*BLOCK_LEN+10,str);
if(total_scores>4000)
{
grade=2;
setcolor(WHITE);
sprintf(str,"%5d",grade);
floodfill((H_BLOCK_NUM-5)*BLOCK_LEN+2,11*BLOCK_LEN+10,BLUE);
outtextxy((H_BLOCK_NUM-5)*BLOCK_LEN+2,11*BLOCK_LEN+10,str);
}
else if(total_scores>10000)
grade=3;
}
}
void move()
{
unsigned short A,B,nextA,nextB,
N,M,
tip_X=H_BLOCK_NUM-5,tip_Y=1;
randomize();
A=random(7);
B=random(4);
start_timer(newhandler);/*start timer*/
while(1)
{
nextA=random(7);
nextB=random(4);
A?(N=3):(N=4);
nextA?(M=3):(M=4);
draw_image(tip_X,tip_Y,shape[nextA][nextB][0],M);/*draw the tip(next) iamge */
draw_image(X,Y,shape[A][B][0],N);
while(1)
{
if(bioskey(1))/*no key press down,bioskey(1) return 0*/
{
switch(bioskey(0))
{
case RIGHT:if(can_right(A,B,N))
{
draw_image(X++,Y,shape[A][B][0],N);
draw_image(X,Y,shape[A][B][0],N);
}break;
case LEFT:if(can_left(A,B,N))
{
draw_image(X--,Y,shape[A][B][0],N);
draw_image(X,Y,shape[A][B][0],N);
}
break;
case UP:if(A==4) break;/*O_shape do not change shape*/
if(can_up(shape[A][B][1],N))
{
draw_image(X,Y,shape[A][B][0],N);/*erase the formal image*/
if(++B==4)
B=0;
draw_image(X,Y,shape[A][B][0],N);/*draw the next changed shape*/
}
break;
case DOWN:speed=2;break;
case SPACE:draw_image(X,Y,shape[A][B][0],N);
while(can_down(A,B,N))
Y++;
draw_image(X,Y,shape[A][B][0],N);
break;
case ESC:kill_timer();return;
}
}
if(TimerCounter>speed)
{
if(grade==1)
speed=8;
else if(grade==2)
speed=4;
else
speed=2;
TimerCounter=0;
if(!can_down(A,B,N))
{
if(Y
min_Hight=Y;
if(Y<=0)
{
fill();
kill_timer();
return;
}
eat_block(N);
X=H_BLOCK_NUM*1/3-2;
Y=0;
A=nextA;
B=nextB;
draw_image(tip_X,tip_Y,shape[nextA][nextB][0],M);
break;
}
draw_image(X,Y++,shape[A][B][0],N);
draw_image(X,Y,shape[A][B][0],N);
}
}
}
}
int main()
{
int gdriver=DETECT,gmode;
initgraph(&gdriver,&gmode,"");
init_block();
main_frame();
ready_text();
move();
free(block_image);
getch();
closegraph();
return 0;
}