c語言俄羅斯方塊

linux實現

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>


#define TTY_PATH "/dev/tty"
#define STTY_ON "stty raw -echo -F"
#define STTY_OFF "stty -raw echo -F"

int map[21][14];
char direct;

int node[7][4][16]={
		{{0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0},//長方形
		 {0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0},
		 {0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0},
		 {0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0}},
		{{1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0},//正方形
		 {1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0},
		 {1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0},
		 {1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0}},
		{{0,1,0,0,1,1,1,0,0,0,0,0,0,0,0,0},//3邊加一中點
		 {0,1,0,0,0,1,1,0,0,1,0,0,0,0,0,0},
		 {0,0,0,0,1,1,1,0,0,1,0,0,0,0,0,0},
		 {0,1,0,0,1,1,0,0,0,1,0,0,0,0,0,0}},
		{{0,1,1,0,0,1,0,0,0,1,0,0,0,0,0,0},//右鋤頭型
		 {0,0,0,0,1,1,1,0,0,0,1,0,0,0,0,0},
		 {0,1,0,0,0,1,0,0,1,1,0,0,0,0,0,0},
		 {1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0}},
		{{1,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0},//左鋤頭型
		 {0,0,1,0,1,1,1,0,0,0,0,0,0,0,0,0},
		 {0,1,0,0,0,1,0,0,0,1,1,0,0,0,0,0},
		 {0,0,0,0,1,1,1,0,1,0,0,0,0,0,0,0}},
		{{0,1,0,0,0,1,1,0,0,0,1,0,0,0,0,0},//右曲折型
		 {0,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0},
		 {0,1,0,0,0,1,1,0,0,0,1,0,0,0,0,0},
		 {0,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0}},
		{{0,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0},//左曲折型
		 {1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0},
		 {0,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0},
		 {1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0}}
		};

typedef struct block
{
	int x;
	int y;
	int blockType;
	int blockDirect;	
}Block;
Block bl;

void init_map()//初始化邊框
{
	int i,j;
	for(i=0; i<21; i++)
		for(j=0; j<14; j++)
		{
			if(j==0 || j==13)
				map[i][j] = 200;
			else if(i==20)
				map[i][j] = 201;
			else	
				map[i][j] = 0;
		}
}
void new_block()//生成隨機的俄羅斯方塊
{
	int blockType = rand()%7;
	int blockDirect = rand()%4;
	int x = 1;
	int y = 5;
	bl.x = x;
	bl.y = y;
	bl.blockType = blockType;
	bl.blockDirect = blockDirect;
}

void input()//將移動後的俄羅斯方塊,導入地圖中作標記
{
	int i, j;
	for(i=0; i<4; i++)
		for(j=0; j<4; j++)
			if(node[bl.blockType][bl.blockDirect][i*4+j]==1)
			{
				map[bl.x+i][bl.y+j] = 1;
			}
}
void output()//移動時,將之前俄羅斯方塊在地圖信息清空。
{
	int i, j;
	for(i=0; i<4; i++)
		for(j=0; j<4; j++)
			if(node[bl.blockType][bl.blockDirect][i*4+j]==1)
			{
				map[bl.x+i][bl.y+j] = 0;
			}
}

void change()//俄羅斯方格在碰撞後融入,固定
{
	int i, j;
	for(i=0; i<4; i++)
		for(j=0; j<4; j++)
			if(node[bl.blockType][bl.blockDirect][i*4+j]==1)
			{
				map[bl.x+i][bl.y+j] = 10;
			}
	for(j=1; j<13; j++)
		if(map[5][j] == 10)
		{	
			system("clear");
			printf("game over !!!!!!!!!\n");
			exit(1);
		}
}
	

void print_map()//打印地圖,顯示信息
{
	int i,j;
	for(i=5; i<21; i++)
	{
		for(j=0; j<14; j++)
		{
			if(map[i][j]==200)//左右邊界
				printf("#");
			else if(map[i][j]==201)//下邊界
				printf(" # ");
			else if(map[i][j]==0)//空白地
				printf("   ");
			else if(map[i][j]==1)//移動的俄羅斯方塊
				printf(" * ");
			else if(map[i][j]==10)//固定的俄羅斯方塊
				printf(" @ ");
		}
		printf("\n");
	}
}
void delLine(int n)//消行
{
	int i,j;
	for(j = 1; j<13; j++)
		map[n][j] = 0;
	for(i = n; i>5 ; i--)
		for(j = 1; j<13; j++)
		if(map[i-1][j] != 1)
		map[i][j] = map[i-1][j];
}

