俄罗斯方块的实现—C语言

目录

简单解释几个函数:

1、制作俄罗斯方块:

2、 判断方块是否可以移动

3、 判断是否满行

 完整代码如下:

 运行界面展示:


█ 开发工具:Dev  C++

简单解释几个函数:

 

1、制作俄罗斯方块:

/*
  *制作俄罗斯方块
  */
  void MakeTetris(struct Tetris *tetris)
  {
  	a[tetris->x][tetris->y ]=b[0];
  	switch(tetris->flag)
  	{
  		case 1:
  		{
  			color(2);
  			a[tetris->x][tetris->y-1]=b[1];
  			a[tetris->x+2][tetris->y-1]=b[2];
  			a[tetris->x+2][tetris->y]=b[3];
  			break;
			  }
			  
		case 2:
  		{
  			color(3);
  			a[tetris->x-2][tetris->y]=b[1];
  			a[tetris->x+2][tetris->y]=b[2];
  			a[tetris->x+4][tetris->y]=b[3];
  			break;
			  }
			  
		case 3:
  		{
  			color(3);
  			a[tetris->x][tetris->y-1]=b[1];
  			a[tetris->x][tetris->y-2]=b[2];
  			a[tetris->x][tetris->y+1]=b[3];
  			break;
			  }
			  
		 case 4:
  		{
  			color(11);
  			a[tetris->x-2][tetris->y]=b[1];
  			a[tetris->x+2][tetris->y]=b[2];
  			a[tetris->x][tetris->y+1]=b[3];
  			break;
			  }
			  
			  
		case 5:
  		{
  			color(11);
  			a[tetris->x][tetris->y-1]=b[1];
  			a[tetris->x][tetris->y+1]=b[2];
  			a[tetris->x-2][tetris->y]=b[3];
  			break;
			  }
			  
			  
		case 6:
  		{
  			color(11);
  			a[tetris->x][tetris->y-1]=b[1];
  			a[tetris->x-2][tetris->y]=b[2];
  			a[tetris->x+2][tetris->y]=b[3];
  			break;
			  }
			  
			  
		case 7:
  		{
  			color(11);
  			a[tetris->x][tetris->y-1]=b[1];
  			a[tetris->x][tetris->y+1]=b[2];
  			a[tetris->x+2][tetris->y]=b[3];
  			break;
			  }
			  
			  
		case 8:
  		{
  			color(6);
  			a[tetris->x][tetris->y+1]=b[1];
  			a[tetris->x-2][tetris->y]=b[2];
  			a[tetris->x+2][tetris->y+1]=b[3];
  			break;
			  }
			  
			  
		case 9:
  		{
  			color(6);
  			a[tetris->x][tetris->y-1]=b[1];
  			a[tetris->x-2][tetris->y]=b[2];
  			a[tetris->x-2][tetris->y+1]=b[3];
  			break;
			  }
			  
			  
		case 10:
  		{
  			color(6);
  			a[tetris->x][tetris->y-1]=b[1];
  			a[tetris->x-2][tetris->y-1]=b[2];
  			a[tetris->x+2][tetris->y]=b[3];
  			break;
			  }
			  
			  
		case 11:
  		{
  			color(6);
  			a[tetris->x][tetris->y+1]=b[1];
  			a[tetris->x-2][tetris->y-1]=b[2];
  			a[tetris->x-2][tetris->y]=b[3];
  			break;
			  }
			  
			  
		case 12:
  		{
  			color(7);
  			a[tetris->x][tetris->y-1]=b[1];
  			a[tetris->x][tetris->y+1]=b[2];
  			a[tetris->x-2][tetris->y-1]=b[3];
  			break;
			  }
			  
			  
	    case 13:
  		{
  			color(7);
  			a[tetris->x-2][tetris->y]=b[1];
  			a[tetris->x+2][tetris->y-1]=b[2];
  			a[tetris->x+2][tetris->y]=b[3];
  			break;
			  }
			  
		case 14:
  		{
  			color(7);
  			a[tetris->x][tetris->y-1]=b[1];
  			a[tetris->x][tetris->y+1]=b[2];
  			a[tetris->x+2][tetris->y+1]=b[3];
  			break;
			  }
			  
			  
		case 15:
  		{
  			color(7);
  			a[tetris->x-2][tetris->y]=b[1];
  			a[tetris->x-2][tetris->y+1]=b[2];
  			a[tetris->x+2][tetris->y]=b[3];
  			break;
			  }
			  
			  
			  
		case 16:
  		{
  			color(7);
  			a[tetris->x][tetris->y+1]=b[1];
  			a[tetris->x][tetris->y-1]=b[2];
  			a[tetris->x+2][tetris->y-1]=b[3];
  			break;
			  }
			  
			  
		case 17:
  		{
  			color(7);
  			a[tetris->x-2][tetris->y]=b[1];
  			a[tetris->x+2][tetris->y+1]=b[2];
  			a[tetris->x+2][tetris->y]=b[3];
  			break;
			  }
			  
		case 18:
  		{
  			color(7);
  			a[tetris->x][tetris->y-1]=b[1];
  			a[tetris->x][tetris->y+1]=b[2];
  			a[tetris->x-2][tetris->y+1]=b[3];
  			break;
			  }
			  
		case 19:
  		{
  			color(7);
  			a[tetris->x-2][tetris->y]=b[1];
  			a[tetris->x-2][tetris->y-1]=b[2];
  			a[tetris->x+2][tetris->y]=b[3];
  			break;
			  }
	  }
   } 
   

