C语言写的俄罗斯方块.docx
《C语言写的俄罗斯方块.docx》由会员分享,可在线阅读,更多相关《C语言写的俄罗斯方块.docx(14页珍藏版)》请在冰豆网上搜索。
C语言写的俄罗斯方块
请大家指教一下,由于自己算法的问题向左位移有些问题
在TC2下通过
#include
#include
#include
#include
#include
#include
#include
#defineESC0x011b
#defineUP0x4800
#defineDOWN0x5000
#defineLEFT0x4b00
#defineRIGHT0x4d00
#defineSPACE0x3920
#defineY0x1579
#defineN0x316e
#defineclearkbd();while(bioskey
(1))bioskey(0);/*清空键盘缓冲队列*/
voidupdate();
voidmessagebox();
voidprocess();
voidinitremove();
voidinitinfo();
voidinitbox();
voidinitposition();
voidnext_shape();
typedefstructshape/*形状单一状态的记录*/
{intattr;
intco[8];
}shape;
typedefstructRE_AB/*相对,绝对坐标记录*/
{intRx,Ry;
intx1,x2,y1,y2;
}RE_AB;
RE_ABRA;
shapep[19]={{RED,0,1,1,0,1,1,2,1},/*数组中保证y最大的在最后,以便initposition使用*/
{RED,0,1,1,0,1,1,1,2},
{RED,0,0,1,0,2,0,1,1},
{RED,0,0,0,1,1,1,0,2},
{GREEN,0,0,1,0,2,0,3,0},
{GREEN,0,0,0,1,0,2,0,3},
{CYAN,0,0,0,1,1,0,1,1},
{BROWN,0,0,1,0,1,1,2,1},
{BROWN,1,0,0,1,1,1,0,2},
{BLUE,1,0,2,0,1,1,0,1},
{BLUE,0,0,0,1,1,1,1,2},
{MAGENTA,0,0,0,1,0,2,1,2},
{MAGENTA,2,0,0,1,1,1,2,1},
{MAGENTA,0,0,1,0,1,1,1,2},
{MAGENTA,0,0,0,1,1,0,2,0},
{YELLOW,0,2,1,0,1,1,1,2},
{YELLOW,0,0,1,0,2,0,2,1},
{YELLOW,1,0,0,0,0,1,0,2},
{YELLOW,0,0,0,1,1,1,2,1},
};
intnback,nleft,nright,r_f[12][22],rs1,rs2,xcors,xcorb,ycors,ycorb;
/*检查方快有没有左,右,下接触,游戏区内所有格子有无颜色记录数组,rs1形状记录,rs2为提示框用,记录小格子在游戏区中的位置,按键存储*/
voidinterrupt(*oldint)();/*系统定时中断*/
intcount_down=0,count_other=0;/*中断记时*/
voidinterruptnewint()/*设置新的中断程序*/
{count_down++;
count_other++;
oldint();
}
voidintenable()/*设置中断向量表,启动新的中断程序*/
{oldint=getvect(0x1c);
disable();
setvect(0x1c,newint);
enable();
}
voidintrestore()/*恢复中断向量*/
{disable();
setvect(0x1c,oldint);
enable();
}
voidHZ12(intx0,inty0,intw,intcolor,char*s)/*根据字模,在dos下显示汉字*/
/*横坐标,纵坐标,字间隔,汉字颜色,汉字字符串*/
{FILE*fp;
registercharbuffer[24];
registercharstr[2];
unsignedlongfpos;/*fpos为最终偏移动量*/
registerinti,j,k;
fp=fopen(hzk12,r);/*打开12*12汉字苦*/
while(*s)/*一直到字符串结束为止*/
{
if(*s<0)/*汉字输出*/
{str[0]=(*s)-0xa0;
str[1]=*(s+1)-0xa0;
fpos=((str[0]-1)*94+(str[1]-1))*24L;/*计算汉字在hzk12的偏移量*/
fseek(fp,fpos,SEEK_SET);/*指针移动到当前位置*/
fread(buffer,24,1,fp);/*读取一个汉字到数组中*/
for(i=0;i<12;i++)/*12行*/
for(j=0;j<2;j++)/*两个字节*/
for(k=0;k<8;k++)/*8位*/
if(((buffer[i*2+j]>>(7-k))&0x1)!
=NULL)/*是一就画点*/
putpixel(x0+8*j+k,y0+i,color);
s+=2;/*一个汉字占两个字节,现在将指针移动两个字节*/
x0+=w;/*显示坐标也按照间隔移动*/
}
else/*显示非汉字字符*/
{settextstyle(0,0,1);
setcolor(color);
str[0]=*s;str[1]=0;
outtextxy(x0,y0+3,str);/*显示单个字符*/
x0+=w-7;/*显示单个字符后的x坐标变化*/
s++;/*指针移动到下一个字节*/
}
}
fclose(fp);
}
voidtranslation()/*把相对坐标解释为绝对坐标*/
{if(RA.Rx==1)
{RA.x1=1;RA.x2=16;}
else
{RA.x1=16*(RA.Rx-1);RA.x2=16*RA.Rx;}
if(RA.Ry==1)
{RA.y1=1;RA.y2=16;}
else
{RA.y1=16*(RA.Ry-1);RA.y2=16*RA.Ry;}
}
intcheck_b()/*检查是否到达低部*/
{intx,y,i,zf=0;/*zf为是否有颜色填充记录*/
for(i=0;i<7;i++,i++)
{x=RA.Rx+p[rs1].co[i];
y=RA.Ry+p[rs1].co[i+1];
if(y>=6)
zf+=r_f[x-15][y-6+1];
}
if(zf==0)
return1;
else
return0;
}
intfinish()
{inttfull=0,i;/*判断顶层空间是否有填充*/
for(i=1;i<11;i++)
tfull+=r_f[i][1];
if(tfull!
=0)
return1;/*告诉judge()可以结束了*/
}
intcheck_l()/*检查形状是否与左接触*/
{intx,y,i,zf=0;
for(i=0;i<7;i++,i++)
{x=RA.Rx+p[rs1].co[i];
y=RA.Ry+p[rs1].co[i+1];
if(y>6)
zf+=r_f[x-15-1][y-6];
if(y<=6&&x==16)
zf+=1;
}
if(zf==0)
return1;
else
return0;
}
intcheck_r()/*检查形状是否与右接触*/
{/*zf为是否有颜色填充记录*/
intx,y,i,zf=0;/*zf为是否有颜色填充记录*/
for(i=0;i<7;i++,i++)
{
x=RA.Rx+p[rs1].co[i];
y=RA.Ry+p[rs1].co[i+1];
if(y>6)
zf+=r_f[x-15+1][y-6];
if(y<=6&&x==25)
zf+=1;
}
if(zf==0)
return1;
else
return0;
}
voidcheck_touch()
{nback=check_b();
nleft=check_l();
nright=check_r();
}
voiddraw(intcb)/*画形状,cb=1以填充色画形状,cb=2以背景色画形状,cb=3以白色画形状*/
{inti,recordx=RA.Rx,recordy=RA.Ry;
for(i=0;i<7;i++,i++)
{RA.Rx+=p[rs1].co[i];
RA.Ry+=p[rs1].co[i+1];
if(RA.Ry<=6)
{RA.Rx=recordx;
RA.Ry=recordy;
continue;
}
translation();
if(cb==1)
setfillstyle(1,p[rs1].attr);
else
if(cb==2)
setfillstyle(1,BLACK);
else
if(cb==3)
{setfillstyle(1,WHITE);
r_f[RA.Rx-15][RA.Ry-6]=1;/*置对应数组标记元素*/
}
bar(RA.x1+1,RA.y1+1,RA.x2-1,RA.y2-1);
RA.Rx=recordx;
RA.Ry=recordy;
}
}
voidmov(intkey)/*向下,左,右移动方块*/
{draw
(2);
if(key==LEFT&&nleft)
RA.Rx--;
else
if(key==RIGHT&&nright)
RA.Rx++;
else
RA.Ry++;
nback=check_b();
if(nback)/*判断形状有没有到达底部,有就将其颜色变为白色*/
draw
(1);
else
draw(3);
}
voidchange()/*变换形状*/
{intstatus=rs1,buffer,i,x,y,zf=0;
if(p[rs1].attr==p[rs1+1].attr)
rs1++;
else
while(p[rs1].attr==p[rs1-1].attr)
rs1--;
for(i=0;i<7;i++,i++)/*检查变化形状后是否与已存形状发生冲突*/
{x=RA.Rx+p[rs1].co[i];
y=RA.Ry+p[rs1].co[i+1];
if(y>6)
zf+=r_f[x-15][y-6];
}
if(zf!
=0)
rs1=status;
buffer=rs1;
rs1=status;
status=buffer;
draw
(2);
buffer=rs1;
rs1=status;
status=buffer;
nback=check_b();/*判断变化后的形状是不是到达了低部,这个检查是十分必要的*/
if(nback)
draw
(1);
else
draw(3);
}
voidaccelerate()
{if(count_down>=1)
{check_touch();/*消除上一步动作对方块状态的影响*/
count_down=0;
if(nback)/*0表示到达底部,1表示没有到达*/
mov(DOWN);
}
}
voiddrawbox()/*画方块所在方框*/
{intxcor,ycor;
for(xcor=xcors;xcor<=xcorb;xcor++)
for(ycor=ycors;ycor<=ycorb;ycor++)
{if(xcor==xcors||xcor==xcorb||ycor==ycors||ycor==ycorb)
{RA.Rx=xcor;
RA.Ry=ycor;
translation();
setfillstyle(1,DARKGRAY);
bar(RA.x1+1,RA.y1+1,RA.x2-1,RA.y2-1);
}
}
}
voiderasure(intk)
{inti,j,recordx=RA.Rx,recordy=RA.Ry;
{j=k-1;
for(;j>0;j--)
{for(i=1;i<11;i++)
{r_f[i][j+1]=r_f[i][j];
RA.Rx=i+15;
RA.Ry=j+1+6;
translation();
if(r_f[i][j+1]==1)
setfillstyle(1,WHITE);
else
setfillstyle(1,BLACK);
bar(RA.x1+1,RA.y1+1,RA.x2-1,RA.y2-1);
RA.Rx=recordx;
RA.Ry=recordy;
}
}
}
}
voidpause()
{HZ12(450,400,15,BLACK,正常);
HZ12(450,400,15,GREEN,暂停);
for(;;)
if(bioskey
(1)&&bioskey(0)==SPACE)
{clearkbd();
HZ12(450,400,15,BLACK,暂停);
HZ12(450,400,15,RED,正常);
return;
}
}
voidjudge()
{inti,j,full=0;/*full等于10说明某一行满,该消除了*/
if(finish())/*判断游戏是否该结束了*/
messagebox();/*win编程里有这个函数*/
for(j=1;j<21;j++)/*判断某一行是否满了*/
{for(i=1;i<11;i++)
full+=r_f[i][j];
if(full==10)
erasure(j);/*消除这行*/
full=0;
}
}
voidupdate()/*使程序可以重新运行*/
{cleardevice();
setbkcolor(BLACK);
initinfo();/*提示信息初始化*/
initbox();/*游戏框架初始化*/
srand((unsigned)time(NULL));/*随机器函数的初始化*/
rs1=random(19);
rs2=random(19);
next_shape();
initposition();/*方块最开始的出现位置*/
initremove();/*记录每个方格有无颜色填充数组初始化*/
HZ12(450,400,15,RED,正常);
process();
}
voidEXIT()
{closegraph();
intrestore();/*恢复中断向量*/
exit(0);
}
voidinitremove()
{inti,j;
for(i=0;i<12;i++)
for(j=0;j<22;j++)
if(i==0||i==11||j==0||j==21)
r_f[i][j]=1;
else
r_f[i][j]=0;
}
voidinitinfo()
{charaStr[2];
setcolor(RED);
outtextxy(450,100,Thisgame'swriteris:
);
HZ12(450,140,15,RED,该程序作者:
NULL);
outtextxy(525,110,NULL);
outtextxy(450,180,FUNCTIONFORKEYS:
);
outtextxy(450,200,UP:
changetheshape);
outtextxy(450,210,DOWN:
accelerate);
outtextxy(450,220,LEFT:
moveleft);
outtextxy(450,230,RIGHT:
moveright);
outtextxy(450,240,ESC:
exitthisgame);
outtextxy(450,250,SPACE:
pause);
HZ12(450,260,20,RED,上:
);
HZ12(450,280,20,RED,下:
);
HZ12(450,300,20,RED,左:
);
HZ12(450,320,20,RED,右:
);
HZ12(450,340,20,RED,ESC:
退出);
HZ12(450,360,15,RED,空格:
暂停/开始);
HZ12(450,380,15,RED,目前状态:
);
HZ12(20,200,15,RED,下一个形状);
aStr[0]=24;
aStr[1]=0;
aStr[6]=0;
HZ12(480,260,12,GREEN,aStr);
HZ12(500,260,12,GREEN,(变形));
aStr[0]=25;
aStr[1]=0;
HZ12(480,280,12,GREEN,aStr);
HZ12(500,280,12,GREEN,(加速));
aStr[0]=27;
aStr[1]=0;
HZ12(480,300,12,GREEN,aStr);
HZ12(500,300,12,GREEN,向左);
aStr[0]=26;
aStr[1]=0;
HZ12(480,320,12,GREEN,aStr);
HZ12(500,320,12,GREEN,向右);
}
voidmessagebox()
{intkey;
setcolor(GREEN);
setfillstyle(1,DARKGRAY);
rectangle(220,200,420,300);
bar(221,201,419,299);
HZ12(280,210,15,GREEN,GAMEOVER);
HZ12(275,230,15,GREEN,重新游戏:
Y);
HZ12(275,270,15,GREEN,退出游戏:
N);
HZ12(450,400,15,BLACK,正常);
HZ12(450,400,15,GREEN,GAMEOVER);
for(;;)
if(bioskey
(1))
{key=bioskey(0);
if(key==Y)
{clearkbd();
update();
}
else
if(key==N)
{clearkbd();
EXIT();
}
else
clearkbd();
}
}
voidinitbox()
{xcors=15;/*画游戏框*/
xcorb=26;
ycors=6;
ycorb=27;
drawbox();
xcors=2;/*画提示框*/
xcorb=7;
ycors=6;
ycorb=11;
drawbox();
}
voidinitposition()
{RA.Rx=18;
RA.Ry=6-p[rs1].co[7];;
RA.x1=0;
RA.x2=0;
RA.y1=0;
RA.y2=0;
}
voidnext_shape()/*画下一形状提示框*/
{intrecordx=RA.Rx,recordy=RA.Ry,buffer;
RA.Rx=3;
RA.Ry=7;
draw
(2);
buffer=rs1;
rs1=rs2;
rs2=buffer;
draw
(1);
RA.Rx=recordx;
RA.Ry=recordy;
buffer=rs1;
rs1=rs2;
rs2=buffer;
}
voidprocess()/*游戏过程*/
{for(;;)
{check_touch();
if(!
nback)
{rs1=rs2;
rs2=random(19);/*产生另一种方块的码数*/
initposition();
judge();/*判断某一行是否满了和这个游戏是否可以结束了*/
draw
(1);
next_shape();
}
if(count_other>=1)
{count_other=0;
if(bioskey
(1))/*对按键的处理*/
{intkey=bioskey(0);
clearkbd();/*清除键盘缓冲队列*/
if(key==ESC)
EXIT();
if(key==LEFT&&nleft&&nback)
mov(LEFT);
if(key==RIGHT&&nright&&nback)
mov(RIGHT);
if(key==UP&&nback)
change();
if(key==SPACE)
pause();
if(key==DOWN)
accelerate();
}
}
if(count_down>=4)
{check_touch();/*消除上一步动作对方块状态的影响*/
count_down=0;
if(nback)/*0表示到达底部,1表示没有到达*/
mov(DOWN);
}
}/*for*/
}
main()
{intgdriver=DETECT,gmode=0;
initgraph(&gdriver,&gmode,d:
turboc);/*启动图形与中断部分*/
intenable();
update();
}