如何用C语言写俄罗斯方块程序?

俄罗斯方块c源代码

#包含?& ltstdio.h & gt

#包含?& ltwindows.h & gt

#包含?& ltconio.h & gt

#包含?& lttime.h & gt

#定义?ZL?4 //坐标增量,?不要把游戏窗口拉到一边。

#定义?WID?36 ?//游戏窗口的宽度

#定义?黑?20 ?//游戏窗口的高度

int?I,j,Ta,Tb,Tc;//?Ta,Tb,Tc用于记忆和转换box变量的值。

int?a[60][60]= { 0 };?//标记游戏画面的坐标点:0,1,2分别为空、正方形、边框。

int?b[4];?//标记四个“口”框:1是,0否,类似于一个开关。

int?x,y,?水平,分数,速度;?//盒子中心的x,y坐标,游戏等级,分数,游戏速度。

int?旗帜,下一个;?//当前要操作的块类型序号,以及下一个块类型序号。

作废?gtxy(int?m,?int?n);?//下面声明了要使用的自定义函数。

作废?gflag(?);?//获取下一个块号

作废?csh(?);?//初始化接口

作废?开始(?);?//开始部分

作废?prfk?(?);?//打印框

作废?clfk(?);?//清除该框

作废?mkfk(?);?//制作一个盒子

作废?keyD(?);?//按键操作

int?ifmov(?);?//判断框是否可以移动或更改。

void clHA(?);?//清除一整行框

作废?clNEXT(?);?//清除边框外的下一个框。

int?主(?)

{?csh(?);?

?while(1)

{开始(?);?//开始部分

?while(1)

?{?prfk(?);?

睡眠(速度);?//延迟

?clfk(?);

?TB = x;Tc =标志;?//保存当前的X坐标和序列号,以备取消。

?keyD(?);?

?y++;?//框向下移动。

如果?(ifmov(?)==0)?{?y-;?prfk(?);?dlHA(?);?打破;}?//不掉线,删线,步出循环。

?}

?for(I = y-2;我& lty+2;i++){?如果?(我==ZL)?{?j = 0;?}?}?//盒子接触盒子的顶部。

如果?(j==0)?{?系统(“cls”);gtxy(10,10);Printf("游戏结束!");?getch();?打破;?}?

clNEXT(?);?//清除框外的下一个框。

}

?回归?0;

}

作废?gtxy(int?m,?int?n)?//控制光标移动

{COORD?pos?//定义变量

位置。x?=?m;?//横坐标

位置。y?=?n;//纵坐标

SetConsoleCursorPosition(GetStdHandle(STD _ OUTPUT _ HANDLE),?pos);?

}

作废?csh(?)//初始化接口