✔在本游戏中,使用“■”来填充各种方块,在横向上,它占两个字符;在纵向上,它占一个字符。俄罗斯方块的7种基本图形旋转后共有19种旋转图形。而此段代码就是制作出这19种俄罗斯形状。

 

2、 判断方块是否可以移动

/*
  *判断是否可移动
  */
  int ifMove(struct Tetris *tetris)   //判断该点是否可以移动
{
 	if(a[tetris->x][tetris->y]!=0)//当中心方块位置上有图案时,返回值为0,即不可移动
 	{
  		return 0;
 	}
 	else
 	{
  		if( 
   		( tetris->flag==1  && ( a[tetris->x][tetris->y-1]==0   &&
    	a[tetris->x+2][tetris->y-1]==0 && a[tetris->x+2][tetris->y]==0 ) ) ||
   		( tetris->flag==2  && ( a[tetris->x-2][tetris->y]==0   && 
    	a[tetris->x+2][tetris->y]==0 && a[tetris->x+4][tetris->y]==0 ) )   ||
   		( tetris->flag==3  && ( a[tetris->x][tetris->y-1]==0   &&
    	a[tetris->x][tetris->y-2]==0 && a[tetris->x][tetris->y+1]==0 ) )   ||
   		( tetris->flag==4  && ( a[tetris->x-2][tetris->y]==0   &&
    	a[tetris->x+2][tetris->y]==0 && a[tetris->x][tetris->y+1]==0 ) )   ||
   		( tetris->flag==5  && ( a[tetris->x][tetris->y-1]==0   &&
   		 a[tetris->x][tetris->y+1]==0 && a[tetris->x-2][tetris->y]==0 ) )   ||
   		( tetris->flag==6  && ( a[tetris->x][tetris->y-1]==0   &&
    	a[tetris->x-2][tetris->y]==0 && a[tetris->x+2][tetris->y]==0 ) )   ||
   		( tetris->flag==7  && ( a[tetris->x][tetris->y-1]==0   &&
    	a[tetris->x][tetris->y+1]==0 && a[tetris->x+2][tetris->y]==0 ) )   ||
   		( tetris->flag==8  && ( a[tetris->x][tetris->y+1]==0   &&
    	a[tetris->x-2][tetris->y]==0 && a[tetris->x+2][tetris->y+1]==0 ) ) ||
   		( tetris->flag==9  && ( a[tetris->x][tetris->y-1]==0   &&
    	a[tetris->x-2][tetris->y]==0 && a[tetris->x-2][tetris->y+1]==0 ) ) ||
   		( tetris->flag==10 && ( a[tetris->x][tetris->y-1]==0   &&
    	a[tetris->x-2][tetris->y-1]==0 && a[tetris->x+2][tetris->y]==0 ) ) ||
   		( tetris->flag==11 && ( a[tetris->x][tetris->y+1]==0   &&
    	a[tetris->x-2][tetris->y-1]==0 && a[tetris->x-2][tetris->y]==0 ) ) ||
   		( tetris->flag==12 && ( a[tetris->x][tetris->y-1]==0   &&
    	a[tetris->x][tetris->y+1]==0 && a[tetris->x-2][tetris->y-1]==0 ) ) ||
   		( tetris->flag==15 && ( a[tetris->x-2][tetris->y]==0   &&
    	a[tetris->x-2][tetris->y+1]==0 && a[tetris->x+2][tetris->y]==0 ) ) ||
   		( tetris->flag==14 && ( a[tetris->x][tetris->y-1]==0   &&
    	a[tetris->x][tetris->y+1]==0 && a[tetris->x+2][tetris->y+1]==0 ) ) ||
   		( tetris->flag==13 && ( a[tetris->x-2][tetris->y]==0   &&
    	a[tetris->x+2][tetris->y-1]==0 && a[tetris->x+2][tetris->y]==0 ) ) ||
   		( tetris->flag==16 && ( a[tetris->x][tetris->y+1]==0   &&
    	a[tetris->x][tetris->y-1]==0 && a[tetris->x+2][tetris->y-1]==0 ) ) ||
   		( tetris->flag==19 && ( a[tetris->x-2][tetris->y]==0   &&
    	a[tetris->x-2][tetris->y-1]==0 && a[tetris->x+2][tetris->y]==0 ) ) ||
   		( tetris->flag==18 && ( a[tetris->x][tetris->y-1]==0   &&
    	a[tetris->x][tetris->y+1]==0 && a[tetris->x-2][tetris->y+1]==0 ) ) ||
   		( tetris->flag==17 && ( a[tetris->x-2][tetris->y]==0   &&
    	a[tetris->x+2][tetris->y+1]==0 && a[tetris->x+2][tetris->y]==0 ) ) )
   		{
    		return 1;
   		}
	}
 	return 0;
}

✔要判断移动到的位置是不是空位置,首先判断此位置中心方块是否是方块或墙壁,如果是方块或者墙壁,则不可移动;如果不是,则继续判断,如果19种形状的俄罗斯方块的各自的“■” 位置上都是空,那么表示可以移动。

 

3、 判断是否满行

