编辑代码

#include <stdio.h> 
#include <stdlib.h> 
#include<time.h>
#include <fcntl.h> 
#define TTY_PATH  "/dev/tty"
#define STTY_US  "stty raw -echo -F "
#define STTY_DEF  "stty -raw echo -F "
#define WIDTH 12
#define HEIGHT 22
struct Point{
	int x;
	int y;
};
//struct Point shape1[4]={{0,0},{0,-1},{0.-2},{1,0}};
//struct Point shape2[4]={{0,0},{0,1},{1,0},{2,0}};
struct Point shapes[19][4]={
	{{0,0},{-1,0},{1,0},{2,0}},//横条	
    {{0,0},{0,-1},{0,1},{0,2}},//竖条	
    {{0,0},{-1,-1},{-1,0},{0,-1}},//方块	
    {{0,0},{0,-1},{0,-2},{1,0}},//正L1	
    {{0,0},{0,1},{1,0},{2,0}},//正L2
    {{0,0},{-1,0},{0,1},{0,2}},//正L3	
    {{0,0},{0,-1},{-1,0},{-2,0}},//正L4	
    {{0,0},{-1,0},{0,-1},{0,-2}},//反L1	
    {{0,0},{0,-1},{1,0},{2,0}},//反L2	
    {{0,0},{1,0},{0,1},{0,2}},//反L3	
    {{0,0},{-1,0},{-2,0},{0,1}},//反L4	
    {{0,0},{-1,0},{1,0},{0,-1}},//T1	
    {{0,0},{0,1},{0,-1},{1,0}},//T2	
    {{0,0},{-1,0},{1,0},{0,1}},//T3	
    {{0,0},{-1,0},{0,-1},{0,1}},//T4	
    {{0,0},{1,0},{0,-1},{-1,-1}},//正Z1	
    {{0,0},{1,-1},{0,1},{1,0}},//正Z2	
    {{0,0},{1,-1},{-1,0},{0,-1}},//反Z1	
    {{0,0},{-1,-1},{-1,0},{0,1}}//反Z2
};
int shapeIndex=0;
int x=0,y=0;
int screen[HEIGHT][WIDTH]={0};
void change();
void drowPoint();
void fallDown();
void addToStaticScreen();
void createShape();
void clearLines();
void moveLines();
void initScreen(){
	int i;
	for(i=0;i<WIDTH;i++){
		screen[0][i]=2;
		screen[HEIGHT-1][i]=2;
	}
	int j;
	for(j=0;j<HEIGHT;j++){
		screen[j][0]=2;
		screen[j][WIDTH-1]=2;
	}
}
void userCtrl(){
	char c=getChar();
	switch(c){
		case 'a':
			if(leftMove())
				x--;
			break;
		case 'd':
			if(rightMove())
				x++;
			break;
		case 's':
			fallDown();
			break;
		case 'w':
			change();
			break;
		case 3:
			system(STTY_DEF TTY_PATH);
			exit(0);
			break;
	}
}
void fallDown(){
	if(downMove()){
		y++;
	}else{
		addToStaticScreen();
		clearLines();
		createShape();
	}
}
void clearLines(){
	int count=0;
	int i;
	for(i=HEIGHT-2;i>0;i--){
		if(isFull(i)){
			count++;
		}else if(count>0){
			moveLines(i,i+count);
		}
	}
}
int isFull(int line){
	int i;
	for(i=0;i<WIDTH-1;i++){
		if(screen[line][i]==0){
			return 0;
		}
	}
	return 1;
}
void moveLines(int src,int desc){
	int i;
	for(i=1;i<WIDTH-1;i++){
		screen[desc][i]=screen[src][i];
		screen[src][i]=0;
	}
}
void addToStaticScreen(){
	int i;
	for(i=0;i<4;i++){
		int pointX=shapes[shapeIndex][i].x+x;
		int pointY=shapes[shapeIndex][i].y+y;
		screen[pointY][pointX]=1;
	}
}
int leftMove(){
	int px=x-1;
	int py=y;
	int i;
	for(i=0;i<4;i++){
		int pointX=shapes[shapeIndex][i].x+px;
		int pointY=shapes[shapeIndex][i].y+py;
		if(screen[pointY][pointX]!=0){
			return 0;
		}
	}
	return 1;
}
int rightMove(){
	int px=x+1;
	int py=y;
	int i;
	for(i=0;i<4;i++){
		int pointX=shapes[shapeIndex][i].x+px;
		int pointY=shapes[shapeIndex][i].y+py;
		if(screen[pointY][pointX]!=0){
			return 0;
		}
	}
	return 1;
}
int downMove(){
	int px=x;
	int py=y+1;
	int i;
	for(i=0;i<4;i++){
		int pointX=shapes[shapeIndex][i].x+px;
		int pointY=shapes[shapeIndex][i].y+py;
		if(screen[pointY][pointX]!=0){
			return 0;
		}
	}
	return 1;
}
void change(){
	int peIndex=shapeIndex;
	switch(peIndex){
		case 1:
			peIndex=0;
			break;
		case 2:
			break;
		case 6:
			peIndex=3;
			break;
		case 10:
			peIndex=7;
			break;
		case 14:
			peIndex=11;
			break;
		case 16:
			peIndex=15;
			break;
		case 18:
			peIndex=17;
			break;
		default:
			peIndex++;
			break;
	}
	if(changeMove(peIndex)){
		shapeIndex=peIndex;
	}
}
int changeMove(int peIndex){
	int i;
	for(i=0;i<4;i++){
		int pointX=shapes[peIndex][i].x+x;
		int pointY=shapes[peIndex][i].y+y;
		if(screen[pointY][pointX]!=0){
			return 0;
		}
	}
	return 1;
}
void draw(){
	int i,j;
	for(i=0;i<4;i++){
		drowPoint(shapes[shapeIndex][i].x+x,shapes[shapeIndex][i].y+y);
	}
	for(i=0;i<HEIGHT;i++){
		for(j=0;j<WIDTH;j++){
			if(screen[i][j]!=0){
				drowPoint(j,i);
			}
		}
	}
	fflush(stdout);
}
void createShape(){
	x=WIDTH/2;
	y=2;
	shapeIndex=rand()%19;
}
int getChar()	
{
  fd_set rfds;
  struct timeval tv;
  int ch = 0;
  FD_ZERO(&rfds);
  FD_SET(0, &rfds);
  tv.tv_sec = 0;
  tv.tv_usec = 10; 
  if (select(1, &rfds, NULL, NULL, &tv) > 0)
  {
      ch = getchar(); 
  }
  return ch;
}

void drowPoint(int x, int y)
{
	printf("\033[%d;%dH", y+1, x*2+1);
	if(x==0||x==WIDTH-1||y==0||y==HEIGHT-1){
		printf("\033[0;31m◆\033[0m ");
	}else{
		printf("\033[1;36m■ \033[0m");
	}
//	printf("\033[?25l");
}
int main(){
	srand(time(0));
	system(STTY_US TTY_PATH);
	createShape();
	initScreen();
	printf("\033[?25l");
	int count=0;
	while(1){
		system("clear");
		draw();
		userCtrl();
		if(++count==10){
			fallDown();
			count=0;
		}
		usleep(50*1000);
	}
	return 0;
}