void isFillLine()//是否滿足消行條件
{
	
	int i,j;
	int fals;
	for(i=19; i>5; i--)
	{
		fals = 1;
		for(j=1; j<13; j++)
		{
			if(map[i][j] != 10)
			{
				fals = 0;		
				continue;
			}
		}
		if(fals)
		{
			delLine(i);
		}
	}
}
void down()//下移
{
	int i, j;
	int fale = 1;
	for(i=3; i>=0; i--)
		for(j=0; j<4; j++)
			if(node[bl.blockType][bl.blockDirect][i*4+j] == 1)
				if(map[bl.x+i+1][bl.y+j] == 10 || map[bl.x+i+1][bl.y+j] == 201)
				{
					change();
					fale = 0;
					new_block();
					isFillLine();			
					return;
				}	
	if(fale)
	{
		output();
		bl.x += 1;
		input();
	}
				
}
void right()//右移
{
	int i, j;
	int fale = 1;
	for(i=3; i>=0; i--)
		for(j=0; j<4; j++)
			if(node[bl.blockType][bl.blockDirect][i*4+j] == 1)
				if(map[bl.x+i][bl.y+j+1] == 10 || map[bl.x+i][bl.y+j+1] == 200)
				{
					fale = 0;
					return;
				}	
	if(fale)
	{
		output();
		bl.y += 1;
		input();
	}
	
}
void left()//左移
{
	int i, j;
	int fale = 1;
	for(i=3; i>=0; i--)
		for(j=0; j<4; j++)
			if(node[bl.blockType][bl.blockDirect][i*4+j] == 1)
				if(map[bl.x+i][bl.y+j-1] == 10 || map[bl.x+i][bl.y+j-1] == 200)
				{
					fale = 0;
					return;
				}	
	if(fale)
	{
		output();
		bl.y -= 1;
		input();
	}
	
}

void change_block()//俄羅斯方塊變形
{
	int i,j;
	output();
	int fals = 1;
	bl.blockDirect += 1;
	bl.blockDirect %= 4;
	for(i=0; i<4; i++)
		for(j=0; j<4; j++)
		if(node[bl.blockType][bl.blockDirect][i*4+j]==1)
			if(map[bl.x+i][bl.y+j] != 0 )
			{
				fals = 0;
				break;
			}
	if(fals)
	{
		input();
	}else
	{
		bl.blockDirect -= 1;
		input();
	}
}

char in_direct()//非堵塞輸入
{
    fd_set fd; 
	struct timeval tv; 
	char ch; 
	FD_ZERO(&fd);
	FD_SET(0, &fd);
	tv.tv_sec = 0;
	tv.tv_usec = 10; 
	if(select(1, &fd ,NULL, NULL, &tv) > 0)
	{   
	       ch = getchar(); 
	}   
	return ch; 
}
int main()//q 退出遊戲,a,d 左右移動,空格變形
{
	srand(time(NULL));
	init_map();	
	new_block();
	input();
	char ch;
	int num = 0;
	while(1)
	{
		usleep(500000);
		system(STTY_ON TTY_PATH);
		ch = in_direct();
		system(STTY_OFF TTY_PATH);
		system("clear");	
		if(ch == 'a' && num <= 1)
		{
			left();
			print_map();
			num++;
			continue;
		}else if(ch == 'd' && num <= 1)
		{
			right();
			print_map();
			num++;
			continue;
		}else if(ch == ' ' && num <= 1 )
		{
			change_block();
			print_map();
			num++;
			continue;
		}else if(ch == 'q')
		{
			system("clear");
			printf("gave over!!!!!\n");
			exit(0);
		}
		down();
		print_map();
		num = 0;

	}
	return 0;
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章