/*
 *判断是否满行,并删除满行的俄罗斯方块
 */
 void Del_Fullline(struct Tetris *tetris)
{
		int k, del_rows = 0;  //分别用于记录某行方块的个数和删除方块的行数的变量
	for (j = FrameY + Frame_height - 1; j >= FrameY + 1; j--)
	{
		k = 0;
		for (i = FrameX + 2; i<FrameX + 2 * Frame_width - 2; i += 2)
		{
			if (a[i][j] == 1) //竖坐标依次从下往上,横坐标依次由左至右判断是否满行
			{
				k++;  //记录此行方块的个数
				if (k == Frame_width - 2)  //如果满行 
				{
					for (k = FrameX + 2; k<FrameX + 2 * Frame_width - 2; k += 2)//删除满行的方块
					{
						a[k][j] = 0;
						gotoxy(k, j);
						printf("  ");
						//      					Sleep(1);
					}
					for (k = j - 1; k>FrameY; k--) //如果删除行以上的位置有方块,则先清除,再将方块下移一个位置
					{
						for (i = FrameX + 2; i<FrameX + 2 * Frame_width - 2; i += 2)
						{
							if (a[i][k] == 1)
							{
								a[i][k] = 0;
								gotoxy(i, k);
								printf("  ");
								a[i][k + 1] = 1;
								gotoxy(i, k + 1);
								printf("■");
							}
						}
					}
					j++;   //方块下移后,重新判断删除行是否满行
					del_rows++; //记录删除方块的行数
				}
			}
		}
	}
	tetris->score += 10* del_rows; //每删除一行,得10分
	tetris->speed -= 20*del_rows; //速度加快20ms
	if (del_rows>0 && (tetris->score % 20 == 0 || tetris->score / 20>tetris->rank - 1))
	{        //如果得20分即累计删除2行.进一级 
		tetris->rank++;
	}
}

 

 

 完整代码如下:

/*******头 文 件*******/ 
#include <stdio.h>  //标准输入输出函数库 
#include <windows.h>  //控制 DOS界面(获取控制台上坐标位置、设置字体颜色) 
#include<conio.h>	//接受键盘输入输出 
#include<time.h>	//用于获得随机数
 


/******* 宏 定 义 *******/ 
#define FrameX 4	//游戏窗口左上角的X轴坐标为13 
#define FrameY 4	// 游戏窗口左上角的Y轴坐标为3 
#define Frame_height 20	//游戏窗口的高度为20 
#define Frame_width  18	// 游戏窗口的宽度为18

/******* 定 义 全 局 变 量********/ 
int i,j,Temp,Temp1,Temp2,speed;
int score=0;
int rank=0;
int a[80][80]={0};
int b[4];
int HighScore=0; 
struct Tetris{
	int x;
	int y;
	int flag;
	int next;
	int speed;
	int number;
	int score;
	int rank; 
};
HANDLE hOut;

/********函 数 声 明********/
int color(int c);
void gotoxy(int x,int y);
void gameTime(clock_t star_time);
void DrawGameframe();
void Flag(struct Tetris*);
void MaKeTetris(struct Tetris*);
void PrintTetris(struct Tetris*);
void CleanTetris(struct Tetris*);
int ifMove(struct Tetris*);
void Del_Fullline(struct Tetris*);
void updateGrade() ;
void Gameplay();
void regulation();
void explation();
void welcom();
void Replay(struct Tetris*tetris);
void title();
void rabbit();
void HideCursor();
void close();
void File_in();
void File_out();


int main() 
{	
	HideCursor();
	title();
	rabbit();
	welcom();
	File_out();
	return 0;

}
 
/**
 *文字颜色函数
 */ 
int color(int c)
{
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),c);
	return 0;
}


/**
 *获取屏幕光标位置 
 */ 
void gotoxy(int x,int y)
{
	COORD pos;
	pos.X=x;
	pos.Y=y;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);

}
//隐藏光标
void HideCursor()
{
 CONSOLE_CURSOR_INFO curInfo; //定义光标信息的结构体变量
 curInfo.dwSize = 1;  //如果没赋值的话,隐藏光标无效
 curInfo.bVisible = FALSE; //将光标设置为不可见
 HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); //获取控制台句柄
 SetConsoleCursorInfo(handle, &curInfo); //设置光标信息
}


/**
 *欢迎界面上方的标题 
 */ 

void title(){
	color(9);//深蓝色 
	gotoxy(24,3);
	printf("趣 味 俄 罗 斯 方 块n");
	color(11);
	gotoxy(18,5);
	printf("■");
	gotoxy(18,6);
	printf("■■");
	gotoxy(18,7);
	printf("■");
	
	color(6);
	gotoxy(26,6);
	printf("■■");
	gotoxy(28,7);
	printf("■■");
	 
	color(2);
	gotoxy(36,6);
	printf("■■");
	gotoxy(36,7);
	printf("■■");
	
	color(3);
	gotoxy(45,5);
	printf("■");
	gotoxy(45,6);
	printf("■");
	gotoxy(45,7);
	printf("■");
	gotoxy(45,8);
	printf("■");
	
	color(7);
	gotoxy(56,6);
	printf("■");
	gotoxy(52,7);
	printf("■■■");
}
  
 /**
  *绘制兔子 
  */ 
 void rabbit(){
 	gotoxy(64,7);
 	color(3);
 	printf(" │ ̄│ │ ̄│");
 	
 	gotoxy(64,8);
 	printf(" │  │ │  │");
 	
 	gotoxy(64,9);
 	printf(" │  │ │  │");
 	
    gotoxy(64,10);
 	printf("_│");
 	
 	gotoxy(73,10);
 	printf("│_");
 	
 	gotoxy(62,11);
 	printf("│");
 	
 	gotoxy(76,11);
 	printf("│");
 	
 	gotoxy(62,12);
 	printf("│             │");
 	
 	gotoxy(62,13);
 	printf("│             │");
 	
 	gotoxy(62,14);
 	printf("│             │");
 	
 	gotoxy(62,15);
 	printf("┗━━┯━━━┛━━━┱━━┛");
 	
 	gotoxy(64,16);
 	printf("┏┫       ┣┓");
 	
 	gotoxy(62,17);
 	printf("━━┸━━━━┷━━━━┷━━");
 	
 	gotoxy(67,11);	
    color(5);
    printf("`~'~`'");
 	color(12); 
 	gotoxy(67,12);
 	printf("○   ○");
 	
 	
 	gotoxy(65,13);
 	color(13);
 	printf("//");
 	
 	gotoxy(74,13);
 	printf("//");
 	
 	gotoxy(69,14);
 	color(2);
 	printf("┻");
 	
	
	gotoxy(65,19);
	color(4) ;
	printf("   光宗耀组"); 
	
	
 } 
 /*
  *菜单选项边框 
  */