{gtxy(ZL+WID/2-5,ZL-2);?Printf(《俄罗斯方块》);?//打印游戏的名称

gtxy(ZL+WID+3,ZL+7);?printf("*******?下一个:“);?//打印菜单信息

gtxy(ZL+WID+3,ZL+13);?printf(" * * * * * * * * * * *);

gtxy(ZL+WID+3,ZL+15);?printf("Esc?:退出游戏”);

gtxy(ZL+WID+3,ZL+17);?printf(" write key:variant ");

gtxy(ZL+WID+3,ZL+19);?Printf ("space:暂停游戏");

gtxy(ZL ZL);?printf("╔”);?gtxy(ZL+WID-2,ZL);?printf("╗”);?//打印框角度

gtxy(ZL,ZL+黑);?printf("╚”);?gtxy(ZL+WID-2,ZL+黑);?printf("╝”);

a[ZL][ZL+黑]= 2;?a[ZL+WID-2][ZL+黑]= 2;?//记住是有模式的。

for(I = 2;我& ltWID-2;i+=2)?{ gtxy(ZL+我,ZL);?printf("═”);?}?//打印顶部水平框架

for(I = 2;我& ltWID-2;i+=2)?{ gtxy(ZL+我,ZL+黑);?printf("═”);?a[ZL+我][ZL+黑]= 2;?}?//下框

for(I = 1;我& lt黑;i++)?{?gtxy(ZL、ZL+I);?printf("║”);?a[ZL][ZL+I]= 2;?}?//记住左边的竖框有图案。

for(I = 1;我& lt黑;i++)?{gtxy(ZL+WID-2,ZL+我);?printf("║”);?a[ZL+WID-2][ZL+我]= 2;?}?//右框

CONSOLE_CURSOR_INFO?cursor_info={1,0}//以下是隐藏光标的设置。

SetConsoleCursorInfo(GetStdHandle(STD _ OUTPUT _ HANDLE),& ampcursor _ info);

level = 1;?得分= 0;?速度= 400;

gflag(?);?flag = next?//获取当前块号。

}

作废?gflag(?) ?//获取下一个块的序列号。

{?srand((无符号)时间(空));?下一个?=?rand()% 19+1;}

作废?开始(?)?//开始部分

{?gflag(?);?Ta =旗帜;?flag = next?//保存当前块号,临时操作下一个块号。

x = ZL+WID+6;?y = ZL+10;?prfk(?);?//给x和y赋值,打印出框外的下一个框。

flag = Ta?x = ZL+WID/2;?y = ZL-1;?//检索当前块号,并给x和y赋值。

}

作废?prfk?(?)?//打印俄罗斯方块

{?for(I = 0;我& lt4;i++)?{ b[I]= 1;?}?//数组b[4]的每个元素的值是1。

mkfk?(?);?//制作俄罗斯方块

对于(?我=?x-2;?我& lt= x+4;?i+=2?)?//打印框

{?for(j = y-2;j & lt=?y+1;j++)?{?如果(?a[i][j]==1?& amp& amp?j & gtZL?){?gtxy(i,j);?printf("□");?}?}?}

gtxy(ZL+WID+3,ZL+1);?printf("级别?:?%d”,级别);?//打印下面的菜单信息。

gtxy(ZL+WID+3,ZL+3);?printf("分数?:?%d”,得分);

gtxy(ZL+WID+3,ZL+5);?printf("速度?:?%d”,速度);

}

作废?clfk(?)?//清除俄罗斯方块

{?for(I = 0;我& lt4;i++)?{?b[I]= 0;?}?//数组b[4]的每个元素的值都是0。

mkfk?(?);?//制作俄罗斯方块

对于(?I = x-2;?我& lt= x+4;?i+=2?)?//清除该框

{?for(j = y-2;j & lt= y+1;j++){?如果(?a[i][j]==0?& amp& amp?j & gtZL?){?gtxy(i,j);?printf("?);?}?}?}

}

作废?mkfk(?)?//制作俄罗斯方块

{?a[x][?y]= b[0];?//框中心位置状态:?1-是,0-无

开关(标志)/* * * 6大类,19小类。

{?案子?1:?{?a[x][y-1]= b[1];?a[x+2][y-1]= b[2];?a[x+2][y]= b[3];?打破;?}?//田字广场

案子?2:?{?a[x-2][y]= b[1];?a[x+2][y]= b[2];?a[x+4][y]= b[3];?打破;?}?//直框:-

案子?3:?{?a[x][y-1]= b[1];?a[x][y-2]= b[2];?a[x][y+1]= b[3];?打破;?}?//线性框:?|

案子?4:?{?a[x-2][y]= b[1];?a[x+2][y]= b[2];?a[x][y+1]= b[3];?打破;?}?//T形盒

案子?5:?{?a[x][y-1]= b[1];?a[x][y+1]= b[2];?a[x-2][y]= b[3];?打破;?}?//T字顺时针转90度。

案子?6:?{?a[x][y-1]= b[1];?a[x-2][y]= b[2];?a[x+2][y]= b[3];?打破;?}?//T型正转180度

案子?7:?{?a[x][y-1]= b[1];?a[x][y+1]= b[2];?a[x+2][y]= b[3];?打破;?}?//T形依次旋转270度。

案子?8:?{?a[x][y+1]= b[1];?a[x-2][y]= b[2];?a[x+2][y+1]= b[3];?打破;?}?//Z框

案子?9:?{?a[x][y-1]= b[1];?a[x-2][y]= b[2];?a[x-2][y+1]= b[3];?打破;?}?//Z旋转90度。

案子?10:?{?a[x][y-1]= b[1];?a[x-2][y-1]= b[2];?a[x+2][y]= b[3];?打破;?}?//Z形顺时针旋转180度。

案子?11:?{?a[x][y+1]= b[1];?a[x+2][y-1]= b[2];?a[x+2][?y]= b[3];?打破;?}?//Z形向前旋转270度。

案子?12:?{?a[x][y-1]= b[1];?a[x][y+1]= b[2];?a[x-2][y-1]= b[3];?打破;?}?//7字框

案子?13:?{ a[x-2][y]= b[1];?a[x+2][y-1]= b[2];?a[x+2][y]= b[3];?打破;?}?//7字转90度。

案子?14:?{?a[x][y-1]= b[1];?a[x][y+1]= b[2];?a[x+2][y+1]= b[3];?打破;?}?//7字转180度。

案子?15:?{?a[x-2][y]= b[1];?a[x-2][y+1]= b[2];?a[x+2][y]= b[3];?打破;?}?//7字转270度。

案子?16:?{?a[x][y+1]= b[1];?a[x][y-1]= b[2];?a[x+2][y-1]= b[3];?打破;?}?//倒置的7字符正方形

案子?17:?{?a[x-2][y]= b[1];?a[x+2][y+1]= b[2];?a[x+2][y]= b[3];?打破;?}?//将倒置的7字翻转90度。

案子?18:?{?a[x][y-1]= b[1];?a[x][y+1]= b[2];?a[x-2][y+1]= b[3];?打破;?}?//倒7字转180度。

案子?19:?{?a[x-2][y]= b[1];?a[x-2][y-1]= b[2];?a[x+2][y]= b[3];?打破;?}?//将倒置的7字向前旋转270度。

}

}

作废?keyD(?)?//按键操作

{?如果?(kbhit(?))

{?int?关键;

key = getch();

如果?(key==224)

{?key = getch();

如果?(key==75)?{?x-= 2;?}?//按左箭头键,中心的水平轴会减少2。

如果?(key==77)?{?x+= 2;?}?//按右箭头键,在中心的水平轴上加2。

如果?(key==72)?//按向上箭头键更改框。

{?如果?(flag & gt=2?& amp& amp?标志& lt=3?)?{?flag++;?flag % = 2;?flag+= 2;?}

如果?(?flag & gt=4?& amp& amp?标志& lt=7?)?{?flag++;?flag % = 4;?flag+= 4;?}

如果?(flag & gt=8?& amp& amp?标志& lt=11?)?{?flag++;?flag % = 4;?flag+= 8;?}

如果?(flag & gt=12?& amp& amp?标志& lt=15?)?{?flag++;?flag % = 4;?flag+= 12;?}

如果?(?flag & gt=16?& amp& amp?标志& lt=19?)?{?flag++;?flag % = 4;?flag+= 16;?}?}

}

?如果?(key==32)?//按空格键暂停。

{?prfk(?);?而(1)?{?如果?(getch(?)==32)?{?clfk(?);打破;}?}?}?//再次按空格键继续游戏。

?如果?(ifmov(?)==0)?{?x = Tb?flag = Tc?}?//如果不动,取消上述操作。

?不然呢?{?prfk(?);?睡眠(速度);?clfk(?);?TB = x;Tc =标志;} ?//如果是可移动的,则执行操作。

}

}

int?ifmov(?)//判断是否可以移动

{?如果?(a[x][y]!=0)?{?回归?0;?}?//正方形中心有一个图案,返回0,不能移动。

else{?如果?(?(flag==1?& amp& amp?(?a[x][?y-1]==0?& amp& amp?a[x+2][y-1]==0?& amp& amp?a[x+2][y]==0?)?)?|| ?

(flag==2?& amp& amp?(?a[x-2][y]==0?& amp& amp?a[x+2][y]==0?& amp& amp?a[x+4][y]==0?)?)?||?

(flag==3?& amp& amp?(?a[x][y-1]==0?& amp& amp?a[x][y-2]==0?& amp& amp?a[x][y+1]==0?)?)?||

(flag==4?& amp& amp?(?a[x-2][y]==0?& amp& amp?a[x+2][y]==0?& amp& amp?a[x][y+1]==0?)?)?||

(flag==5?& amp& amp?(?a[x][y-1]==0?& amp& amp?a[x][y+1]==0?& amp& amp?a[x-2][y]==0?)?)?||

(flag==6?& amp& amp?(?a[x][?y-1]==0?& amp& amp?a[x-2][y]==0?& amp& amp?a[x+2][y]==0?)?)?||

(flag==7?& amp& amp?(?a[x][y-1]==0?& amp& amp?a[x][y+1]==0?& amp& amp?a[x+2][y]==0?)?)?||

(flag==8?& amp& amp?(?a[x][y+1]==0?& amp& amp?a[x-2][y]==0?& amp& amp?a[x+2][y+1]==0?)?)?||

(flag==9?& amp& amp?(?a[x][y-1]==0?& amp& amp?a[x-2][y]==0?& amp& amp?a[x-2][y+1]==0?)?)?||

(flag==10?& amp& amp?(?a[x][y-1]==0?& amp& amp?a[x-2][y-1]==0?& amp& amp?a[x+2][y]==0?)?)?||

(flag==11?& amp& amp?(?a[x][y+1]==0?& amp& amp?a[x+2][y-1]==0?& amp& amp?a[x+2][y]==0?)?)?||

(flag==12?& amp& amp?(?a[x][y-1]==0?& amp& amp?a[x][y+1]==0?& amp& amp?a[x-2][y-1]==0?)?)?||

(flag = = 13 & amp;& amp(a[x-2][y]= = 0 & amp;& ampa[x+2][y-1]= = 0 & amp;& ampa[x+2][y]==0 ) ) ||

(flag = = 14 & amp;& amp(a[x][y-1]= = 0 & amp;& ampa[x][y+1]= = 0 & amp;& ampa[x+2][y+1]==0 ) ) ||

?(flag = = 15 & amp;& amp(a[x-2][y]= = 0 & amp;& ampa[x-2][y+1]= = 0 & amp;& ampa[x+2][y]==0 ) ) ||

?(flag = = 16 & amp;& amp(a[x][y+1]= = 0 & amp;& ampa[x][y-1]= = 0 & amp;& ampa[x+2][y-1]==0 ) ) ||

?(flag = = 17 & amp;& amp(a[x-2][y]= = 0 & amp;& ampa[x+2][y+1]= = 0 & amp;& ampa[x+2][y]==0 ) ) ||

(flag = = 18 & amp;& amp(a[x][y-1]= = 0 & amp;& ampa[x][y+1]= = 0 & amp;& ampa[x-2][y+1]==0 ) ) ||

?(flag = = 19 & amp;& amp(a[x-2][y]= = 0 & amp;& ampa[x-2][y-1]==0

?& amp& amp?a[x+2][y]==0?)?)?)?{?回归?1;?}

}

回归?0;?//其他条件返回0。

}

作废?clNEXT(?) ?//清除框外的下一个框。

{?旗帜?=?接下来;?x = ZL+WID+6;?y = ZL+10;?clfk(?);?}

void clHA(?) ?//清除一整行框

{?int?k,?hang = 0;?//k是一行中方块的个数。Hang是删除的方形行数。

for(j = ZL+HEI-1;j & gt= ZL+1;j -)?//当一条线有WID/2-2个方块时,它就是满的。

{?k = 0;?for(I = ZL+2;我& ltZL+WID-2;i+=2)

{?如果?(a[i][j]==1)//纵坐标从下到上,横坐标从左到右依次判断行是否满。

{?k++;?//接下来,删除该行。

?如果?(k==WID/2-2)?{ ?for(k = ZL+2;k & ltZL+WID-2;k+=2)?

?{?a[k][j]= 0;?gtxy(k,j);?printf("?);?睡眠(1);?}

?for(k = j-1;k & gtZL;k -)

?{?for(I = ZL+2;我& ltZL+WID-2;i+=2)?//删除的行上有方框。首先清除它们,然后将它们全部向下移动一行。

{?if(a[i][k]==1)?{?a[I][k]= 0;?gtxy(i,k);?printf("?);a[I][k+1]= 1;?

?gtxy(i,k+1);?printf("□");?}?}

}

?j++;?//盒子下移后,重新判断删除的行是否已满。

?hang++;?//记录删除框中的行数。

}

?}

}

}

得分+= 100 *杭;?//每删除一行,获得100积分。

如果?(?Hang & gt0?& amp& amp?(分数%500==0?||?得分/500 & gt;?level-1?)?) ?//500分的话,加速上一关。

{?速度-= 20;?level++;?如果(速度& lt200)速度+= 20;}?

}