自己写了3天的俄罗斯方块,纯原创!

#include <stdio.h>
#include <time.h>
#include <conio.h>

int  f,g,h,i,j,k,l,m,n,o=3,p,q=0,(*x)[3],
	 a[20][10]={0},map[20][10]={0},
	 TEMP[3][3]={0},temp[3][3]={0},
	 T[3][3]={0,1,0,1,1,1,0,0,0},
	 J[3][3]={0,1,0,0,1,0,1,1,0},
	 L[3][3]={0,1,0,0,1,0,0,1,1},
	 S[3][3]={0,1,1,1,1,0,0,0,0},
	 Z[3][3]={1,1,0,0,1,1,0,0,0};

char c[22][41]={'\0'},e=127,d[9],
	 b[22][41]={ "┏━━━━━━━━━━┓┏━━━━━━┓",
				 "┃          ┃┃      ┃",
				 "┃          ┃┃ 下一图形 ┃",
				 "┃          ┃┃      ┃",
				 "┃          ┃┃      ┃",
				 "┃          ┃┃      ┃",
				 "┃          ┃┃      ┃",
				 "┃          ┃┃      ┃",
				 "┃          ┃┃          ┃",
				 "┃          ┃┃ 消除层数 ┃",
				 "┃          ┃┃      ┃",
				 "┃          ┃┃            ┃",
				 "┃          ┃┃          ┃",
				 "┃          ┃┃ A:左方向 ┃",
				 "┃          ┃┃ S:下方向 ┃",
				 "┃          ┃┃  D:右方向  ┃",
				 "┃          ┃┃ 空格: 旋转 ┃",
				 "┃          ┃┃            ┃",
				 "┃          ┃┃ pjw @ MAKE ┃",
				 "┃          ┃┃ copy right ┃",
				 "┃          ┃┃ 2014-01-12 ┃",
				 "┗━━━━━━━━━━┛┗━━━━━━┛"};
	 
void add()//增加图案到数据区
{
	for(i=0;i<20;i++) for(j=0;j<10;j++) map[i][j]=0;//清空数据区
	if(k<5)
	{
		x = k==0 ? T : k==1 ? J : k==2 ? L : k==3 ? S : k==4 ? Z : NULL;//判断随机获取的图案0~4
		for(i=0;i<3;i++) for(j=0;j<3;j++) TEMP[i][j]=x[i][j];
		for(g=f;g;g--) 
		{
			for(i=0,p=2;i<3;i++,p--) for(j=0;j<3;j++) temp[j][p]=TEMP[i][j];
			for(i=0;i<3;i++) for(j=0;j<3;j++) TEMP[i][j]=temp[i][j];
		}
		for(i=0;i<3;i++) for(j=0;j<3;j++) if(TEMP[i][j]==1) map[i+h][j+l]=1;
	}
	else if(k==5)//增加图案5到数据区
	{
		if(f==0||f==2) for(i=0,j=0;j<4;j++) map[i+h][j+l]=1;
		else for(i=0,j=0;i<4;i++) map[i+h-1][j+l+1]=1;
	}
	else for(i=0;i<2;i++) for(j=0;j<2;j++) map[i+h][j+l]=1;//增加图案6到数据区
}

void add1()//增加图案到下一方块区
{
	if(o<0) return;
	if(o<5)
	{
		x = o==0 ? T : o==1 ? J : o==2 ? L : o==3 ? S : o==4 ? Z : NULL;
		for(i=0;i<3;i++) for(j=0;j<3;j++) if(x[i][j]==1) c[i+5][j*2+28]=0xa1,c[i+5][j*2+28+1]=0xf6;
	}
	else if(o==5)
	{
		for(i=0,j=0;j<4;j++) c[i+5][j*2+28]=0xa1,c[i+5][j*2+28+1]=0xf6;
	}
	else for(i=0;i<2;i++) for(j=0;j<2;j++) c[i+5][j*2+28]=0xa1,c[i+5][j*2+28+1]=0xf6;
	itoa(q,d,10); for(i=0;d[i]!='\0';i++) c[11][i+28]=d[i];

}