void welcom()
{
	int n;
	int i,j=1;
	color(14);
	for (i=9;i<=20;i++)
	{
		for (j=15;j<=60;j++)
		{
			gotoxy(j,i);
			if (i==9||i==20) printf("=");
			else if (j==15||j==59) printf("||");
		}
	}
	//---desige menu option text 
	color(12);
	gotoxy(25,12);
	printf("1.开始游戏");
	 
	gotoxy(40,12);
	printf("2.按键说明");
	
	gotoxy(25,17);
	printf("3.游戏规则");
	
	gotoxy(40,17);
	printf("4.退出");
	
	gotoxy(21,22);
	color(3); 
	printf("请选择[1 2 3 4]:[ ]bb");
	color(14);
	scanf("%d",&n);
	switch(n)
	{
		case 1:
		       system("cls");
		       DrawGameframe();
		       Gameplay();
		    
		       break;
		case 2:
			   explation();
		       break;
		case 3:
		       regulation(); 
			   break;
		case 4:
		       close();
			   break;
	}
 } 
 /*
  *制作游戏窗口
  */
 void DrawGameframe()
{
	gotoxy(FrameX+Frame_width-7,FrameY-2);
	color(15);
	printf("趣味俄罗斯方块");
	gotoxy(FrameX+2*Frame_width+3,FrameY+7);
	color(7);
	printf("︻︻︻︻︻");
	gotoxy(FrameX+2*Frame_width+13,FrameY+7);
	color(15);
	printf("下一个出现方块:");
	gotoxy(FrameX+2*Frame_width+3,FrameY+13); 
	color(7);
	printf("︼︼︼︼︼");
	gotoxy(FrameX+2*Frame_width+3,FrameY+17); 
	color(8);
	printf("↑键:旋转");
	gotoxy(FrameX+2*Frame_width+3,FrameY+19);
	printf("空格:暂停游戏"); 
	gotoxy(FrameX+2*Frame_width+3,FrameY+15);
	printf("Esc:退出游戏"); 
	gotoxy(FrameX,FrameY);
	color(15);
	printf("〇");
	gotoxy(FrameX+2*Frame_width-2,FrameY);
	printf("〇");
	gotoxy(FrameX,FrameY+Frame_height);
	printf("〇");
	gotoxy(FrameX+2*Frame_width-2,FrameY+Frame_height);
	printf("〇");
	a[FrameX][FrameY+Frame_height]=2;                  //边框左下角的 a[13][23]=2,  防止方块出边框 
    a[FrameX+2*Frame_width-2][FrameY+Frame_height]=2;  //边框右下角的 a[47][23]=2,  防止方块出边框 
	for(i=2;i<2*Frame_width-2;i+=2)
	{
		gotoxy(FrameX+i,FrameY);
		printf("▃");
	}
	for(i=2;i<2*Frame_width-2;i+=2)
	{
		gotoxy(FrameX+i,FrameY+Frame_height);
		printf("▃");
		a[FrameX+i][FrameY+Frame_height]=2;
	}
	for(i=1;i<Frame_height;i++)
	{
		gotoxy(FrameX,FrameY+i);
		printf("▍");
		a[FrameX][FrameY+i]=2;
	}
	for(i=1;i<Frame_height;i++)
	{
		gotoxy(FrameX+2*Frame_width-1,FrameY+i);
		printf("▍");
		a[FrameX+2*Frame_width-2][FrameY+i]=2;
	}
}
   
 /*
  *制作俄罗斯方块
  */
  void MakeTetris(struct Tetris *tetris)
  {
  	a[tetris->x][tetris->y ]=b[0];
  	switch(tetris->flag)
  	{
  		case 1:
  		{
  			color(2);
  			a[tetris->x][tetris->y-1]=b[1];
  			a[tetris->x+2][tetris->y-1]=b[2];
  			a[tetris->x+2][tetris->y]=b[3];
  			break;
			  }
			  
		case 2:
  		{
  			color(3);
  			a[tetris->x-2][tetris->y]=b[1];
  			a[tetris->x+2][tetris->y]=b[2];
  			a[tetris->x+4][tetris->y]=b[3];
  			break;
			  }
			  
		case 3:
  		{
  			color(3);
  			a[tetris->x][tetris->y-1]=b[1];
  			a[tetris->x][tetris->y-2]=b[2];
  			a[tetris->x][tetris->y+1]=b[3];
  			break;
			  }
			  
		 case 4:
  		{
  			color(11);
  			a[tetris->x-2][tetris->y]=b[1];
  			a[tetris->x+2][tetris->y]=b[2];
  			a[tetris->x][tetris->y+1]=b[3];
  			break;
			  }
			  
			  
		case 5:
  		{
  			color(11);
  			a[tetris->x][tetris->y-1]=b[1];
  			a[tetris->x][tetris->y+1]=b[2];
  			a[tetris->x-2][tetris->y]=b[3];
  			break;
			  }
			  
			  
		case 6:
  		{
  			color(11);
  			a[tetris->x][tetris->y-1]=b[1];
  			a[tetris->x-2][tetris->y]=b[2];
  			a[tetris->x+2][tetris->y]=b[3];
  			break;
			  }
			  
			  
		case 7:
  		{
  			color(11);
  			a[tetris->x][tetris->y-1]=b[1];
  			a[tetris->x][tetris->y+1]=b[2];
  			a[tetris->x+2][tetris->y]=b[3];
  			break;
			  }
			  
			  
		case 8:
  		{
  			color(6);
  			a[tetris->x][tetris->y+1]=b[1];
  			a[tetris->x-2][tetris->y]=b[2];
  			a[tetris->x+2][tetris->y+1]=b[3];
  			break;
			  }
			  
			  
		case 9:
  		{
  			color(6);
  			a[tetris->x][tetris->y-1]=b[1];
  			a[tetris->x-2][tetris->y]=b[2];
  			a[tetris->x-2][tetris->y+1]=b[3];
  			break;
			  }
			  
			  
		case 10:
  		{
  			color(6);
  			a[tetris->x][tetris->y-1]=b[1];
  			a[tetris->x-2][tetris->y-1]=b[2];
  			a[tetris->x+2][tetris->y]=b[3];
  			break;
			  }
			  
			  
		case 11:
  		{
  			color(6);
  			a[tetris->x][tetris->y+1]=b[1];
  			a[tetris->x-2][tetris->y-1]=b[2];
  			a[tetris->x-2][tetris->y]=b[3];
  			break;
			  }
			  
			  
		case 12:
  		{
  			color(7);
  			a[tetris->x][tetris->y-1]=b[1];
  			a[tetris->x][tetris->y+1]=b[2];
  			a[tetris->x-2][tetris->y-1]=b[3];
  			break;
			  }
			  
			  
	    case 13:
  		{
  			color(7);
  			a[tetris->x-2][tetris->y]=b[1];
  			a[tetris->x+2][tetris->y-1]=b[2];
  			a[tetris->x+2][tetris->y]=b[3];
  			break;
			  }
			  
		case 14:
  		{
  			color(7);
  			a[tetris->x][tetris->y-1]=b[1];
  			a[tetris->x][tetris->y+1]=b[2];
  			a[tetris->x+2][tetris->y+1]=b[3];
  			break;
			  }
			  
			  
		case 15:
  		{
  			color(7);
  			a[tetris->x-2][tetris->y]=b[1];
  			a[tetris->x-2][tetris->y+1]=b[2];
  			a[tetris->x+2][tetris->y]=b[3];
  			break;
			  }
			  
			  
			  
		case 16:
  		{
  			color(7);
  			a[tetris->x][tetris->y+1]=b[1];
  			a[tetris->x][tetris->y-1]=b[2];
  			a[tetris->x+2][tetris->y-1]=b[3];
  			break;
			  }
			  
			  
		case 17:
  		{
  			color(7);
  			a[tetris->x-2][tetris->y]=b[1];
  			a[tetris->x+2][tetris->y+1]=b[2];
  			a[tetris->x+2][tetris->y]=b[3];
  			break;
			  }
			  
		case 18:
  		{
  			color(7);
  			a[tetris->x][tetris->y-1]=b[1];
  			a[tetris->x][tetris->y+1]=b[2];
  			a[tetris->x-2][tetris->y+1]=b[3];
  			break;
			  }
			  
		case 19:
  		{
  			color(7);
  			a[tetris->x-2][tetris->y]=b[1];
  			a[tetris->x-2][tetris->y-1]=b[2];
  			a[tetris->x+2][tetris->y]=b[3];
  			break;
			  }
	  }
   } 
   
   
   /*
    *打印俄罗斯方块
	*/
