您的位置:广东在线游戏网 > 游戏解答 > 俄罗斯方块c语言的代码-谁能提供个俄罗斯方块的C语言代码??谢谢

俄罗斯方块c语言的代码-谁能提供个俄罗斯方块的C语言代码??谢谢

作者:广东在线游戏网日期:

返回目录:游戏解答




(1)第一个cpp:
#include "colorConsole.h"

HANDLE initiate()
{
HANDLE hOutput;
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
return hOutput;
}
BOOL textout(HANDLE hOutput,int x,int y,WORD wColors[],int nColors,LPTSTR lpszString)
{
DWORD cWritten;
BOOL fSuccess;
COORD coord;

coord.X = x; // start at first cell
coord.Y = y; // of first row
fSuccess = WriteConsoleOutputCharacter(
hOutput, // screen buffer handle
lpszString, // pointer to source string
lstrlen(lpszString), // length of string
coord, // first cell to write to
&cWritten); // actual number written
if (! fSuccess)
cout<<"error:WriteConsoleOutputCharacter"<<endl;

for (;fSuccess && coord.X < lstrlen(lpszString)+x; coord.X += nColors)
{
fSuccess = WriteConsoleOutputAttribute(
hOutput, // screen buffer handle
wColors, // pointer to source string
nColors, // length of string
coord, // first cell to write to
&cWritten); // actual number written
}
if (! fSuccess)
cout<<"error:WriteConsoleOutputAttribute"<<endl;

return 0;
}

(2)第二个cpp
#include <conio.h>
#include <stdlib.h>
#include<stdio.h>
#include <windows.h>
#include <mmsystem.h>
#pragma comment(lib,"winmm.lib") //播放背景音乐的头文件
#include "colorConsole.h"
#include<time.h>
#define SQUARE_COLOR BACKGROUD_BLUE|BACKGROUD_RED| BACKGROUD_INTENSITY //背景颜色
#define SQUARE_COLOR FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_INTENSITY //方块的颜色
#define up 72
#define down 80
#define left 75
#define right 77
#define esc 27
#define MAPW 15 //地图的宽度
#define MAPH 25 //地图的高度

void initiate1();
int * build(); //创建方块 7a64e78988e69d83336 //初始化工作
BOOL isavailable(int a[],int x,int y,int w,int h); //判定是否能放下
void drawblocks(int a[],int w,int h,int x,int y,WORD wColors[],int nColors);
void delete_cache(); //清除键盘缓冲区
void revolve(int a[][4],int w,int h,int *x,int y); //转动方块
void pro();
void end();
void delete_blocks(int *a,int w,int h,int x,int y);
void gameover();
void deletefull_line(int m[][MAPW],int row,int w,int h); //消除一行

int dx=30,dy=5; //屏幕上的偏移量
int score=0,level=0;
int map[MAPH][MAPW];
int a1[4][4]={{1},{1,1,1}};
int a2[4][4]={{0,1},{1,1,1}};
int a3[4][4]={{1,1},{0,1,1}};
int a4[4][4]={{0,0,1},{1,1,1}};
int a5[4][4]={{0,1,1},{1,1}};
int a6[4][4]={{1,1,1,1}};
int a7[4][4]={{1,1},{1,1}};
int a[4][4];

int main()
{
HANDLE handle;
handle=initiate();
WORD wColors[1]={FOREGROUND_BLUE| FOREGROUND_GREEN|FOREGROUND_INTENSITY };
while(1)
{
sndPlaySound("Resource\\Just Dance.wav",SND_LOOP|SND_ASYNC);//用异步方式播放音乐,PlaySound函数在开始播放后立即返回
system("CLS");
int n=0;
printf("目录\n1.开始游戏\n2.退出游戏\n\n\n");
scanf("%d",&n);
switch(n)
{
case 1:
system("CLS");
textout(handle,22,6,wColors+2,1,"请选择游戏等级:");
textout(handle,32,8,wColors+2,1,"1.初级");
textout(handle,32,10,wColors+2,1,"2.中级");
textout(handle,32,12,wColors+2,1,"3.高级");
while(1)
{
char choice;
choice=_getch();
if(choice=='1')
{
textout(handle,22,6,wColors+2,1,"开始游戏,初级");
textout(handle,32,8,wColors+2,1," ");
textout(handle,32,10,wColors+2,1," ");
textout(handle,32,12,wColors+2,1," ");
level=0,score=0;
Sleep(2000);
textout(handle,22,6,wColors+2,1," ");
break;
}
else if(choice=='2')
{
textout(handle,22,6,wColors+2,1,"开始游戏,中级");
textout(handle,32,8,wColors+2,1," ");
textout(handle,32,10,wColors+2,1," ");
textout(handle,32,12,wColors+2,1," ");
level=2,score=20;
Sleep(2000);
textout(handle,22,6,wColors+2,1," ");
break;
}
else if(choice=='3')
{
textout(handle,22,6,wColors+2,1,"开始游戏,高级");
textout(handle,32,8,wColors+2,1," ");
textout(handle,32,10,wColors+2,1," ");
textout(handle,32,12,wColors+2,1," ");
level=4,score=40;
Sleep(2000);
textout(handle,22,6,wColors+2,1," ");
break;
}
else if(choice!='1'&&choice!='2'&&choice!='3')
continue;
}
pro();
break;
case 2:
return 0;
default:
printf("错误,按键继续");
while(!_kbhit());
}
}
}