void echo()//打印数据区图案
{
	printf(" X=%d Y=%d 图案=%d 旋转=%d\n",h,l,k,f);
	for(i=0;i<22;i++) for(j=0;j<41;j++) c[i][j]=b[i][j];//清空背景图案
	add1();
	for(i=0;i<20;i++) for(j=0;j<10;j++)
		{		
			if(map[i][j]==1) c[i+1][2+j*2] = 0xa1,c[i+1][2+j*2+1] =0xf6;//把数据矩阵转化为背景'■'
			if(a[i][j]==1) c[i+1][2+j*2] = 0xa1,c[i+1][2+j*2+1] =0xf6;
		}
	for(i=0;i<22;i++) puts(c[i]);
}

int ai()//新建图形取随机值
{
	f=0,h=0,l=3;
	return rand()%7;
}

void adda()//加入完成数据区
{
	for(i=0;i<20;i++) for(j=0;j<10;j++) if(map[i][j]==1) a[i][j]=map[i][j];//将临时map加入完成a
}

int check(char x)//map数据与a数据冲突对比检测
{
	if(x=='r')//左右测试
	{
		l++; add();
		for(i=0;i<20;i++) for(j=0;j<10;j++) if(map[i][j]==1&&a[i][j]==1)
		{
			l--; add();	return 1;//对比测试,如果有冲突返回真。
		}
		l--; add();
	}

	if(x=='l'&&map[0][0]!=1)
	{
		l--; add();
		for(i=0;i<20;i++) for(j=0;j<10;j++) if(map[i][j]==1&&a[i][j]==1)
		{
			l++; add();	return 1;
		}
		l++; add();
	}

	if(x=='h')//下降测试
	{
		h++; add();
		for(i=0;i<20;i++) for(j=0;j<10;j++) if(map[i][j]==1&&a[i][j]==1)
		{
			h--; add();	return 1;
		}
		h--; add();
	}

	if(x=='s')//旋转测试
	{
		f==3 ? f=0 : f++; add();
		for(i=0;i<20;i++) for(j=0;j<10;j++) if(map[i][j]==1&&a[i][j]==1)
		{
			f==0 ? f=3 : f--; add(); return 1;
		}
		f==0 ? f=3 : f--; add();
	}

	return 0;//没有冲突返回假
}

void del()//完成消除检测
{
	for(i=0;i<20;i++) for(j=0,g=0;j<10;j++) if(a[i][j]==1) 
		if(++g==10) {q++;for(m=i;m;m--) for(n=0;n<10;n++) a[m][n]=a[m-1][n];}
}

void move(int y)//移动偏离值及移动碰撞检测
{
	if(y==1||y==-1)//左右检测
	{
		if(y==1&&check('r')) return;
		if(y==-1&&check('l')) return;
		for(i=0;i<20;i++)
		{
			if(y==1&&map[i][9]==1) return;//右边界检测
			if(y==-1&&map[i][0]==1) return;//左边界检测		
		}
	}

	if(y==0)//下降检测
	{
		if(check('h'))
		{
			adda(); k=o; o=ai() ; return;
		}
		else h++;
		for(i=0;i<10;i++) if(map[19][i]==1)//下边界检测
		{
			adda();	k=o; o=ai();
			return;
		}
	}
	y==1 ? l++ : y==-1 ? l-- : y; add();   
}

void space()//旋转偏离及旋转碰撞检测
{
	if(check('s'))return;
	if(l==-1&&k==0&&f==1)l++; if(l==8&&k==0&&f==3)l--;
	if(l==-1&&k==1&&f==2)l++; if(l==8&&k==1&&f==0)l--;	
	if(l==-1&&k==2&&f==0)l++; if(l==8&&k==2&&f==2)l--;
	if(l==-1&&k==3&&f==1)l++; if(l==8&&k==3&&f==3)l--;
	if(l==-1&&k==4&&f==1)l++; if(l==8&&k==4&&f==3)l--;
	if(h==0&&k==5&&(f==0||f==2))h++;
	if(l==-1&&k==5&&(f==1||f==3))l++;
	if(l==7&&k==5&&(f==1||f==3))l--;
	if(l==8&&k==5&&(f==1||f==3))l-=2;
	f==3 ? f=0 : f++; add();//旋转偏离值
}

int main()
{
	srand(time(NULL)); k=ai();
	do
	{
		system("cls"); e!=127 ? e=='a'||e=='A' ? move(-1) : e=='d'||e=='D' ? move(1) :
		e=='s'|| e=='S' ? move(0) : e==' ' ? space() : e : add(); del(); add(); echo();
	}
	while(e=getch());

	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值