void PrintTetris(struct Tetris *tetris) 
{
	for(i=0;i<4;i++)
	{
		b[i]=1;
	}
		
	MakeTetris(tetris);
	                 
	for( i=tetris->x-2; i<=tetris->x+4;i+=2)
	{
		for(j=tetris->y-2;j<=tetris->y+1;j++)
		{
			if( a[i][j]==1 && j>FrameY)
			{
				gotoxy(i,j);
				printf("■") ;	
			}
		}	
	}
	----print menu message
	
	gotoxy(FrameX+2*Frame_width+3,FrameY-1);
	File_out();
	color(8);
	printf("最高记录:%d",HighScore); 
	gotoxy(FrameX+2*Frame_width+3,FrameY+1);
	color(8);
	printf("rank:  ");
	color(8);
	printf("%d",tetris->rank);
	
	gotoxy(FrameX+2*Frame_width+3,FrameY+3);
	color(8);
	printf("score:  ");
	color(8);
	printf("%d",tetris->score);
	
	gotoxy(FrameX+2*Frame_width+3,FrameY+5);
	color(8);
	printf("speed:  ");
	color(8);
	printf("%dms",tetris->speed);	 
}
 /*
  *判断是否可移动
  */
  int ifMove(struct Tetris *tetris)   //判断该点是否可以移动
{
 	if(a[tetris->x][tetris->y]!=0)//当中心方块位置上有图案时,返回值为0,即不可移动
 	{
  		return 0;
 	}
 	else
 	{
  		if( 
   		( tetris->flag==1  && ( a[tetris->x][tetris->y-1]==0   &&
    	a[tetris->x+2][tetris->y-1]==0 && a[tetris->x+2][tetris->y]==0 ) ) ||
   		( tetris->flag==2  && ( a[tetris->x-2][tetris->y]==0   && 
    	a[tetris->x+2][tetris->y]==0 && a[tetris->x+4][tetris->y]==0 ) )   ||
   		( tetris->flag==3  && ( a[tetris->x][tetris->y-1]==0   &&
    	a[tetris->x][tetris->y-2]==0 && a[tetris->x][tetris->y+1]==0 ) )   ||
   		( tetris->flag==4  && ( a[tetris->x-2][tetris->y]==0   &&
    	a[tetris->x+2][tetris->y]==0 && a[tetris->x][tetris->y+1]==0 ) )   ||
   		( tetris->flag==5  && ( a[tetris->x][tetris->y-1]==0   &&
   		 a[tetris->x][tetris->y+1]==0 && a[tetris->x-2][tetris->y]==0 ) )   ||
   		( tetris->flag==6  && ( a[tetris->x][tetris->y-1]==0   &&
    	a[tetris->x-2][tetris->y]==0 && a[tetris->x+2][tetris->y]==0 ) )   ||
   		( tetris->flag==7  && ( a[tetris->x][tetris->y-1]==0   &&
    	a[tetris->x][tetris->y+1]==0 && a[tetris->x+2][tetris->y]==0 ) )   ||
   		( tetris->flag==8  && ( a[tetris->x][tetris->y+1]==0   &&
    	a[tetris->x-2][tetris->y]==0 && a[tetris->x+2][tetris->y+1]==0 ) ) ||
   		( tetris->flag==9  && ( a[tetris->x][tetris->y-1]==0   &&
    	a[tetris->x-2][tetris->y]==0 && a[tetris->x-2][tetris->y+1]==0 ) ) ||
   		( tetris->flag==10 && ( a[tetris->x][tetris->y-1]==0   &&
    	a[tetris->x-2][tetris->y-1]==0 && a[tetris->x+2][tetris->y]==0 ) ) ||
   		( tetris->flag==11 && ( a[tetris->x][tetris->y+1]==0   &&
    	a[tetris->x-2][tetris->y-1]==0 && a[tetris->x-2][tetris->y]==0 ) ) ||
   		( tetris->flag==12 && ( a[tetris->x][tetris->y-1]==0   &&
    	a[tetris->x][tetris->y+1]==0 && a[tetris->x-2][tetris->y-1]==0 ) ) ||
   		( tetris->flag==15 && ( a[tetris->x-2][tetris->y]==0   &&
    	a[tetris->x-2][tetris->y+1]==0 && a[tetris->x+2][tetris->y]==0 ) ) ||
   		( tetris->flag==14 && ( a[tetris->x][tetris->y-1]==0   &&
    	a[tetris->x][tetris->y+1]==0 && a[tetris->x+2][tetris->y+1]==0 ) ) ||
   		( tetris->flag==13 && ( a[tetris->x-2][tetris->y]==0   &&
    	a[tetris->x+2][tetris->y-1]==0 && a[tetris->x+2][tetris->y]==0 ) ) ||
   		( tetris->flag==16 && ( a[tetris->x][tetris->y+1]==0   &&
    	a[tetris->x][tetris->y-1]==0 && a[tetris->x+2][tetris->y-1]==0 ) ) ||
   		( tetris->flag==19 && ( a[tetris->x-2][tetris->y]==0   &&
    	a[tetris->x-2][tetris->y-1]==0 && a[tetris->x+2][tetris->y]==0 ) ) ||
   		( tetris->flag==18 && ( a[tetris->x][tetris->y-1]==0   &&
    	a[tetris->x][tetris->y+1]==0 && a[tetris->x-2][tetris->y+1]==0 ) ) ||
   		( tetris->flag==17 && ( a[tetris->x-2][tetris->y]==0   &&
    	a[tetris->x+2][tetris->y+1]==0 && a[tetris->x+2][tetris->y]==0 ) ) )
   		{
    		return 1;
   		}
	}
 	return 0;
}

