#include <graphics.h>
#include <stdlib.h>
#include <bios.h>
#include <time.h>
#define ESC 0x001b
#define LEFT 0x4b00
#define RIGHT 0x4d00
#define UP 0x4800
#define SPACE 32
#define FKSIZE 15 /*方块大小*/
#define GFKSIZE (FKSIZE+2)/*方块列距大小*/
#define PSIZE1 1
#define PSIZE2 (GFKSIZE+1)
#define PSIZE3 (2*GFKSIZE+1)
#define PSIZE4 (3*GFKSIZE+1)
#define WTOP 50 /*游戏区域Y坐标起始值*/
#define WLEFT 180 /*游戏区域X坐标起始值*/
#define ROW 15 /*游戏区最大行数据*/
#define COLUNM 10 /*游戏区最大列数据*/
/*方块矢量位置(4个) */
int begin0[4]={PSIZE1,PSIZE2,PSIZE3,PSIZE4};
int GFKColor[7]={2,3,12,5,6,10,11};/*方块颜色列表*/
/*
方块形状共7种
方块坠落形态共19种(用如下方式表示)
1:
fk10[]“口”(x:位于列号[0,0,0,0] y:位于行号[0,1,2,3])
口 0 0 0
口 0 0 0
口 0 0 0
口 0 0 0
*/
int fk10[8]={0,0,0,0,0,1,2,3};
int fk11[8]={0,1,2,3,0,0,0,0};
int fk20[8]={0,0,1,1,0,1,0,1};
int fk30[8]={0,1,1,2,1,0,1,1};
int fk31[8]={0,0,0,1,0,1,2,1};
int fk32[8]={0,1,1,2,0,0,1,0};
int fk33[8]={0,1,1,1,1,0,1,2};
int fk40[8]={0,0,1,1,0,1,1,2};
int fk41[8]={0,1,1,2,1,0,1,0};
int fk50[8]={0,0,1,1,1,2,0,1};
int fk51[8]={0,1,1,2,0,0,1,1};
int fk60[8]={0,1,1,1,0,0,1,2};
int fk61[8]={0,1,2,2,1,1,0,1};
int fk62[8]={0,0,0,1,0,1,2,2};
int fk63[8]={0,0,1,2,0,1,0,0};
int fk70[8]={0,0,0,1,0,1,2,0};
int fk71[8]={0,1,2,2,0,0,0,1};
int fk72[8]={0,1,1,1,2,0,1,2};
int fk73[8]={0,0,1,2,0,1,1,1};
int *GFKP[19]={fk10,fk11,fk20,fk30,fk31,fk32,fk33,fk40,fk41,
fk50,fk51,fk60,fk61,fk62,fk63,fk70,fk71,fk72,fk73};
int index[7]={2,1,4,2,2,4,4};/*7种形状每种包括几种形态索引列表*/
int nextstyle[2]; /*保存形状([0])形态([1])*/
int nextrect[2][4];/*保存将要输出的方块*/
int newrectstyle[2]; /*新的形状形态*/
int drawrect[2][4]; /*游戏区输出方块*/
int hiderect[2][4]; /*游戏区清除方块*/
int GameTable[ROW][COLUNM];/*游戏区域*/
int FKColor[ROW][COLUNM];/*方块颜色缓存区*/
int RectColor;/*记录方块颜色*/
int ncolor=0;/*记录下一个方块颜色*/
int brow; /*动态行号*/
int bcol; /*动态列号*/
int score=0; /*记录成绩*/
int beginG=0;/*进入游戏标记*/
int speed=5;/*下落速度*/
int activesd;
char Mat[][24]={
0x11,0x00,0x11,0x00,0x20,0x80,0x20,0x80,
0x40,0x40,0xBF,0xA0,0x08,0x80,0x08,0x80,
0x10,0x80,0x20,0x80,0xC7,0x00,0x00,0x00,
0x95,0x00,0x59,0x00,0xFD,0xE0,0x32,0x40,
0x5A,0x40,0x95,0x40,0x21,0x40,0xFC,0x80,
0x48,0x80,0x39,0x40,0xC6,0x20,0x00,0x00,
0x00,0x40,0xFF,0xE0,0x04,0x00,0x04,0x00,
0x07,0x00,0x04,0x80,0x04,0x40,0x04,0x00,
0x04,0x00,0x04,0x00,0x04,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x40,0xFF,0xE0,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x04,0x00,0x0A,0x00,0x11,0x00,0x24,0x80,
0xC4,0x60,0x04,0x00,0x04,0x00,0x04,0x00,
0x04,0x00,0x04,0x00,0x04,0x00,0x00,0x00,
0x04,0x00,0x02,0x40,0xFF,0xE0,0x08,0x00,
0x0F,0x80,0x08,0x80,0x08,0x80,0x10,0x80,
0x10,0x80,0x20,0x80,0xC7,0x00,0x00,0x00,
0x42,0x00,0x42,0x00,0x4F,0xC0,0xF2,0x40,
0x42,0x40,0x42,0x40,0x5F,0xE0,0x42,0x00,
0xF5,0x00,0x88,0x80,0x30,0x60,0x00,0x00,
0x82,0x00,0x5F,0xE0,0x42,0x00,0x0F,0xC0,
0xCA,0x40,0x4F,0xC0,0x43,0x00,0x46,0x80,
0x5A,0x40,0xA2,0x00,0x9F,0xE0,0x00,0x00,
0x02,0x00,0x7F,0xE0,0x48,0x80,0x7F,0xE0,
0x48,0x80,0x4F,0x80,0x40,0x00,0x5F,0x80,
0x45,0x00,0x87,0x00,0xB8,0xE0,0x00,0x00,
0x20,0x40,0x2F,0xE0,0x42,0x40,0x92,0x80,
0xE2,0xC0,0x42,0x40,0x92,0x40,0xE5,0x40,
0x14,0x80,0xE9,0x40,0x16,0x20,0x00,0x00,
0x7C,0x20,0x44,0x20,0x45,0x20,0x7D,0x20,
0x11,0x20,0x11,0x20,0xFD,0x20,0x25,0x20,
0x25,0x20,0x44,0x20,0x98,0xE0,0x00,0x00,
0x20,0x00,0x27,0xE0,0xF1,0x20,0x11,0x20,
0x29,0x20,0x71,0x20,0xAA,0x20,0x22,0x20,
0x22,0x20,0x24,0x40,0x29,0xC0,0x00,0x00,
0x04,0x00,0x04,0x00,0x7F,0xC0,0x44,0x40,
0x44,0x40,0x44,0x40,0x7F,0xC0,0x04,0x00,
0x04,0x00,0x04,0x00,0x04,0x00,0x00,0x00,
0x04,0x00,0xFF,0xE0,0x00,0x00,0x1F,0x80,
0x10,0x80,0x7F,0xE0,0x40,0x20,0x5F,0x20,
0x51,0x20,0x5F,0x20,0x40,0xE0,0x00,0x00,
0x08,0x00,0x08,0x40,0xFF,0xE0,0x08,0x00,
0x10,0x00,0x1F,0xC0,0x22,0x00,0x22,0x00,
0x42,0x00,0x82,0x00,0x7F,0xE0,0x00,0x00,
0x04,0x00,0x04,0x00,0xFF,0xE0,0x08,0x00,
0x10,0x00,0x1F,0xC0,0x30,0x40,0x50,0x40,
0x90,0x40,0x1F,0xC0,0x10,0x40,0x00,0x00,
0x19,0x00,0xE3,0xE0,0x24,0x40,0xFA,0x80,
0x21,0x00,0x76,0x80,0x69,0xE0,0xA2,0x20,
0xAD,0x40,0x21,0x80,0x2E,0x00,0x00,0x00,
0x42,0x00,0x23,0xE0,0xF4,0x00,0x4F,0xE0,
0x71,0x20,0x55,0x40,0x55,0x00,0x55,0xE0,
0x55,0x00,0xB7,0x00,0x89,0xE0,0x00,0x00,
0x21,0x00,0xF9,0x00,0x47,0xE0,0x61,0x00,
0xA7,0xE0,0xFA,0x00,0x23,0xC0,0x38,0x40,
0xE0,0x80,0x23,0x00,0x20,0x80,0x00,0x00,
0x42,0x00,0x42,0x00,0x4F,0xC0,0xE2,0x40,
0xD2,0x40,0x42,0x40,0x5F,0xE0,0x42,0x00,
0x45,0x00,0x48,0x80,0x70,0x60,0x00,0x00,
0x11,0x00,0xFF,0xE0,0x55,0x00,0x27,0x80,
0x8C,0x80,0x53,0x00,0x24,0x80,0x5F,0xE0,
0xC8,0x80,0x48,0x80,0x4F,0x80,0x00,0x00,
0x23,0x00,0x2D,0x40,0x45,0x20,0x5F,0xE0,
0xC5,0x00,0x47,0x20,0x4D,0x40,0x54,0x80,
0x44,0xA0,0x45,0x60,0x5C,0x20,0x00,0x00,
0x7F,0xE0,0x49,0x20,0x49,0x20,0x7F,0xE0,
0x04,0x00,0x0F,0xC0,0x10,0x80,0x69,0x00,
0x06,0x00,0x0C,0x00,0xF0,0x00,0x00,0x00,
0x48,0x60,0xFD,0x80,0x49,0x00,0x79,0x00,
0x49,0xE0,0x79,0x40,0x49,0x40,0xFD,0x40,
0x2A,0x40,0x4A,0x40,0x84,0x40,0x00,0x00,
};
/*输出汉字*/
void OutCh(char *mat,int matsize,int x,int y,int color)
{
int i, j, k, n;
n = (matsize - 1) / 8 + 1;
for(j = 0; j < matsize; j++)
for(i = 0; i < n; i++)
for(k = 0;k < 8; k++)
if(mat[j * n + i] & (0x80 >> k))
putpixel(x + i * 8 + k, y + j, color);
}
/*绘制直线*/
void Line(int x1,int y1,int x2,int y2,int color)
{
int dr;
float r,c,k,dx,dy;
r=y2-y1;c=x2-x1; dx=x1;dy=y1;
if(abs(r)>abs(c))
{
if(r!=0)
{
k=c/r;
if(r>0)
{
for(dr=0;dr<=r;dr+=1)
{
putpixel(dx+0.5,y1+dr,color);
dx+=k;
}}
if(r<0)
{
dx=x2;
for(dr=0;dr<=-r;dr+=1)
{
putpixel(dx+0.5,y2+dr,color);
dx+=k;
}}}
else
{
if(c>0)
{
for(dr=0;dr<=r;dr+=1)
putpixel(x1+dr,y1,color);
}
if(c<0)
{
for(dr=r;dr<=0;dr+=1)
putpixel(x1+dr,y1,color);
}}}
else
{
if(c!=0)
{
k=r/c;
if(c>0)
{
for(dr=0;dr<=c;dr+=1)
{
putpixel(x1+dr,dy+0.5,color);
dy+=k;
}}
if(c<0)
{
dy=y2;
for(dr=0;dr<=-c;dr+=1)
{
putpixel(x2+dr,dy+0.5,color);
dy+=k;
}}}
else
{
if(r>0)
{
for(dr=0;dr<=r;dr+=1)
putpixel(x1,y1+dr,color);
}
if(r<0)
{
for(dr=r;dr<=0;dr+=1)
putpixel(x1,y1+dr,color);
}}}}
/*绘制并填充矩形图*/
void Rect(int x1,int y1,int x2,int y2,int color,int fillmode)
{
int r,c;
Line(x1,y1,x2,y1,color);
Line(x1,y2,x2,y2,color);
Line(x1,y1,x1,y2,color);
Line(x2,y1,x2,y2,color);
r=y2-y1;
c=x2-x1;
if(fillmode)
floodfill(x1+c/2,y1+r/2,color);
}
/*绘制条形栏(高亮在左边)*/
void LBar(int x1,int y1,int x2,int y2)
{
Rect(x1,y1,x2,y2,6,1);
Line(x1,y1,x1,y2,15);
Line(x1,y1,x2,y1,15);
Line(x2,y1,x2,y2,8);
Line(x1,y2,x2,y2,8);
}
/*游戏简易区域*/
void GameWind()
{
int i,j;
char s[5];
setfillstyle(1,1);
Rect(WLEFT-10,WTOP-40,WLEFT+COLUNM*GFKSIZE+100,WTOP-20,1,1);
Rect(WLEFT-10,WTOP-40,WLEFT+COLUNM*GFKSIZE+100,WTOP+390,9,0);
Line(WLEFT-9,WTOP-20,WLEFT+COLUNM*GFKSIZE+99,WTOP-20,8);
for(i=0;i<3;i++)
OutCh(Mat[i+21],12,WLEFT-5+i*13,WTOP-35,15);
for(i=0;i<2;i++)
OutCh(Mat[i+5],12,WLEFT-5+(i+3)*13,WTOP-35,15);
setfillstyle(1,4);
LBar(WLEFT+COLUNM*GFKSIZE+68,WTOP-35,WLEFT+COLUNM*GFKSIZE+95,WTOP-25);
setcolor(15);
outtextxy(WLEFT+COLUNM*GFKSIZE+70,WTOP-33,"ESC");
setfillstyle(1,8);
Rect(WLEFT,WTOP,WLEFT+COLUNM*GFKSIZE,WTOP+ROW*GFKSIZE,8,1);
for(i=0;i<=COLUNM;i++)
Line(WLEFT+i*GFKSIZE,WTOP,WLEFT+i*GFKSIZE,WTOP+ROW*GFKSIZE,3);
for(i=0;i<=ROW;i++)
Line(WLEFT,WTOP+i*GFKSIZE,WLEFT+COLUNM*GFKSIZE,WTOP+i*GFKSIZE,3);
setcolor(7);
for(i=0;i<2;i++)
OutCh(Mat[i],12,375+i*13,55,7);
sprintf(s,"%d",score);
outtextxy(375,75,s);
for(i=0;i<5;i++)
OutCh(Mat[i+2],12,375+i*13,105,7);
for(i=0;i<2;i++)
OutCh(Mat[i+7],12,375+i*13,205,7);
sprintf(s,"%d",speed);
outtextxy(375,225,s);
for(i=0;i<2;i++)
OutCh(Mat[i+9],12,375+i*13,250,7);
OutCh(Mat[11],12,375,275,7);
OutCh(Mat[9],12,388,275,7);
Rect(200,320,330,410,15,0);
OutCh(Mat[14],12,210,335,7);
OutCh(Mat[16],12,235,335,7);
OutCh(Mat[15],12,210,350,7);
OutCh(Mat[16],12,235,350,7);
OutCh(Mat[17],12,210,365,7);
OutCh(Mat[18],12,235,365,7);
OutCh(Mat[19],12,210,380,7);
OutCh(Mat[20],12,235,380,7);
outtextxy(250,335," - LEFT");
outtextxy(250,350," - RIGHT");
outtextxy(250,365," - UP");
outtextxy(250,380," - SPACE");
}
/*隐藏方块*/
void HideRect(int r,int c,int rt[2][4])
{
int j,ry,cx;
ry=WTOP+r*GFKSIZE;
cx=WLEFT+c*GFKSIZE;
setfillstyle(1,8);
for(j=0;j<4;j++)
{
Rect(begin0[rt[0][j]]+cx,begin0[rt[1][j]]+ry,
begin0[rt[0][j]]+cx+FKSIZE,begin0[rt[1][j]]+ry+FKSIZE,8,1);
GameTable[r+rt[1][j]][c+rt[0][j]]=0;
FKColor[r+rt[1][j]][c+rt[0][j]]=0;
}
}
/*显示方块*/
void ShowRect(int r,int c,int rt[2][4])
{
int i,j,ry,cx;
ry=WTOP+r*GFKSIZE;
cx=WLEFT+c*GFKSIZE;
setfillstyle(1,RectColor);
for(j=0;j<4;j++)
{
LBar(begin0[rt[0][j]]+cx,begin0[rt[1][j]]+ry,begin0[rt[0][j]]
+cx+FKSIZE,begin0[rt[1][j]]+ry+FKSIZE);
GameTable[r+rt[1][j]][c+rt[0][j]]=1;
FKColor[r+rt[1][j]][c+rt[0][j]]=RectColor;
}
for(i=0;i<2;i++)
for(j=0;j<4;j++)
hiderect[i][j]=rt[i][j];
for(i=0;i<speed;i++){delay(50000);}/*设置中断时间*/
}
/*获取方块类型索引号*/
int GetIndex(int fki,int fks)
{
int i,id;
id=fks;
if(fki>0)
for(i=0;i<fki;i++)
id+=index[i];
return id;
}
/*获取下个方块*/
void GetNextRect()
{
int i,c,rts,id;
srand(time(0));
rts=rand()%7;
id=rand()%index[rts];
ncolor=GFKColor[rts];
nextstyle[0]=rts;
nextstyle[1]=id;
id=GetIndex(rts,id);
if(beginG)/*游戏已开始清除方块*/
{
setfillstyle(1,0);
for(i=0;i<4;i++)
Rect(begin0[nextrect[0][i]]+375,begin0[nextrect[1][i]]+120,
begin0[nextrect[0][i]]+375+FKSIZE,begin0[nextrect[1][i]]+120+FKSIZE,0,1);
}
for(c=0;c<4;c++)/*获取下一个方块数据*/
{
nextrect[0][c]=GFKP[id][c];
nextrect[1][c]=GFKP[id][4+c];
}
setfillstyle(1,ncolor); /*显示新方块*/
for(i=0;i<4;i++)
LBar(begin0[nextrect[0][i]]+375,begin0[nextrect[1][i]]+120,
begin0[nextrect[0][i]]+375+FKSIZE,begin0[nextrect[1][i]]+120+FKSIZE);
}
/*获取游戏方块数据*/
void GetRectData()
{
int i,j;
for(i=0;i<2;i++)
{
newrectstyle[i]=nextstyle[i];
for(j=0;j<4;j++)
drawrect[i][j]=nextrect[i][j];
}
RectColor=ncolor;
}
/*获取最大值*/
int GetMax(int tm[4])
{
int i,max;
max=tm[0];
for(i=1;i<4;i++)
if(tm[i]>max)
max=tm[i];
return max;
}
/*判断向左称条件*/
int LMove()
{
int i,j,t,mr,tm;
mr=GetMax(drawrect[1]);
t=0;
for(i=0;i<=mr;i++)
{
for(j=3;j>=0;j--)
{
if(drawrect[1][j]==i)
tm=drawrect[0][j];
}
/*检测左接触面方块的上一列缓存空间有无方块*/
if(!GameTable[brow+i][bcol+tm-1])
t++;
}
if(t==mr+1) return 1;
else return 0;
}
/*判断向右移条件*/
int RMove()
{
int i,j,t,mr,tm;
mr=GetMax(drawrect[1]);
t=0;
for(i=0;i<=mr;i++)
{
for(j=0;j<4;j++)
{
if(drawrect[1][j]==i)
tm=drawrect[0][j];
}
/*检测右侧接触面方块的下一列缓存空间有无方块*/
if(!GameTable[brow+i][bcol+tm+1])
t++;
}
if(t==mr+1) return 1;
else return 0;
}
/*判断自由下落条件*/
int BMove()
{
int i,j,t,mc,tm;
mc=GetMax(drawrect[0]);
t=0;
for(i=0;i<=mc;i++)
{
for(j=0;j<4;j++)
{
if(drawrect[0][j]==i)
tm=drawrect[1][j];
}
/*检测位于最下面方块的下一行是否有空的缓存空间*/
if(brow+tm+1<ROW&&!GameTable[brow+tm+1][bcol+i])
t++;
}
if(t==mc+1) return 1;
else return 0;
}
/*方块初始化*/
void Rectinit()
{
int c,rts,id;
newrectstyle[0]=5;
newrectstyle[1]=2;
id=GetIndex(5,2);
RectColor=6;
activesd=speed;
for(c=0;c<4;c++)
{
drawrect[0][c]=GFKP[id][c];
drawrect[1][c]=GFKP[id][4+c];
}
}
/*清除满方块行*/
void ClearRect()
{
int i,j,k,cl,l,h;
char s[100];
for(i=ROW-1;i>=0;i--)
{
k=0;
for(j=0;j<COLUNM;j++)
{
if(GameTable[i][j])/*计算行中各列是否有方块*/
k++;
else
break;
}
if(k==COLUNM)/*满行*/
{
setfillstyle(1,8);
for(cl=0;cl<COLUNM;cl++) /*清除一行方块*/
{
Rect(WLEFT+1+cl*GFKSIZE,WTOP+1+i*GFKSIZE,WLEFT+
1+cl*GFKSIZE+FKSIZE,WTOP+1+i*GFKSIZE+FKSIZE,8,1);
GameTable[i][cl]=0; /*清空游戏区域缓存*/
FKColor[i][cl]=0;
}
/*输出成绩(分数)*/
sprintf(s,"%d",score);
setcolor(0);
outtextxy(375,75,s);
score+=100;
sprintf(s,"%d",score);
setcolor(7);
outtextxy(375,75,s);
/*据条件改变速度和级别*/
if(speed>1&&score>0&&score%5000==0)
{
setcolor(0);
sprintf(s,"%d",speed);
outtextxy(375,225,s);
speed--;
setcolor(7);
sprintf(s,"%d",speed);
outtextxy(375,225,s);
if(speed>3)
{
OutCh(Mat[11],12,375,275,0);
OutCh(Mat[12],12,375,275,7);
}
else
{
OutCh(Mat[12],12,375,275,0);
OutCh(Mat[13],12,375,275,7);
}
}
for(l=i;l>0;l--) /*上面的方块下移一行*/
{
for(h=0;h<COLUNM;h++)
{
if(GameTable[l-1][h])
{
setfillstyle(1,FKColor[l-1][h]);
LBar(WLEFT+1+h*GFKSIZE,WTOP+1+l*GFKSIZE,WLEFT+1
+h*GFKSIZE+FKSIZE,WTOP+1+l*GFKSIZE+FKSIZE);
GameTable[l][h]=1;/*方块存入清空的缓存区*/
FKColor[l][h]=FKColor[l-1][h];/*方块颜色写入缓存*/
setfillstyle(1,8);
Rect(WLEFT+1+h*GFKSIZE,WTOP+1+(l-1)*GFKSIZE,WLEFT+1
+h*GFKSIZE+FKSIZE,WTOP+1+(l-1)*GFKSIZE+FKSIZE,8,1);
GameTable[l-1][h]=0;/*把原来的缓存区清空*/
FKColor[l-1][h]=0;/*把原来的颜色变为背景色*/
}
}
}
ClearRect();/*函数递归*/
}
}
}
/*判断游戏是否结束条件*/
int GameOver()
{
int i;
for(i=0;i<4;i++)
{
if(GameTable[brow+drawrect[1][i]][bcol+drawrect[0][i]])/*检测游戏区域空间是否够容纳输出的新方块*/
return 0;
}
return 1;
}
/*有键按下*/
void KeyDown(int key)
{
int id,i,tm[2][4],w,h,mr,wb,wr,j,k=1;
if(key<<8)
key=key&0xff;
switch(key)
{
case ESC:
closegraph();
exit(0);
break;
case LEFT: /*方块左移*/
if(bcol>0)
{
if(LMove()&&!GameTable[brow][bcol-1])/*左移条件*/
{
HideRect(brow,bcol,hiderect);/*清除原来的方块区域(图像和缓存)*/
bcol-=1;
ShowRect(brow,bcol,drawrect);/*在新的位置显示方块(图像和保存行列号)*/
}
}
break;
case RIGHT: /*方块右移*/
w=GetMax(drawrect[0]);
if(bcol+w<COLUNM-1)
{
if(RMove()&&!GameTable[brow][bcol+1])
{
HideRect(brow,bcol,hiderect);
bcol+=1;
ShowRect(brow,bcol,drawrect);
}
}
break;
case UP: /*变换方块坠落形态*/
mr=newrectstyle[1];
mr++;
if(mr==index[newrectstyle[0]])
mr=0;
id=GetIndex(newrectstyle[0],mr);
for(i=0;i<4;i++)
{
tm[0][i]=GFKP[id][i];
tm[1][i]=GFKP[id][4+i];
}
w=GetMax(tm[0]);
h=GetMax(tm[1]);
if(bcol+w<=COLUNM-1&&brow+h<=ROW-1)
{
wb=GetMax(drawrect[0]);
if(wb>w)
wr=wb;
else
wr=w;
HideRect(brow,bcol,hiderect);
for(i=0;i<=h;i++)
for(j=0;j<=wr;j++)
{
/*检测方块变换空间如果在变换方块的行宽和列
高范围内有方块本次操作变换失败*/
if(GameTable[brow+i][bcol+j])
k=0;
}
if(k)
{
newrectstyle[1]=mr;
for(i=0;i<4;i++)
{
drawrect[0][i]=GFKP[id][i];
drawrect[1][i]=GFKP[id][4+i];
}
}
ShowRect(brow,bcol,drawrect);
}
break;
case SPACE:/*快速下落*/
activesd=speed;
speed=0;
break;
default: break;
}
}
/*游戏入口*/
void Game()
{
int i,key,mend=1;
GetNextRect();
brow=0;
bcol=4;
Rectinit();
ShowRect(brow,bcol,drawrect);
getch();
while(1)
{
key=0;
if(mend==0)
{
beginG=1;
GetRectData();
GetNextRect();
brow=0;
bcol=4;
speed=activesd;
ClearRect();
if(GameOver())
{
ShowRect(brow,bcol,drawrect);
mend=1;
}
else
{
printf("Game over!");
break;
}
}
HideRect(brow,bcol,hiderect);
if(bioskey(1))
key=bioskey(0);
KeyDown(key);
if(!key)/*方块自由下落*/
{
if(BMove())
brow++;
else
mend=0;
ShowRect(brow,bcol,drawrect);
}
}
}
/*初始化Win-TC图形模式*/
void init()
{
int dr=0,dm;
registerbgidriver(EGAVGA_driver);
initgraph(&dr, &dm, "");
}
void main()
{
init();
GameWind();
Game();
getch();
closegraph();
}#include <graphics.h>
#include <stdlib.h>
#include <bios.h>
#include <time.h>
#define ESC 0x001b
#define LEFT 0x4b00
#define RIGHT 0x4d00
#define UP 0x4800
#define SPACE 32
#define FKSIZE 15 /*方块大小*/
#define GFKSIZE (FKSIZE+2)/*方块列距大小*/
#define PSIZE1 1
#define PSIZE2 (GFKSIZE+1)
#define PSIZE3 (2*GFKSIZE+1)
#define PSIZE4 (3*GFKSIZE+1)
#define WTOP 50 /*游戏区域Y坐标起始值*/
#define WLEFT 180 /*游戏区域X坐标起始值*/
#define ROW 15 /*游戏区最大行数据*/
#define COLUNM 10 /*游戏区最大列数据*/
/*方块矢量位置(4个) */
int begin0[4]={PSIZE1,PSIZE2,PSIZE3,PSIZE4};
int GFKColor[7]={2,3,12,5,6,10,11};/*方块颜色列表*/
/*
方块形状共7种
方块坠落形态共19种(用如下方式表示)
1:
fk10[]“口”(x:位于列号[0,0,0,0] y:位于行号[0,1,2,3])
口 0 0 0
口 0 0 0
口 0 0 0
口 0 0 0
*/
int fk10[8]={0,0,0,0,0,1,2,3};
int fk11[8]={0,1,2,3,0,0,0,0};
int fk20[8]={0,0,1,1,0,1,0,1};
int fk30[8]={0,1,1,2,1,0,1,1};
int fk31[8]={0,0,0,1,0,1,2,1};
int fk32[8]={0,1,1,2,0,0,1,0};
int fk33[8]={0,1,1,1,1,0,1,2};
int fk40[8]={0,0,1,1,0,1,1,2};
int fk41[8]={0,1,1,2,1,0,1,0};
int fk50[8]={0,0,1,1,1,2,0,1};
int fk51[8]={0,1,1,2,0,0,1,1};
int fk60[8]={0,1,1,1,0,0,1,2};
int fk61[8]={0,1,2,2,1,1,0,1};
int fk62[8]={0,0,0,1,0,1,2,2};
int fk63[8]={0,0,1,2,0,1,0,0};
int fk70[8]={0,0,0,1,0,1,2,0};
int fk71[8]={0,1,2,2,0,0,0,1};
int fk72[8]={0,1,1,1,2,0,1,2};
int fk73[8]={0,0,1,2,0,1,1,1};
int *GFKP[19]={fk10,fk11,fk20,fk30,fk31,fk32,fk33,fk40,fk41,
fk50,fk51,fk60,fk61,fk62,fk63,fk70,fk71,fk72,fk73};
int index[7]={2,1,4,2,2,4,4};/*7种形状每种包括几种形态索引列表*/
int nextstyle[2]; /*保存形状([0])形态([1])*/
int nextrect[2][4];/*保存将要输出的方块*/
int newrectstyle[2]; /*新的形状形态*/
int drawrect[2][4]; /*游戏区输出方块*/
int hiderect[2][4]; /*游戏区清除方块*/
int GameTable[ROW][COLUNM];/*游戏区域*/
int FKColor[ROW][COLUNM];/*方块颜色缓存区*/
int RectColor;/*记录方块颜色*/
int ncolor=0;/*记录下一个方块颜色*/
int brow; /*动态行号*/
int bcol; /*动态列号*/
int score=0; /*记录成绩*/
int beginG=0;/*进入游戏标记*/
int speed=5;/*下落速度*/
int activesd;
char Mat[][24]={
0x11,0x00,0x11,0x00,0x20,0x80,0x20,0x80,
0x40,0x40,0xBF,0xA0,0x08,0x80,0x08,0x80,
0x10,0x80,0x20,0x80,0xC7,0x00,0x00,0x00,
0x95,0x00,0x59,0x00,0xFD,0xE0,0x32,0x40,
0x5A,0x40,0x95,0x40,0x21,0x40,0xFC,0x80,
0x48,0x80,0x39,0x40,0xC6,0x20,0x00,0x00,
0x00,0x40,0xFF,0xE0,0x04,0x00,0x04,0x00,
0x07,0x00,0x04,0x80,0x04,0x40,0x04,0x00,
0x04,0x00,0x04,0x00,0x04,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x40,0xFF,0xE0,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x04,0x00,0x0A,0x00,0x11,0x00,0x24,0x80,
0xC4,0x60,0x04,0x00,0x04,0x00,0x04,0x00,
0x04,0x00,0x04,0x00,0x04,0x00,0x00,0x00,
0x04,0x00,0x02,0x40,0xFF,0xE0,0x08,0x00,
0x0F,0x80,0x08,0x80,0x08,0x80,0x10,0x80,
0x10,0x80,0x20,0x80,0xC7,0x00,0x00,0x00,
0x42,0x00,0x42,0x00,0x4F,0xC0,0xF2,0x40,
0x42,0x40,0x42,0x40,0x5F,0xE0,0x42,0x00,
0xF5,0x00,0x88,0x80,0x30,0x60,0x00,0x00,
0x82,0x00,0x5F,0xE0,0x42,0x00,0x0F,0xC0,
0xCA,0x40,0x4F,0xC0,0x43,0x00,0x46,0x80,
0x5A,0x40,0xA2,0x00,0x9F,0xE0,0x00,0x00,
0x02,0x00,0x7F,0xE0,0x48,0x80,0x7F,0xE0,
0x48,0x80,0x4F,0x80,0x40,0x00,0x5F,0x80,
0x45,0x00,0x87,0x00,0xB8,0xE0,0x00,0x00,
0x20,0x40,0x2F,0xE0,0x42,0x40,0x92,0x80,
0xE2,0xC0,0x42,0x40,0x92,0x40,0xE5,0x40,
0x14,0x80,0xE9,0x40,0x16,0x20,0x00,0x00,
0x7C,0x20,0x44,0x20,0x45,0x20,0x7D,0x20,
0x11,0x20,0x11,0x20,0xFD,0x20,0x25,0x20,
0x25,0x20,0x44,0x20,0x98,0xE0,0x00,0x00,
0x20,0x00,0x27,0xE0,0xF1,0x20,0x11,0x20,
0x29,0x20,0x71,0x20,0xAA,0x20,0x22,0x20,
0x22,0x20,0x24,0x40,0x29,0xC0,0x00,0x00,
0x04,0x00,0x04,0x00,0x7F,0xC0,0x44,0x40,
0x44,0x40,0x44,0x40,0x7F,0xC0,0x04,0x00,
0x04,0x00,0x04,0x00,0x04,0x00,0x00,0x00,
0x04,0x00,0xFF,0xE0,0x00,0x00,0x1F,0x80,
0x10,0x80,0x7F,0xE0,0x40,0x20,0x5F,0x20,
0x51,0x20,0x5F,0x20,0x40,0xE0,0x00,0x00,
0x08,0x00,0x08,0x40,0xFF,0xE0,0x08,0x00,
0x10,0x00,0x1F,0xC0,0x22,0x00,0x22,0x00,
0x42,0x00,0x82,0x00,0x7F,0xE0,0x00,0x00,
0x04,0x00,0x04,0x00,0xFF,0xE0,0x08,0x00,
0x10,0x00,0x1F,0xC0,0x30,0x40,0x50,0x40,
0x90,0x40,0x1F,0xC0,0x10,0x40,0x00,0x00,
0x19,0x00,0xE3,0xE0,0x24,0x40,0xFA,0x80,
0x21,0x00,0x76,0x80,0x69,0xE0,0xA2,0x20,
0xAD,0x40,0x21,0x80,0x2E,0x00,0x00,0x00,
0x42,0x00,0x23,0xE0,0xF4,0x00,0x4F,0xE0,
0x71,0x20,0x55,0x40,0x55,0x00,0x55,0xE0,
0x55,0x00,0xB7,0x00,0x89,0xE0,0x00,0x00,
0x21,0x00,0xF9,0x00,0x47,0xE0,0x61,0x00,
0xA7,0xE0,0xFA,0x00,0x23,0xC0,0x38,0x40,
0xE0,0x80,0x23,0x00,0x20,0x80,0x00,0x00,
0x42,0x00,0x42,0x00,0x4F,0xC0,0xE2,0x40,
0xD2,0x40,0x42,0x40,0x5F,0xE0,0x42,0x00,
0x45,0x00,0x48,0x80,0x70,0x60,0x00,0x00,
0x11,0x00,0xFF,0xE0,0x55,0x00,0x27,0x80,
0x8C,0x80,0x53,0x00,0x24,0x80,0x5F,0xE0,
0xC8,0x80,0x48,0x80,0x4F,0x80,0x00,0x00,
0x23,0x00,0x2D,0x40,0x45,0x20,0x5F,0xE0,
0xC5,0x00,0x47,0x20,0x4D,0x40,0x54,0x80,
0x44,0xA0,0x45,0x60,0x5C,0x20,0x00,0x00,
0x7F,0xE0,0x49,0x20,0x49,0x20,0x7F,0xE0,
0x04,0x00,0x0F,0xC0,0x10,0x80,0x69,0x00,
0x06,0x00,0x0C,0x00,0xF0,0x00,0x00,0x00,
0x48,0x60,0xFD,0x80,0x49,0x00,0x79,0x00,
0x49,0xE0,0x79,0x40,0x49,0x40,0xFD,0x40,
0x2A,0x40,0x4A,0x40,0x84,0x40,0x00,0x00,
};
/*输出汉字*/
void OutCh(char *mat,int matsize,int x,int y,int color)
{
int i, j, k, n;
n = (matsize - 1) / 8 + 1;
for(j = 0; j < matsize; j++)
for(i = 0; i < n; i++)
for(k = 0;k < 8; k++)
if(mat[j * n + i] & (0x80 >> k))
putpixel(x + i * 8 + k, y + j, color);
}
/*绘制直线*/
void Line(int x1,int y1,int x2,int y2,int color)
{
int dr;
float r,c,k,dx,dy;
r=y2-y1;c=x2-x1; dx=x1;dy=y1;
if(abs(r)>abs(c))
{
if(r!=0)
{
k=c/r;
if(r>0)
{
for(dr=0;dr<=r;dr+=1)
{
putpixel(dx+0.5,y1+dr,color);
dx+=k;
}}
if(r<0)
{
dx=x2;
for(dr=0;dr<=-r;dr+=1)
{
putpixel(dx+0.5,y2+dr,color);
dx+=k;
}}}
else
{
if(c>0)
{
for(dr=0;dr<=r;dr+=1)
putpixel(x1+dr,y1,color);
}
if(c<0)
{
for(dr=r;dr<=0;dr+=1)
putpixel(x1+dr,y1,color);
}}}
else
{
if(c!=0)
{
k=r/c;
if(c>0)
{
for(dr=0;dr<=c;dr+=1)
{
putpixel(x1+dr,dy+0.5,color);
dy+=k;
}}
if(c<0)
{
dy=y2;
for(dr=0;dr<=-c;dr+=1)
{
putpixel(x2+dr,dy+0.5,color);
dy+=k;
}}}
else
{
if(r>0)
{
for(dr=0;dr<=r;dr+=1)
putpixel(x1,y1+dr,color);
}
if(r<0)
{
for(dr=r;dr<=0;dr+=1)
putpixel(x1,y1+dr,color);
}}}}
/*绘制并填充矩形图*/
void Rect(int x1,int y1,int x2,int y2,int color,int fillmode)
{
int r,c;
Line(x1,y1,x2,y1,color);
Line(x1,y2,x2,y2,color);
Line(x1,y1,x1,y2,color);
Line(x2,y1,x2,y2,color);
r=y2-y1;
c=x2-x1;
if(fillmode)
floodfill(x1+c/2,y1+r/2,color);
}
/*绘制条形栏(高亮在左边)*/
void LBar(int x1,int y1,int x2,int y2)
{
Rect(x1,y1,x2,y2,6,1);
Line(x1,y1,x1,y2,15);
Line(x1,y1,x2,y1,15);
Line(x2,y1,x2,y2,8);
Line(x1,y2,x2,y2,8);
}
/*游戏简易区域*/
void GameWind()
{
int i,j;
char s[5];
setfillstyle(1,1);
Rect(WLEFT-10,WTOP-40,WLEFT+COLUNM*GFKSIZE+100,WTOP-20,1,1);
Rect(WLEFT-10,WTOP-40,WLEFT+COLUNM*GFKSIZE+100,WTOP+390,9,0);
Line(WLEFT-9,WTOP-20,WLEFT+COLUNM*GFKSIZE+99,WTOP-20,8);
for(i=0;i<3;i++)
OutCh(Mat[i+21],12,WLEFT-5+i*13,WTOP-35,15);
for(i=0;i<2;i++)
OutCh(Mat[i+5],12,WLEFT-5+(i+3)*13,WTOP-35,15);
setfillstyle(1,4);
LBar(WLEFT+COLUNM*GFKSIZE+68,WTOP-35,WLEFT+COLUNM*GFKSIZE+95,WTOP-25);
setcolor(15);
outtextxy(WLEFT+COLUNM*GFKSIZE+70,WTOP-33,"ESC");
setfillstyle(1,8);
Rect(WLEFT,WTOP,WLEFT+COLUNM*GFKSIZE,WTOP+ROW*GFKSIZE,8,1);
for(i=0;i<=COLUNM;i++)
Line(WLEFT+i*GFKSIZE,WTOP,WLEFT+i*GFKSIZE,WTOP+ROW*GFKSIZE,3);
for(i=0;i<=ROW;i++)
Line(WLEFT,WTOP+i*GFKSIZE,WLEFT+COLUNM*GFKSIZE,WTOP+i*GFKSIZE,3);
setcolor(7);
for(i=0;i<2;i++)
OutCh(Mat[i],12,375+i*13,55,7);
sprintf(s,"%d",score);
outtextxy(375,75,s);
for(i=0;i<5;i++)
OutCh(Mat[i+2],12,375+i*13,105,7);
for(i=0;i<2;i++)
OutCh(Mat[i+7],12,375+i*13,205,7);
sprintf(s,"%d",speed);
outtextxy(375,225,s);
for(i=0;i<2;i++)
OutCh(Mat[i+9],12,375+i*13,250,7);
OutCh(Mat[11],12,375,275,7);
OutCh(Mat[9],12,388,275,7);
Rect(200,320,330,410,15,0);
OutCh(Mat[14],12,210,335,7);
OutCh(Mat[16],12,235,335,7);
OutCh(Mat[15],12,210,350,7);
OutCh(Mat[16],12,235,350,7);
OutCh(Mat[17],12,210,365,7);
OutCh(Mat[18],12,235,365,7);
OutCh(Mat[19],12,210,380,7);
OutCh(Mat[20],12,235,380,7);
outtextxy(250,335," - LEFT");
outtextxy(250,350," - RIGHT");
outtextxy(250,365," - UP");
outtextxy(250,380," - SPACE");
}
/*隐藏方块*/
void HideRect(int r,int c,int rt[2][4])
{
int j,ry,cx;
ry=WTOP+r*GFKSIZE;
cx=WLEFT+c*GFKSIZE;
setfillstyle(1,8);
for(j=0;j<4;j++)
{
Rect(begin0[rt[0][j]]+cx,begin0[rt[1][j]]+ry,
begin0[rt[0][j]]+cx+FKSIZE,begin0[rt[1][j]]+ry+FKSIZE,8,1);
GameTable[r+rt[1][j]][c+rt[0][j]]=0;
FKColor[r+rt[1][j]][c+rt[0][j]]=0;
}
}
/*显示方块*/
void ShowRect(int r,int c,int rt[2][4])
{
int i,j,ry,cx;
ry=WTOP+r*GFKSIZE;
cx=WLEFT+c*GFKSIZE;
setfillstyle(1,RectColor);
for(j=0;j<4;j++)
{
LBar(begin0[rt[0][j]]+cx,begin0[rt[1][j]]+ry,begin0[rt[0][j]]
+cx+FKSIZE,begin0[rt[1][j]]+ry+FKSIZE);
GameTable[r+rt[1][j]][c+rt[0][j]]=1;
FKColor[r+rt[1][j]][c+rt[0][j]]=RectColor;
}
for(i=0;i<2;i++)
for(j=0;j<4;j++)
hiderect[i][j]=rt[i][j];
for(i=0;i<speed;i++){delay(50000);}/*设置中断时间*/
}
/*获取方块类型索引号*/
int GetIndex(int fki,int fks)
{
int i,id;
id=fks;
if(fki>0)
for(i=0;i<fki;i++)
id+=index[i];
return id;
}
/*获取下个方块*/
void GetNextRect()
{
int i,c,rts,id;
srand(time(0));
rts=rand()%7;
id=rand()%index[rts];
ncolor=GFKColor[rts];
nextstyle[0]=rts;
nextstyle[1]=id;
id=GetIndex(rts,id);
if(beginG)/*游戏已开始清除方块*/
{
setfillstyle(1,0);
for(i=0;i<4;i++)
Rect(begin0[nextrect[0][i]]+375,begin0[nextrect[1][i]]+120,
begin0[nextrect[0][i]]+375+FKSIZE,begin0[nextrect[1][i]]+120+FKSIZE,0,1);
}
for(c=0;c<4;c++)/*获取下一个方块数据*/
{
nextrect[0][c]=GFKP[id][c];
nextrect[1][c]=GFKP[id][4+c];
}
setfillstyle(1,ncolor); /*显示新方块*/
for(i=0;i<4;i++)
LBar(begin0[nextrect[0][i]]+375,begin0[nextrect[1][i]]+120,
begin0[nextrect[0][i]]+375+FKSIZE,begin0[nextrect[1][i]]+120+FKSIZE);
}
/*获取游戏方块数据*/
void GetRectData()
{
int i,j;
for(i=0;i<2;i++)
{
newrectstyle[i]=nextstyle[i];
for(j=0;j<4;j++)
drawrect[i][j]=nextrect[i][j];
}
RectColor=ncolor;
}
/*获取最大值*/
int GetMax(int tm[4])
{
int i,max;
max=tm[0];
for(i=1;i<4;i++)
if(tm[i]>max)
max=tm[i];
return max;
}
/*判断向左称条件*/
int LMove()
{
int i,j,t,mr,tm;
mr=GetMax(drawrect[1]);
t=0;
for(i=0;i<=mr;i++)
{
for(j=3;j>=0;j--)
{
if(drawrect[1][j]==i)
tm=drawrect[0][j];
}
/*检测左接触面方块的上一列缓存空间有无方块*/
if(!GameTable[brow+i][bcol+tm-1])
t++;
}
if(t==mr+1) return 1;
else return 0;
}
/*判断向右移条件*/
int RMove()
{
int i,j,t,mr,tm;
mr=GetMax(drawrect[1]);
t=0;
for(i=0;i<=mr;i++)
{
for(j=0;j<4;j++)
{
if(drawrect[1][j]==i)
tm=drawrect[0][j];
}
/*检测右侧接触面方块的下一列缓存空间有无方块*/
if(!GameTable[brow+i][bcol+tm+1])
t++;
}
if(t==mr+1) return 1;
else return 0;
}
/*判断自由下落条件*/
int BMove()
{
int i,j,t,mc,tm;
mc=GetMax(drawrect[0]);
t=0;
for(i=0;i<=mc;i++)
{
for(j=0;j<4;j++)
{
if(drawrect[0][j]==i)
tm=drawrect[1][j];
}
/*检测位于最下面方块的下一行是否有空的缓存空间*/
if(brow+tm+1<ROW&&!GameTable[brow+tm+1][bcol+i])
t++;
}
if(t==mc+1) return 1;
else return 0;
}
/*方块初始化*/
void Rectinit()
{
int c,rts,id;
newrectstyle[0]=5;
newrectstyle[1]=2;
id=GetIndex(5,2);
RectColor=6;
activesd=speed;
for(c=0;c<4;c++)
{
drawrect[0][c]=GFKP[id][c];
drawrect[1][c]=GFKP[id][4+c];
}
}
/*清除满方块行*/
void ClearRect()
{
int i,j,k,cl,l,h;
char s[100];
for(i=ROW-1;i>=0;i--)
{
k=0;
for(j=0;j<COLUNM;j++)
{
if(GameTable[i][j])/*计算行中各列是否有方块*/
k++;
else
break;
}
if(k==COLUNM)/*满行*/
{
setfillstyle(1,8);
for(cl=0;cl<COLUNM;cl++) /*清除一行方块*/
{
Rect(WLEFT+1+cl*GFKSIZE,WTOP+1+i*GFKSIZE,WLEFT+
1+cl*GFKSIZE+FKSIZE,WTOP+1+i*GFKSIZE+FKSIZE,8,1);
GameTable[i][cl]=0; /*清空游戏区域缓存*/
FKColor[i][cl]=0;
}
/*输出成绩(分数)*/
sprintf(s,"%d",score);
setcolor(0);
outtextxy(375,75,s);
score+=100;
sprintf(s,"%d",score);
setcolor(7);
outtextxy(375,75,s);
/*据条件改变速度和级别*/
if(speed>1&&score>0&&score%5000==0)
{
setcolor(0);
sprintf(s,"%d",speed);
outtextxy(375,225,s);
speed--;
setcolor(7);
sprintf(s,"%d",speed);
outtextxy(375,225,s);
if(speed>3)
{
OutCh(Mat[11],12,375,275,0);
OutCh(Mat[12],12,375,275,7);
}
else
{
OutCh(Mat[12],12,375,275,0);
OutCh(Mat[13],12,375,275,7);
}
}
for(l=i;l>0;l--) /*上面的方块下移一行*/
{
for(h=0;h<COLUNM;h++)
{
if(GameTable[l-1][h])
{
setfillstyle(1,FKColor[l-1][h]);
LBar(WLEFT+1+h*GFKSIZE,WTOP+1+l*GFKSIZE,WLEFT+1
+h*GFKSIZE+FKSIZE,WTOP+1+l*GFKSIZE+FKSIZE);
GameTable[l][h]=1;/*方块存入清空的缓存区*/
FKColor[l][h]=FKColor[l-1][h];/*方块颜色写入缓存*/
setfillstyle(1,8);
Rect(WLEFT+1+h*GFKSIZE,WTOP+1+(l-1)*GFKSIZE,WLEFT+1
+h*GFKSIZE+FKSIZE,WTOP+1+(l-1)*GFKSIZE+FKSIZE,8,1);
GameTable[l-1][h]=0;/*把原来的缓存区清空*/
FKColor[l-1][h]=0;/*把原来的颜色变为背景色*/
}
}
}
ClearRect();/*函数递归*/
}
}
}
/*判断游戏是否结束条件*/
int GameOver()
{
int i;
for(i=0;i<4;i++)
{
if(GameTable[brow+drawrect[1][i]][bcol+drawrect[0][i]])/*检测游戏区域空间是否够容纳输出的新方块*/
return 0;
}
return 1;
}
/*有键按下*/
void KeyDown(int key)
{
int id,i,tm[2][4],w,h,mr,wb,wr,j,k=1;
if(key<<8)
key=key&0xff;
switch(key)
{
case ESC:
closegraph();
exit(0);
break;
case LEFT: /*方块左移*/
if(bcol>0)
{
if(LMove()&&!GameTable[brow][bcol-1])/*左移条件*/
{
HideRect(brow,bcol,hiderect);/*清除原来的方块区域(图像和缓存)*/
bcol-=1;
ShowRect(brow,bcol,drawrect);/*在新的位置显示方块(图像和保存行列号)*/
}
}
break;
case RIGHT: /*方块右移*/
w=GetMax(drawrect[0]);
if(bcol+w<COLUNM-1)
{
if(RMove()&&!GameTable[brow][bcol+1])
{
HideRect(brow,bcol,hiderect);
bcol+=1;
ShowRect(brow,bcol,drawrect);
}
}
break;
case UP: /*变换方块坠落形态*/
mr=newrectstyle[1];
mr++;
if(mr==index[newrectstyle[0]])
mr=0;
id=GetIndex(newrectstyle[0],mr);
for(i=0;i<4;i++)
{
tm[0][i]=GFKP[id][i];
tm[1][i]=GFKP[id][4+i];
}
w=GetMax(tm[0]);
h=GetMax(tm[1]);
if(bcol+w<=COLUNM-1&&brow+h<=ROW-1)
{
wb=GetMax(drawrect[0]);
if(wb>w)
wr=wb;
else
wr=w;
HideRect(brow,bcol,hiderect);
for(i=0;i<=h;i++)
for(j=0;j<=wr;j++)
{
/*检测方块变换空间如果在变换方块的行宽和列
高范围内有方块本次操作变换失败*/
if(GameTable[brow+i][bcol+j])
k=0;
}
if(k)
{
newrectstyle[1]=mr;
for(i=0;i<4;i++)
{
drawrect[0][i]=GFKP[id][i];
drawrect[1][i]=GFKP[id][4+i];
}
}
ShowRect(brow,bcol,drawrect);
}
break;
case SPACE:/*快速下落*/
activesd=speed;
speed=0;
break;
default: break;
}
}
/*游戏入口*/
void Game()
{
int i,key,mend=1;
GetNextRect();
brow=0;
bcol=4;
Rectinit();
ShowRect(brow,bcol,drawrect);
getch();
while(1)
{
key=0;
if(mend==0)
{
beginG=1;
GetRectData();
GetNextRect();
brow=0;
bcol=4;
speed=activesd;
ClearRect();
if(GameOver())
{
ShowRect(brow,bcol,drawrect);
mend=1;
}
else
{
printf("Game over!");
break;
}
}
HideRect(brow,bcol,hiderect);
if(bioskey(1))
key=bioskey(0);
KeyDown(key);
if(!key)/*方块自由下落*/
{
if(BMove())
brow++;
else
mend=0;
ShowRect(brow,bcol,drawrect);
}
}
}
/*初始化Win-TC图形模式*/
void init()
{
int dr=0,dm;
registerbgidriver(EGAVGA_driver);
initgraph(&dr, &dm, "");
}
void main()
{
init();
GameWind();
Game();
getch();
closegraph();
}