void pro() //游戏主题
{
initiate1();
int *b=NULL;
b=build(); //创建方块
int sign,blank,x,y;
while(1)
{
for(int i=0;i<4;i++) //复制方块
for(int j=0;j<4;j++)
if(a[i][j]=*(b+i*4+j)) blank=i;
y=1-blank;x=4;
delete_blocks(&a[0][0],4,4,16,10);

b=build();
HANDLE handle;
handle=initiate();
WORD wColors[1]={FOREGROUND_BLUE| FOREGROUND_GREEN|FOREGROUND_INTENSITY };
drawblocks(b,4,4,16,10,wColors,1);

wColors[0]=SQUARE_COLOR;
drawblocks(&a[0][0],4,4,x,y,wColors,1);

delete_cache();

char string[5];
wColors[0]=FOREGROUND_RED| FOREGROUND_GREEN|FOREGROUND_INTENSITY;
textout(handle,dx-10,8+dy,wColors,1,itoa(score,string,10));
textout(handle,dx-10,14+dy,wColors,1,itoa(level,string,10));

sign=1;
while(sign)
{
int delay=0,max_delay=100-10*level; //延迟量
while(delay<max_delay)
{
if(_kbhit()) //用if避免按住键使方块卡住
{
int draw=0;
int key=_getch();
switch (key)
{
case up:
delete_blocks(&a[0][0],4,4,x,y);
revolve(a,4,4,&x,y);
draw=1;
break;
case down:
delay=max_delay;
break;
case left:
if(isavailable(&a[0][0],x-1,y,4,4))
{
delete_blocks(&a[0][0],4,4,x,y);
x--;
draw=1;
}
break;
case right:
if(isavailable(&a[0][0],x+1,y,4,4))
{
delete_blocks(&a[0][0],4,4,x,y);
x++;
draw=1;
}
break;
case 32://32 是空格键的ASCII码,按空格键暂停
while(1)
{
textout(handle,dx,-2+dy,wColors,1,"Press any key to continue");
Sleep(200);
textout(handle,dx,-2+dy,wColors,1," ");
Sleep(200);
if(_kbhit())
{
draw=1;
break;
}
}
break;
case esc://按键退出游戏
exit(EXIT_SUCCESS);
}
if(draw)
{
HANDLE handle;
handle=initiate();
WORD wColors[1]={SQUARE_COLOR};
drawblocks(&a[0][0],4,4,x,y,wColors,1);
draw=0;
}
}
_sleep(5);delay++;
}
if(isavailable(&a[0][0],x,y+1,4,4)) //是否能下移
{
delete_blocks(&a[0][0],4,4,x,y);
y++;
HANDLE handle;
handle=initiate();
WORD wColors[1]={SQUARE_COLOR};
drawblocks(&a[0][0],4,4,x,y,wColors,1);
}
else
{
sign=0; //标记,使跳出 while(sign) 循环,产生新方块
if(y<=1)
{
system("CLS");
HANDLE handle;
handle=initiate();
WORD wColors[1]={FOREGROUND_RED| FOREGROUND_GREEN};
textout(handle,4+dx,6+dy,wColors,1,"GAME OVER!!!");
textout(handle,4+dx,8+dy,wColors,1,"分数:");
textout(handle,10+dx,8+dy,wColors,1,itoa(score,string,10));
textout(handle,4+dx,10+dy,wColors,1,"制作者:***");
delete_cache();
exit(EXIT_SUCCESS);
} //是否结束
for(int i=0;i<4;i++) //放下方块
for(int j=0;j<4;j++)
if(a[i][j]&&((i+y)<MAPH-1)&&((j+x)<MAPW-1))
map[i+y][j+x]=a[i][j];
int full,k=0;
for( i=y;i<min(y+4,MAPH-1);i++)
{
full=1;
for(int j=1;j<14;j++)
if(!map[i][j]) full=0;
if(full) //消掉一行
{
deletefull_line(map,i,MAPW,MAPH);
k++;
score=score+k;
level=min(score/10,9);
}
}
}
}

}
}
void initiate1() //初始化
{
int i;
for(i=0;i<25;i++)
{
map[i][0]=-2;
map[i][14]=-2;
}
for(i=0;i<15;i++)
{
map[0][i]=-1;
map[24][i]=-1;
}
map[0][0]=-3;
map[0][14]=-3;
map[24][0]=-3;
map[24][14]=-3;

HANDLE handle;
handle=initiate();
WORD wColors[1]={FOREGROUND_GREEN| FOREGROUND_BLUE|FOREGROUND_INTENSITY};
textout(handle,dx-10,6+dy,wColors,1,"SCORE");
textout(handle,dx-10,12+dy,wColors,1,"LEVEL");
textout(handle,32+dx,8+dy,wColors,1,"NEXT");
wColors[0]=FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_INTENSITY;
drawblocks(&map[0][0],15,25,0,0,wColors,1);
textout(handle,dx,dy,wColors,1,"◎═════════════◎");
wColors[0]=FOREGROUND_BLUE| FOREGROUND_GREEN|FOREGROUND_INTENSITY;
textout(handle,dx+8,dy+5,wColors,1,"按任意键开始");
wColors[0]=FOREGROUND_BLUE|FOREGROUND_RED|FOREGROUND_INTENSITY ;
textout(handle,dx+7,dy-3,wColors,1,"制作者:***");

int x=_getch();
srand(time(NULL));
textout(handle,dx+8,dy+5,wColors,1," ");
}

int * build() //创建方块
{
int * a=NULL;
int c=rand()%7;
switch(c)
{
case 0:
a=&a1[0][0];break;
case 1:
a=&a2[0][0];break;
case 2:
a=&a3[0][0];break;
case 3:
a=&a4[0][0];break;
case 4:
a=&a5[0][0];break;
case 5:
a=&a6[0][0];break;
case 6:
a=&a7[0][0];break;
}
return a;
}