/*
 *在文件中读取最高分
 */
 void File_out()
 {
 	FILE *fp;
 	fp =fopen("save.txt","r+");
	fscanf(fp,"%d",&HighScore);
	fclose(fp);
 }
 
 /*
  *将最高分存储与文件中
  */
  void File_in()
  {
  	FILE *fp ;
	fp =fopen("save.txt","w+");
	fprintf(fp,"%d",HighScore);
	fclose(fp); 
   } 
 
 
 
  
/*
 *清除俄罗斯方块的痕迹 
 */ 
void CleanTetris(struct Tetris *tetris)
{
	for(i=0;i<4;i++)
	{
		b[i]=0;
	}
	MakeTetris(tetris);
	for(i=tetris->x-2;i<=tetris->x+4;i+=2)
	{
		for(j=tetris->y-2;j<=tetris->y+1;j++)
		{
			if(a[i][j]==0 && j>FrameY)
			{
				gotoxy(i,j);
				printf("  ");
			}
		}
	}
}


/*
 *判断是否满行,并删除满行的俄罗斯方块
 */
 void Del_Fullline(struct Tetris *tetris)
{
		int k, del_rows = 0;  //分别用于记录某行方块的个数和删除方块的行数的变量
	for (j = FrameY + Frame_height - 1; j >= FrameY + 1; j--)
	{
		k = 0;
		for (i = FrameX + 2; i<FrameX + 2 * Frame_width - 2; i += 2)
		{
			if (a[i][j] == 1) //竖坐标依次从下往上,横坐标依次由左至右判断是否满行
			{
				k++;  //记录此行方块的个数
				if (k == Frame_width - 2)  //如果满行 
				{
					for (k = FrameX + 2; k<FrameX + 2 * Frame_width - 2; k += 2)//删除满行的方块
					{
						a[k][j] = 0;
						gotoxy(k, j);
						printf("  ");
						//      					Sleep(1);
					}
					for (k = j - 1; k>FrameY; k--) //如果删除行以上的位置有方块,则先清除,再将方块下移一个位置
					{
						for (i = FrameX + 2; i<FrameX + 2 * Frame_width - 2; i += 2)
						{
							if (a[i][k] == 1)
							{
								a[i][k] = 0;
								gotoxy(i, k);
								printf("  ");
								a[i][k + 1] = 1;
								gotoxy(i, k + 1);
								printf("■");
							}
						}
					}
					j++;   //方块下移后,重新判断删除行是否满行
					del_rows++; //记录删除方块的行数
				}
			}
		}
	}
	tetris->score += 10* del_rows; //每删除一行,得10分
	tetris->speed -= 20*del_rows; //速度加快20ms
	if (del_rows>0 && (tetris->score % 20 == 0 || tetris->score / 20>tetris->rank - 1))
	{        //如果得20分即累计删除2行.进一级 
		tetris->rank++;
	}
}


/*
 *随机产生俄罗斯方块类型的序号
 */
 void Flag(struct Tetris*tetris)
 {
 	tetris->number++;
 	srand(time(NULL));
 	if(tetris->number==1)
	 {
 		tetris->flag=rand()%19+1;
	 }
	 tetris->next=rand()%19+1;
  } 
  
  /*
   *开始游戏
   */
 void Gameplay()
{
	int n;
	struct Tetris t,*tetris=&t;
	char ch;
	tetris->number=0;
	tetris->speed=300;
	tetris->score=0;
	tetris->rank=1;
	
	while(1)
	{
		Flag(tetris);                          //随机产生方块当前序号 和下一个序号 
		Temp=tetris->flag;                     //当前方块序号暂时保存 
		tetris->x=FrameX+2*Frame_width+6;      //右边预览界面方块坐标x=55 
		tetris->y=FrameY+10;                   //右边预览界面方块坐标y=13 
		tetris->flag = tetris->next;           //下一个方块序号暂给flag ,准备在预览窗口打印 
	
		PrintTetris(tetris);                    //在预览窗口打印下一个方块 
		
		tetris->x=FrameX+Frame_width;           //游戏窗口出现方块的中心方块坐标x=31 
		//tetris->x=FrameX+10;                         //改变游戏窗口出现方块的中心方块坐标x=13 
		tetris->y=FrameY-1;                      //游戏窗口出现方块的中心方块坐标y=2 
		tetris->flag=Temp;                       //找回当前方块序号 
	
		//--keys options按键操作 
		while(1)
		{
			label: PrintTetris(tetris);
			Sleep(tetris->speed);
			CleanTetris(tetris);
			Temp1=tetris->x;
			Temp2=tetris->flag;
			if(kbhit())         //   有键盘输入? 
			{
				ch=getch();    //  有,接受 输入 
				if(ch==75)     //   75 对应方向键 ←
				{
					tetris->x-=2;
				}
				if(ch==77)     //    77 对应方向键 → 
				{
					tetris->x+=2;
				}
				if(ch==80)     //     80 对应方向键 ↓----加速下落 
				{
					if(ifMove(tetris)!=0)  //判断可以移动吗? 
					{
				 		tetris->y+=2;	  //    可以,一次下落两行 
				 
					}
					if(ifMove(tetris)==0)  //如果不能移动 
						{
				 			tetris->y=FrameY+Frame_height-2;  //确定Y	
						}
				}
				if(ch==72)
				{
					if(tetris->flag>=2 && tetris->flag<=3)//  2/3 是直线方块 ,
						{
							tetris->flag++;    //if 2,then get 3   if 3, then get 4
							tetris->flag%=2;   //3%2=1              4%2=0
							tetris->flag+=2;   //1+2=3	            0+2=2
						}
					if(tetris->flag>=4 && tetris->flag<=7)  //      4/5/6/7  是T字方块 
						{
							tetris->flag++;    //if4 ,then get 5    if7,  then get 8 
							tetris->flag%=4;   //5%4=1                8%4=0
							tetris->flag+=4;   //1+4=5	              0+4=4
						}
					if(tetris->flag>=8 && tetris->flag<=11)
						{
							tetris->flag++;
							tetris->flag%=4;
							tetris->flag+=8;		
						}
					if(tetris->flag>=12 && tetris->flag<=15)
						{
							tetris->flag++;
							tetris->flag%=4;
							tetris->flag+=12;		
						}
					if(tetris->flag>=16 && tetris->flag<=19)
						{
							tetris->flag++;
							tetris->flag%=4;
							tetris->flag+=16;		
						}
					
				}
				if(ch == 32)   //空格键  暂停 
				{
					PrintTetris(tetris);
					while(1)   //循环等待,再次按下空格键 
					{
						if(kbhit())
						{
							ch=getch();
							if(ch == 32)
							{
								goto label;   // 
							}
						}
					}
				}
				if(ch == 27)    //   ESC键 ----返回 欢迎界面 
				{
					system("cls");
					memset(a,0,6400*sizeof(int));
					welcom();
				}
				if(ifMove(tetris)==0)  //如果不可以动 ----上面的操作无效 
				{
					tetris->x=Temp1;
					tetris->flag=Temp2;
				}
				else         //如果可移动,返回label 
				{
					goto label;
				}
			}
			tetris->y++;    //没有操作,方块向下移动,每次一行 
			
			if(ifMove(tetris)==0)   //向下移动,又判断不能移动,方块放在此处 
			{
				tetris->y--;
				PrintTetris(tetris);
				Del_Fullline(tetris);
				break;
			}
		}
		
	//--game over: blocks get the top of frame
		for (i=tetris->y-2;i<tetris->y+2;i++) //方块接触到框顶位置 
		{
			if(i==FrameY)
			{
				system("cls");
				gotoxy(29,7);
				printf("  n");
				color(15);
				printf("ttt■■■■     ■    ■     ■■          n");
				printf("ttt■           ■■  ■     ■   ■       n");
				printf("ttt■■■       ■ ■ ■     ■     ■     n");
				printf("ttt■■■       ■ ■ ■     ■     ■     n");
				printf("ttt■           ■  ■■     ■   ■       n");
				printf("ttt■■■■     ■    ■     ■■          n");
			
				
				
				
				
				
				
				gotoxy(29,18);
				color(6);
				printf("再玩一局--------1");
				gotoxy(29,19);
				printf("不玩了--------2");
				gotoxy(29,20);
				printf("choose[1/2]");
				color(15);
				scanf("%d",&n);
				switch(n)
				{
					case 1:
						system("cls");
						Replay(tetris);
						break;
					case 2:
						system("cls");
						gotoxy(29,7);
						printf("您的得分是: %d",tetris->score);
						if(tetris->score >= HighScore)
						{
							color(6);
							gotoxy(29,8);
							printf("创记录啦!最高记录被你刷新啦~");
							HighScore=tetris->score;
							File_in(); 	
						}else{
							color(6);
							gotoxy(29,8);
							printf("继续努力吧~ 你离最高分还差:%d",HighScore-tetris->score);
						}
						exit(0);
						break;
				}
			 
			}
		}
		tetris->flag = tetris->next;  //清除右边窗口方块的图形 
		tetris->x=FrameX+2*Frame_width+6;
		tetris->y=FrameY+10;
		CleanTetris(tetris);
	}
	
}
/*
 *重新开始游戏
 */
 void Replay(struct Tetris *tetris)
 {
 	system("cls");
 	memset(a,0,6400*sizeof(int));
 	DrawGameframe();
 	Gameplay();
  } 
  
  