void drawblocks(int a[],int w,int h,int x,int y,WORD wColors[],int nColors) //画出方块
{
HANDLE handle;
handle = initiate();
int temp;

for(int i=0;i<h;i++)
for(int j=0;j<w;j++)
if((temp=a[i*w+j])&&y+i>0)
{
if(temp==-3)
{
textout(handle,2*(x+j)+dx,y+i+dy,wColors,nColors,"◎");
_sleep(30);
}
else if(temp==-2)
{
textout(handle,2*(x+j)+dx,y+i+dy,wColors,nColors,"║");
_sleep(30);
}

else if(temp==1)
textout(handle,2*(x+j)+dx,y+i+dy,wColors,nColors,"◎");
else if(temp==-1)
{
textout(handle,2*(x+j)+dx,y+i+dy,wColors,nColors,"═");
_sleep(30);
}
}
}

void delete_cache() //清除缓冲区
{
while(_kbhit())
{
_getch();
}
}

void delete_blocks(int *a,int w,int h,int x,int y) //覆盖方块
{
HANDLE handle;
handle=initiate();
WORD wColors[1]={SQUARE_COLOR};
for(int i=0;i<h;i++)
for(int j=0;j<w;j++)
if(a[i*w+j]&&i+y>0)
textout(handle,2*(x+j)+dx,y+i+dy,wColors,1," ");
}

void revolve(int a[][4],int w,int h,int *x,int y) //转动方块
{
int b[4][4]={{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}};
int sign=0,line=0;
for(int i=h-1;i>=0;i--)
{
for(int j=0;j<w;j++)
if(a[i][j])
{
b[j][line]=a[i][j];
sign=1;
}
if(sign)
{
line++;
sign=0;
}
}
for(i=0;i<4;i++)
if(isavailable(&b[0][0],*x-i,y,w,h))
{
*x-=i;
for(int k=0;k<h;k++)
for(int j=0;j<w;j++)
a[k][j]=b[k][j];
break;
}
}

void deletefull_line(int m[][MAPW],int row,int w,int h) //消除满行的方块
{
HANDLE handle;
handle=initiate();
WORD wColors[1]={SQUARE_COLOR};
textout(handle,2+dx,row+dy,wColors,1,"﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌");
_sleep(100);

int i;
for(i=row;i>1;i--)
{
delete_blocks(&m[i][1],MAPW-2,1,1,i);
for(int j=1;j<MAPW-1;j++)
m[i][j]=m[i-1][j];
drawblocks(&m[i][1],MAPW-2,1,1,i,wColors,1);
}
for(i=1;i<MAPW-1;i++)
m[1][i]=0;
}

BOOL isavailable(int a[],int x,int y,int w,int h)
{
for(int i=max(y,1);i<y+h;i++)
for(int j=x;j<x+w;j++)
if(map[i][j]&&a[w*(i-y)+j-x])
return 0;
return 1;
}

俄罗斯方块C源代码

#include <stdio.h>

#include <windows.h>

#include <conio.h>

#include <time.h>

#define  ZL  4     //坐标增量, 不使游戏窗口靠边

#define WID  36    //游戏窗口的宽度

#define HEI  20    //游戏窗口的高度

int i,j,Ta,Tb,Tc;      // Ta,Tb,Tc用于记住和转换方块变量的值

int a[60][60]={0};    //标记游戏屏幕各坐标点:0,1,2分别为空、方块、边框

int b[4];        //标记4个"口"方块:1有,0无,类似开关

int x,y, level,score,speed;    //方块中心位置的x,y坐标,游戏等级、得分和游戏速度

int flag,next;   //当前要操作的方块类型序号,下一个方块类型序号

void gtxy(int m, int n);   //以下声明要用到的自编函数

void gflag( );  //获得下一方块序号

void csh( );  //初始化界面

void start( );  //开始部分

void prfk ( );  //打印方块

void clfk( );  //清除方块

void mkfk( );  //制作方块

void keyD( );  //按键操作

int  ifmov( );  //判断方块能否移动或变体

void clHA( );  //清除满行的方块

void clNEXT( );  //清除边框外的NEXT方块

int main( )

csh( );   

   while(1)

     {start( );  //开始部分

       while(1)

       { prfk( );  

         Sleep(speed);  //延时

          clfk( );

          Tb=x;Tc=flag;  //临存当前x坐标和序号,以备撤销操作

          keyD( );  

          y++;     //方块向下移动

         if (ifmov( )==0) { y--; prfk( ); dlHA( ); break;} //不可动放下,删行,跨出循环

       }

      for(i=y-2;i<y+2;i++){ if (i==ZL) { j=0; } }  //方块触到框顶

     if (j==0) { system("cls");gtxy(10,10);printf("游戏结束!"); getch(); break; } 

     clNEXT( );   //清除框外的NEXT方块

    }

  return 0;

}

void gtxy(int m, int n)  //控制光标移动

{COORD pos;  //定义变量

 pos.X = m;  //横坐标

 pos.Y = n;   //纵坐标

 SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos); 

}

void csh( )    //初始化界面

{gtxy(ZL+WID/2-5,ZL-2); printf("俄罗斯方块");      //打印游戏名称

 gtxy(ZL+WID+3,ZL+7); printf("******* NEXT:");  //打印菜单信息

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

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

gtxy(ZL+WID+3,ZL+17); printf("↑键:变体");

 gtxy(ZL+WID+3,ZL+19); printf("空格:暂停游戏");

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

 gtxy(ZL,ZL+HEI);  printf("╚");  gtxy(ZL+WID-2,ZL+HEI);  printf("╝");

a[ZL][ZL+HEI]=2;  a[ZL+WID-2][ZL+HEI]=2;  //记住有图案

 for(i=2;i<WID-2;i+=2) {gtxy(ZL+i,ZL);  printf("═"); }  //打印上横框

 for(i=2;i<WID-2;i+=2) {gtxy(ZL+i,ZL+HEI); printf("═"); a[ZL+i][ZL+HEI]=2; } //下框

 for(i=1;i<HEI;i++) { gtxy(ZL,ZL+i);  printf("║"); a[ZL][ZL+i]=2; }  //左竖框记住有图案

 for(i=1;i<HEI;i++) {gtxy(ZL+WID-2,ZL+i); printf("║"); a[ZL+WID-2][ZL+i]=2; } //右框

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

 SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info);

 level=1; score=0; speed=400;

 gflag( );  flag=next;  //获得一个当前方块序号

}

void gflag( )   //获得下一个方块的序号

{ srand((unsigned)time(NULL)); next = rand()%19+1; }

void start( )  //开始部分

{ gflag( ); Ta=flag; flag=next;  //保存当前方块序号,将下一方块序号临时操作

  x=ZL+WID+6; y=ZL+10; prfk( );  //给x,y赋值,在框外打印出下一方块

 flag=Ta; x=ZL+WID/2; y=ZL-1;  //取回当前方块序号,并给x,y赋值

}

void prfk ( )  //打印俄罗斯方块

{ for(i=0;i<4;i++) {b[i]=1; }  //数组b[4]每个元素的值都为1

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

 for( i= x-2; i<=x+4; i+=2 )  //打印方块

  { for(j=y-2;j<= y+1;j++) { if( a[i][j]==1 && j>ZL ){ gtxy(i,j); printf("□"); } } }

 gtxy(ZL+WID+3,ZL+1);   printf("level : %d",level);  //以下打印菜单信息

 gtxy(ZL+WID+3,ZL+3);  printf("score : %d",score);

 gtxy(ZL+WID+3,ZL+5);  printf("speed : %d",speed);

}

void clfk( )  //清除俄罗斯方块

{ for(i=0;i<4;i++) { b[i]=0; }  //数组b[4]每个元素的值都为0

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

 for( i=x-2; i<=x+4; i+=2 )  //清除方块

  { for(j=y-2;j<=y+1;j++){ if( a[i][j]==0 && j>ZL ){ gtxy(i,j); printf("  "); } } }

}

void mkfk( )  //制作俄罗斯方块

{ a[x][ y]=b[0];  //方块中心位置状态: 1-有,0-无

 switch(flag)   //共6大类,19种小类型

 { case 1: { a[x][y-1]=b[1]; a[x+2][y-1]=b[2]; a[x+2][y]=b[3]; break; }  //田字方块

  case 2: { a[x-2][y]=b[1]; a[x+2][y]=b[2]; a[x+4][y]=b[3]; break; }  //直线方块:----

  case 3: { a[x][y-1]=b[1]; a[x][y-2]=b[2]; a[x][y+1]=b[3]; break; }  //直线方块: |

  case 4: { a[x-2][y]=b[1]; a[x+2][y]=b[2]; a[x][y+1]=b[3]; break; }  //T字方块

  case 5: { a[x][y-1]=b[1]; a[x][y+1]=b[2]; a[x-2][y]=b[3]; break; }  //T字顺时针转90度

  case 6: { a[x][y-1]=b[1]; a[x-2][y]=b[2]; a[x+2][y]=b[3]; break; }  //T字顺转180度

  case 7: { a[x][y-1]=b[1]; a[x][y+1]=b[2]; a[x+2][y]=b[3]; break; }  //T字顺转270度

  case 8: { a[x][y+1]=b[1]; a[x-2][y]=b[2]; a[x+2][y+1]=b[3]; break; } //Z字方块

  case 9: { a[x][y-1]=b[1]; a[x-2][y]=b[2]; a[x-2][y+1]=b[3]; break; }  //Z字顺转90度

  case 10: { a[x][y-1]=b[1]; a[x-2][y-1]=b[2]; a[x+2][y]=b[3]; break; }  //Z字顺转180度

  case 11: { a[x][y+1]=b[1]; a[x+2][y-1]=b[2]; a[x+2][ y]=b[3]; break; } //Z字顺转270度

  case 12: { a[x][y-1]=b[1]; a[x][y+1]=b[2]; a[x-2][y-1]=b[3]; break; }  //7字方块

  case 13: {a[x-2][y]=b[1]; a[x+2][y-1]=b[2]; a[x+2][y]=b[3]; break; }  //7字顺转90度

  case 14: { a[x][y-1]=b[1]; a[x][y+1]=b[2]; a[x+2][y+1]=b[3]; break; }  //7字顺转180度

  case 15: { a[x-2][y]=b[1]; a[x-2][y+1]=b[2]; a[x+2][y]=b[3]; break; }  //7字顺转270度

  case 16: { a[x][y+1]=b[1]; a[x][y-1]=b[2]; a[x+2][y-1]=b[3]; break; }  //倒7字方块

 case 17: { a[x-2][y]=b[1]; a[x+2][y+1]=b[2]; a[x+2][y]=b[3]; break; }  //倒7字顺转90度

 case 18: { a[x][y-1]=b[1]; a[x][y+1]=b[2]; a[x-2][y+1]=b[3]; break; }  //倒7字顺转180度

  case 19: { a[x-2][y]=b[1]; a[x-2][y-1]=b[2]; a[x+2][y]=b[3]; break; }  //倒7字顺转270度

 }

}

void keyD( )  //按键操作

{ if (kbhit( ))       

   { int key;

     key=getch();

     if (key==224)

       { key=getch();

         if (key==75) { x-=2; }  //按下左方向键,中心横坐标减2

         if (key==77) { x+=2; }  //按下右方向键,中心横坐标加2

        if (key==72)     //按下向上方向键,方块变体

          { if (flag>=2 && flag<=3 ) { flag++; flag%=2; flag+=2; }

           if ( flag>=4 && flag<=7 ) { flag++; flag%=4; flag+=4; }

           if (flag>=8 && flag<=11 ) { flag++; flag%=4; flag+=8; }

           if (flag>=12 && flag<=15 ) { flag++; flag%=4; flag+=12; }

           if ( flag>=16 && flag<=19 ) { flag++; flag%=4; flag+=16; } }

         }

      if (key==32)     //按空格键,暂停

        { prfk( ); while(1) { if (getch( )==32) { clfk( );break;} } }  //再按空格键,继续游戏

      if (ifmov( )==0) { x=Tb; flag=Tc; }  //如果不可动,撤销上面操作

      else { prfk( ); Sleep(speed); clfk( ); Tb=x;Tc=flag;}   //如果可动,执行操作

   }

}

int ifmov( )   //判断能否移动

{ if (a[x][y]!=0) { return 0; }  //方块中心处有图案返回0,不可移动

 else{ if ( (flag==1 && ( a[x][ y-1]==0 && a[x+2][y-1]==0 && a[x+2][y]==0 ) ) ||  

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

       (flag==19 && ( a[x-2][y]==0 && a[x-2][y-1]==0

              && a[x+2][y]==0 ) ) ) { return 1; }

    }

  return 0;   //其它情况返回0

}

void clNEXT( )   //清除框外的NEXT方块

{ flag = next;  x=ZL+WID+6;  y=ZL+10;  clfk( ); }

void clHA( )   //清除满行的方块

{ int k, Hang=0;    //k是某行方块个数, Hang是删除的方块行数

  for(j=ZL+HEI-1;j>=ZL+1;j--)  //当某行有WID/2-2个方块时,则为满行

   { k=0; for(i=ZL+2;i<ZL+WID-2;i+=2)

    { if (a[i][j]==1)   //竖坐标从下往上,横坐标由左至右依次判636f7079e79fa5e98193337断是否满行

     { k++;   //下面将操作删除行

       if (k==WID/2-2)  {   for(k=ZL+2;k<ZL+WID-2;k+=2) 

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

          for(k=j-1;k>ZL;k--)

          { for(i=ZL+2;i<ZL+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++;  //记录删除方块的行数

         }

      }

     }

   }

   score+=100*Hang;   //每删除一行,得100分

 if ( Hang>0 && (score%500==0 || score/500> level-1 ) )  //得分满500速度加快升一级

    { speed-=20; level++; if(speed<200)speed+=20; } 

}



(1)由于c的随机性函数不好,所以每次游戏开始根据bios时间设置种子。
(2)得分越高,方块下降速度越快(每200分为单位)。
(3)每下落一个方块加1分,每消除一行加10分,两行加30分,三行加70分,四行加150分。初试分数为100分。
游戏控制:
up-旋转;空格-下落到底; 左右下方向键-控制方向。P-开始或暂停游戏。 ESC-退出。
特点:
(1)由于tc不支持中文,所以基本都是英文注释。
(2)函数命名尽可能规范的表达其内部处理目的和过程。
(3)代码加上注释仅有577行。(我下载过的两个俄罗斯方块代码一个在1087行,一个在993行,我的比它们代码少)。
(4)除了消除空格时算法比较复杂,其他算法都比较简单易读。
(5)绘图效率和局部代码效率扔有待提高。
(6)FrameTime参数可能依据不同硬件环境进行具体设置,InitGame需要正确的TC路径。

/********************************/
/* Desc: 俄罗斯方块游戏 */
/* By: hoodlum1980 */
/* Email: */
/* Date: 2008.03.12 22:30 */
/********************************/
#include <stdio.h>
#include <bios.h>
#include <dos.h>
#include <graphics.h>
#include <string.h>
#include <stdlib.h>
#define true 1
#define false 0
#define BoardWidth 12
#define BoardHeight 23
#define _INNER_HELPER /*inner helper method */
/*Scan Codes Define*/
enum KEYCODES
{
K_ESC =0x011b,
K_UP =0x4800, /* upward arrow */
K_LEFT =0x4b00,
K_DOWN =0x5000,
K_RIGHT =0x4d00,
K_SPACE =0x3920,
K_P =0x1970
};

/* the data structure of the block */
typedef struct tagBlock
{
char c[4][4]; /* cell fill info array, 0-empty, 1-filled */
int x; /* block position cx [ 0,BoardWidht -1] */
int y; /* block position cy [-4,BoardHeight-1] */
char color; /* block color */
char size; /* block max size in width or height */
char name; /* block name (the block's shape) */
} Block;

/* game's global info */
int FrameTime= 1300;
int CellSize= 18;
int BoardLeft= 30;
int BoardTop= 30;

/* next block grid */
int NBBoardLeft= 300;
int NBBoardTop= 30;
int NBCellSize= 10;

/* score board position */
int ScoreBoardLeft= 300;
int ScoreBoardTop=100;
int ScoreBoardWidth=200;
int ScoreBoardHeight=35;
int ScoreColor=LIGHTCYAN;

/* infor text postion */
int InfoLeft=300;
int InfoTop=200;
int InfoColor=YELLOW;

int BorderColor=DARKGRAY;
int BkGndColor=BLACK;
int GameRunning=true;
int TopLine=BoardHeight-1; /* top empty line */
int TotalScore=100;
char info_score[20];
char info_help[255];
char info_common[255];

/* our board, Board[x][y][0]-isFilled, Board[x][y][1]-fillColor */
unsigned char Board[BoardWidth][BoardHeight][2];
char BufferCells[4][4]; /* used to judge if can rotate block */
Block curBlock; /* current moving block */
Block nextBlock; /* next Block to appear */

/* function list */
int GetKeyCode();
int CanMove(int dx,int dy);
int CanRotate();
int RotateBlock(Block *block);
int MoveBlock(Block *block,int dx,int dy);
void DrawBlock(Block *block,int,int,int);
void EraseBlock(Block *block,int,int,int);
void DisplayScore();
void DisplayInfo(char* text);
void GenerateBlock(Block *block);
void NextBlock();
void InitGame();
int PauseGame();
void QuitGame();

/*Get Key Code */
int GetKeyCode()
{
int key=0;
if(bioskey(1))
{
key=bioskey(0);
}
return key;
}

/* display text! */
void DisplayInfo(char *text)
{
setcolor(BkGndColor);
outtextxy(InfoLeft,InfoTop,info_common);
strcpy(info_common,text);
setcolor(InfoColor);
outtextxy(InfoLeft,InfoTop,info_common);
}

/* create a new block by key number,
* the block anchor to the top-left corner of 4*4 cells
*/
void _INNER_HELPER GenerateBlock(Block *block)
{
int key=(random(13)*random(17)+random(1000)+random(3000))%7;
block->size=3;/* because most blocks' size=3 */
memset(block->c,0,16);
switch(key)
{
case 0:
block->name='T';
block->color=RED;
block->c[1][0]=1;
block->c[1][1]=1, block->c[2][1]=1;
block->c[1][2]=1;
break;
case 1:
block->name='L';
block->color=YELLOW;
block->c[1][0]=1;
block->c[1][1]=1;
block->c[1][2]=1, block->c[2][2]=1;
break;
case 2:
block->name='J';
block->color=LIGHTGRAY;
block->c[1][0]=1;
block->c[1][1]=1;
block->c[1][2]=1, block->c[0][2]=1;
break;
case 3:
block->name='z';
block->color=CYAN;
block->c[0][0]=1, block->c[1][0]=1;
block->c[1][1]=1, block->c[2][1]=1;
break;
case 4:
block->name='5';
block->color=LIGHTBLUE;
block->c[1][0]=1, block->c[2][0]=1;
block->c[0][1]=1, block->c[1][1]=1;
break;
case 5:
block->name='o';
block->color=BLUE;
block->size=2;
block->c[0][0]=1, block->c[1][0]=1;
block->c[0][1]=1, block->c[1][1]=1;
break;
case 6:
block->name='I';
block->color=GREEN;
block->size=4;
block->c[1][0]=1;
block->c[1][1]=1;
block->c[1][2]=1;
block->c[1][3]=1;
break;
}
}

/* get next block! */
void NextBlock()
{
/* copy the nextBlock to curBlock */
curBlock.size=nextBlock.size;
curBlock.color=nextBlock.color;
curBlock.x=(BoardWidth-4)/2;
curBlock.y=-curBlock.size;
memcpy(curBlock.c,nextBlock.c,16);
/* generate nextBlock and show it */
EraseBlock(&nextBlock,NBBoardLeft,NBBoardTop,NBCellSize);
GenerateBlock(&nextBlock);
nextBlock.x=1,nextBlock.y=0;
DrawBlock(&nextBlock,NBBoardLeft,NBBoardTop,NBCellSize);
}

/* rotate the block, update the block struct data */
int _INNER_HELPER RotateCells(char c[4][4],char blockSize)
{
char temp,i,j;
switch(blockSize)
{
case 3:
temp=c[0][0];
c[0][0]=c[2][0], c[2][0]=c[2][2], c[2][2]=c[0][2], c[0][2]=temp;
temp=c[0][1];
c[0][1]=c[1][0], c[1][0]=c[2][1], c[2][1]=c[1][2], c[1][2]=temp;
break;
case 4: /* only 'I' block arived here! */
c[1][0]=1-c[1][0], c[1][2]=1-c[1][2], c[1][3]=1-c[1][3];
c[0][1]=1-c[0][1], c[2][1]=1-c[2][1], c[3][1]=1-c[3][1];
break;
}
}

/* judge if the block can move toward the direction */
int CanMove(int dx,int dy)
{
int i,j,tempX,tempY;
for(i=0;i<curBlock.size;i++)
{
for(j=0;j<curBlock.size;j++)
{
if(curBlock.c[i][j])
{
/* cannot move leftward or rightward */
tempX = curBlock.x + i + dx;
if(tempX<0 || tempX>(BoardWidth-1)) return false; /* make sure x is valid! */
/* cannot move downward */
tempY = curBlock.y + j + dy;
if(tempY>(BoardHeight-1)) return false; /* y is only checked lower bound, maybe negative!!!! */
/* the cell already filled, we must check Y's upper bound before check cell ! */
if(tempY>=0 && Board[tempX][tempY][0]) return false;
}
}
}
return true;
}

/* judge if the block can rotate */
int CanRotate()
{
int i,j,tempX,tempY;
/* update buffer */
memcpy(BufferCells, curBlock.c, 16);
RotateCells(BufferCells,curBlock.size);
for(i=0;i<curBlock.size;i++)
{
for(j=0;j<curBlock.size;j++)
{
if(BufferCells[i][j])
{
tempX=curBlock.x+i;
tempY=curBlock.y+j;
if(tempX<0 || tempX>(BoardWidth-1))
return false;
if(tempY>(BoardHeight-1))
return false;
if(tempY>=0 && Board[tempX][tempY][0])
return false;
}
}
}
return true;
}

/* draw the block */
void _INNER_HELPER DrawBlock(Block *block,int bdLeft,int bdTop,int cellSize)
{
int i,j;
setfillstyle(SOLID_FILL,block->color);
for(i=0;i<block->size;i++)
{
for(j=0;j<block->size;j++)
{
if(block->c[i][j] && (block->y+j)>=0)
{
floodfill(
bdLeft+cellSize*(i+block->x)+cellSize/2,
bdTop+cellSize*(j+block->y)+cellSize/2,
BorderColor);
}
}
}
}

/* Rotate the block, if success, return true */
int RotateBlock(Block *block)
{
char temp,i,j;
int b_success;
if(curBlock.size==2)
return;
if(( b_success=CanRotate()))
{
EraseBlock(block,BoardLeft,BoardTop,CellSize);
memcpy(curBlock.c,BufferCells,16);
DrawBlock(block,BoardLeft,BoardTop,CellSize);
}
return b_success;
}

/* erase a block, only fill the filled cell with background color */
void _INNER_HELPER EraseBlock(Block *block,int bdLeft,int bdTop,int cellSize)
{
int i,j;
setfillstyle(SOLID_FILL,BkGndColor);
for(i=0;i<block->size;i++)
{
for(j=0;j<block->size;j++)
{
if(block->c[i][j] && (block->y+j>=0))
{
floodfill(
bdLeft+cellSize*(i+block->x)+cellSize/2,
bdTop+cellSize*(j+block->y)+cellSize/2,
BorderColor);
}
}
}
}

/* move by the direction if can, donothing if cannot
* return value: true - success, false - cannot move toward this direction
*/
int MoveBlock(Block *block,int dx,int dy)
{
int b_canmove=CanMove(dx,dy);
if(b_canmove)
{
EraseBlock(block,BoardLeft,BoardTop,CellSize);
curBlock.x+=dx;
curBlock.y+=dy;
DrawBlock(block,BoardLeft,BoardTop,CellSize);
}
return b_canmove;
}

/* drop the block to the bottom! */
int DropBlock(Block *block)
{
EraseBlock(block,BoardLeft,BoardTop,CellSize);
while(CanMove(0,1))
{
curBlock.y++;
}
DrawBlock(block,BoardLeft,BoardTop,CellSize);
return 0;/* return value is assign to the block's alive */
}

/* init the graphics mode, draw the board grid */
void InitGame()
{
int i,j,gdriver=DETECT,gmode;
struct time sysTime;
/* draw board cells */
memset(Board,0,BoardWidth*BoardHeight*2);
memset(nextBlock.c,0,16);
strcpy(info_help,"P: Pause Game. --by hoodlum1980");
initgraph(&gdriver,&gmode,"c:\\tc\\");
setcolor(BorderColor);
for(i=0;i<=BoardWidth;i++)
{
line(BoardLeft+i*CellSize, BoardTop, BoardLeft+i*CellSize, BoardTop+ BoardHeight*CellSize);
}
for(i=0;i<=BoardHeight;i++)
{
line(BoardLeft, BoardTop+i*CellSize, BoardLeft+BoardWidth*CellSize, BoardTop+ i*CellSize);
}
/* draw board outer border rect */
rectangle(BoardLeft-CellSize/4, BoardTop-CellSize/4,
BoardLeft+BoardWidth*CellSize+CellSize/4,
BoardTop+BoardHeight*CellSize+CellSize/4);

/* draw next block grids */
for(i=0;i<=4;i++)
{
line(NBBoardLeft+i*NBCellSize, NBBoardTop, NBBoardLeft+i*NBCellSize, NBBoardTop+4*NBCellSize);
line(NBBoardLeft, NBBoardTop+i*NBCellSize, NBBoardLeft+4*NBCellSize, NBBoardTop+ i*NBCellSize);
}

/* draw score rect */
rectangle(ScoreBoardLeft,ScoreBoardTop,ScoreBoardLeft+ScoreBoardWidth,ScoreBoardTop+ScoreBoardHeight);
DisplayScore();

/* set new seed! */
gettime(&sysTime);
srand(sysTime.ti_hour*3600+sysTime.ti_min*60+sysTime.ti_sec);

GenerateBlock(&nextBlock);
NextBlock(); /* create first block */
setcolor(DARKGRAY);
outtextxy(InfoLeft,InfoTop+20,"Up -rotate Space-drop");
outtextxy(InfoLeft,InfoTop+35,"Left-left Right-right");
outtextxy(InfoLeft,InfoTop+50,"Esc -exit");
DisplayInfo(info_help);
}

/* set the isFilled and fillcolor data to the board */
void _INNER_HELPER FillBoardData()
{
int i,j;
for(i=0;i<curBlock.size;i++)
{
for(j=0;j<curBlock.size;j++)
{
if(curBlock.c[i][j] && (curBlock.y+j)>=0)
{
Board[curBlock.x+i][curBlock.y+j][0]=1;
Board[curBlock.x+i][curBlock.y+j][1]=curBlock.color;
}
}
}
}

/* draw one line of the board */
void _INNER_HELPER PaintBoard()
{
int i,j,fillcolor;
for(j=max((TopLine-4),0);j<BoardHeight;j++)
{
for(i=0;i<BoardWidth;i++)
{
fillcolor=Board[i][j][0]? Board[i][j][1]:BkGndColor;
setfillstyle(SOLID_FILL,fillcolor);
floodfill(BoardLeft+i*CellSize+CellSize/2,BoardTop+j*CellSize+CellSize/2,BorderColor);
}
}
}

/* check if one line if filled full and increase the totalScore! */
void _INNER_HELPER CheckBoard()
{
int i,j,k,score=10,sum=0,topy,lines=0;
/* we find the top empty line! */
j=topy=BoardHeight-1;
do
{
sum=0;
for(i=0;i< BoardWidth; i++)
{
sum+=Board[i][topy][0];
}
topy--;
} while(sum>0 && topy>0);

/* remove the full filled line (max remove lines count = 4) */
do
{
sum=0;
for(i=0;i< BoardWidth; i++)
sum+=Board[i][j][0];

if(sum==BoardWidth)/* we find this line is full filled, remove it! */
{
/* move the cells data down one line */
for(k=j; k > topy;k--)
{
for(i=0;i<BoardWidth;i++)
{
Board[i][k][0]=Board[i][k-1][0];
Board[i][k][1]=Board[i][k-1][1];
}
}
/*make the top line empty! */
for(i=0;i<BoardWidth;i++)
{
Board[i][topy][0]=0;
Board[i][topy][1]=0;
}
topy++; /* move the topline downward one line! */
lines++; /* lines <=4 */
TotalScore+=score;
score*=2; /* adding: 10, 30, 70, 150 */
}
else
j--;
} while(sum>0 && j>topy && lines<4);
/* speed up the game when score is high, minimum is 400 */
FrameTime=max(1200-100*(TotalScore/200), 400);
TopLine=topy;/* update the top line */
/* if no lines remove, only add 1: */
if(lines==0)
TotalScore++;
}

/* display the score */
void _INNER_HELPER DisplayScore()
{
setcolor(BkGndColor);
outtextxy(ScoreBoardLeft+5,ScoreBoardTop+5,info_score);
setcolor(ScoreColor);
sprintf(info_score,"Score: %d",TotalScore);
outtextxy(ScoreBoardLeft+5,ScoreBoardTop+5,info_score);
}

/* we call this function when a block is inactive. */
void UpdateBoard()
{
FillBoardData();
CheckBoard();
PaintBoard();
DisplayScore();
}

/* pause the game, and timer handler stop move down the block! */
int PauseGame()
{
int key=0;
DisplayInfo("Press P to Start or Resume!");
while(key!=K_P && key!=K_ESC)
{
while(!(key=GetKeyCode())){}
}
DisplayInfo(info_help);
return key;
}

/* quit the game and do cleaning work. */
void QuitGame()
{
closegraph();
}
/* the entry point function. */
void main()
{
int i,flag=1,j,key=0,tick=0;
InitGame();
if(PauseGame()==K_ESC)
goto GameOver;
/* wait until a key pressed */
while(key!=K_ESC)
{
/* wait until a key pressed */
while(!(key=GetKeyCode()))
{
tick++;
if(tick>=FrameTime)
{
/* our block has dead! (can't move down), we get next block */
if(!MoveBlock(&curBlock,0,1))
{
UpdateBoard();
NextBlock();
if(!CanMove(0,1))
goto GameOver;
}
tick=0;
}
delay(100);
}
switch(key)
{
case K_LEFT:
MoveBlock(&curBlock,-1,0);
break;
case K_RIGHT:
MoveBlock(&curBlock,1,0);
break;
case K_DOWN:
MoveBlock(&curBlock,0,1);
break;
case K_UP:
RotateBlock(&curBlock);
break;
case K_SPACE:
DropBlock(&curBlock);
break;
case K_P:
PauseGame();
break;
}
}
GameOver:
DisplayInfo("GAME OVER! Press any key to exit!");
getch(); /* wait the user Press any key. */
QuitGame();
}
----------------------------------【代e799bee5baa6e79fa5e98193e78988e69d83339码文件结尾】--------------------------------------------------

相关阅读

关键词不能为空

标签导航

求恶灵附身的加点 马上9要下好PC恶灵附身了求全操作,新手玩必须知道的东西?... 我刚下载的恶灵附身不知怎么加点 求单机游戏恶灵附身游民版资源,要3DM破解的,网盘,好的加分 想问下哪个知道这首CS wcg 全球竞技联赛主题曲叫什么名字... CS的主题曲有哪些 CS经典视频的经典歌曲? wcg - cs - 反恐精英全球 竞赛主题曲播放地址 天龙八部的补丁怎么手动安装 天龙八部无法更新到最新版本,下手动补丁怎么不能安装? 天龙八部手动安装补丁安在游戏中的哪个文件夹? 我下载了天龙八部的补丁 怎么安装呢? 求此CG动态图出处 这张图都出自什么游戏主角是谁 求这幅动图的出处,怎么看起来好像是寂静岭?(请忽视底下的字幕... 求《美国末日》所有的原图和概念图~~~打包的 求一个简单的c语言写的俄罗斯方块程序 c语言俄罗斯方块代码 用C语言编写的俄罗斯方块代码? 俄罗斯方块c语言的代码 香港电影明星十大恶人 香港80、90年代,电影圈“十大恶人”都有谁??? 香港电影十大反派演员是哪几个? 娱乐圈十大恶人演员 天龙八部3D神翼系统怎么玩 天龙八部3D峨眉什么属性比较好 峨眉属性 天龙八部3d神翼属性怎么选战力高 天龙八部3d逍遥天降神翼要什么属性好 为什么美国枪击事件会很多 为什么美国频发枪击事件? 为什么美国经常发生枪击案? 美国为什么这么多枪击案啊 恶魔城系列游戏的剧情 如果我要通过玩游戏而了解恶魔城的历史该怎么个顺序玩 那个叫IGA的家伙,在恶魔城历史上是个什么角色 《恶魔城》的背景介绍… 7.0dk升级什么天赋好 nga 新手DK练级到底用什么天赋 7.0dk练级什么天赋好 练级的时候dk用什么专精比较好 天龙八部3丐帮天龙那个好 天龙八部3丐帮PK强吗? 天龙八部丐帮打架 天龙八部丐帮打架为什么不行!!!大家来说下 挑选婚礼敬酒礼服要注意的事项有哪些 新娘如何挑选婚礼敬酒服呢 敬酒服怎么选择,有什么忌讳么? 如何挑选婚礼上的敬酒服? 英雄联盟皮城女警和赏金猎人的特点求分析,谁比较容易杀英雄? 英雄联盟中哪个的胸最大? A赏金 B琴女 C阿狸 D妖姬 E... 赏金猎人怎么打妖姬 英雄联盟英雄称号名字还有人们叫出来的外号还有一些术语 暗黑破坏神3里面那个炼狱牧牛杖到底是什么东西....说的详细...