/*
 *按键说明
 */
   void explation(){
   	int i,j=1;
   	system("cls");
   	color(15);
   	gotoxy(32,3);
   	printf("按键说明");
	color(8);
	for(i=6;i<=16;i++)
	{
		for(j=15;j<=60;j++)
		{
			gotoxy(j,i);
			if(i==6||i==16) printf("=");
			else if(j==15||j==59) printf("||");
		}
	}
	color(6);
	gotoxy(18,7);
	printf("tip1:玩家可以通过←→方向键来移动方块");
	color(2);
	gotoxy(18,9);
	printf("tip2:通过↑使方块旋转");
	color(3);
	gotoxy(18,11);
	printf("tip3:通过↓加速方块下落");
	color(7);
	gotoxy(18,13);
	printf("tip4:按空格键暂停游戏,再按空格键继续游戏");
	color(11);
	gotoxy(18,15);
	printf("tip5:按 Esc退出游戏");
	getch();
	system("cls");
	main(); 
   } 
   
/*
 *游戏规则
 */
void regulation()
 {
 	int i,j=1;
 	system("cls");
 	color(15);
 	gotoxy(56,3);
 	printf("游戏规则");
	color(8);
	for(i=6;i<=18;i++)
	{
		for(j=30;j <=88;j++ )
		{		
		 	gotoxy(j,i);
		 	if(i==6||i==18) printf("=");
		 	else if(j==30||j==87)  printf("||");
		}
	}
	color(7);
	gotoxy(34,7);
	printf("tip1:不同形状的小方块从屏幕上方落下,玩家通过调整");
	gotoxy(42,9);
	printf("方块的位置和方向,使它们在屏幕底部拼出完整的"); 
	gotoxy(42,11);
	printf("一行或几行");
	color(6);
	gotoxy(34,13);
	printf("tip2:每消除一行,积分增加100");
	color(2);
	gotoxy(34,15);
	printf("tip3:每累计1000分,会提升一个等级");
	color(3);
	gotoxy(34,17);
	printf("tip4:提升等级会使方块下落速度加快,游戏难度加大");
	getch();
	system("cls");
	welcom(); 
	
  } 
  
  /*
   *退出游戏
   */
   void close()
   {
   	exit (0);
	} 
 

 

 

 运行界面展示: