俄罗斯方块

54 篇文章 0 订阅
34 篇文章 1 订阅
#include<iostream>
#include<stdlib.h>
#include<windows.h>
#include<time.h>
#include<conio.h>
using namespace std;

#define A1 0//A代表长条型,B为方块,C为L型,D为闪电型(实在无法描述那个形状)
#define A2 1

#define B 2

#define C11 3
#define C12 4
#define C13 5
#define C14 6

#define C21 7
#define C22 8
#define C23 9
#define C24 10

#define D11 11
#define D12 12

#define D21 13
#define D22 14

void SetPos(int i,int j)//设定光标位置
{
	COORD pos={i,j};
	HANDLE Out=GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleCursorPosition(Out, pos);
}

int sharp[15][8]=
{
	{0,0,1,0,2,0,3,0},{0,0,0,1,0,2,0,3},
	{0,0,1,0,0,1,1,1},
	{0,0,1,0,1,1,1,2},{0,1,1,1,2,0,2,1},{0,0,0,1,0,2,1,2},{0,0,0,1,1,0,2,0},
	{1,0,1,1,1,2,0,2},{0,0,0,1,1,1,2,1},{0,0,0,1,0,2,1,0},{0,0,1,0,2,0,2,1},
	{0,0,0,1,1,1,1,2},{0,1,1,0,1,1,2,0},
	{0,1,0,2,1,0,1,1},{0,0,1,0,1,1,2,1}
};//这个2维数组是用来保存各个形状位置的

int high[15]={4,1,2,2,3,2,3,2,3,2,3,2,3,2,3};//这个数组是用来保存各个形状高度的

class Box//俄罗斯方块类
{
    private:
	   int map[23][12];//画面坐标
	   int hotpoint[2];//热点(即当前活动的点,所有图形都是相当此点绘制的)
	   int top;//当前最高位置
	   int point;//分数
	   int level;//等级
	   int ID;//当前活动图形的ID号
   public:
	   Box()//初始化
	   {
		   int i,j;
		   for(i=0;i<23;i++)
			   for(j=0;j<12;j++)
				   map[i][j]=0;
		   hotpoint[0]=0;
		   hotpoint[1]=5;
		   point=0;
		   level=1;
		   top=99;
		   ID=0;
	   }
	   void DrawMap();//画界面
	   int Judge(int x,int y);//判断当前位置能否绘制图形
	   void Welcome();//欢迎界面
	   void DrawBox(int x,int y,int num);//绘制图形
	   void Redraw(int x,int y,int num);//擦除图形
	   void Run();//运行
	   void Turn();//转动方块
	   void UpdataMap();//更新画面
};

void Box::DrawMap()//画界面
{
	int i;

	for(i=0;i<14;i++)
	{
		 SetPos(i*2,0);
		 cout<<"■";
	}
	for(i=1;i<=24;i++)
	{
		SetPos(0,i);
		cout<<"■";
		SetPos(13*2,i);
		cout<<"■";
	}
	for(i=0;i<14;i++)
	{
		 SetPos(i*2,24);
		 cout<<"■";
	}
	
	i=15;
	for(i=15;i<=25;i++)
	{
		 SetPos(i*2,0);
		 cout<<"■";
	}
	for(i=1;i<=8;i++)
	{
		SetPos(15*2,i);
		cout<<"■";
		SetPos(25*2,i);
		cout<<"■";
	}
	for(i=15;i<=25;i++)
	{
		 SetPos(i*2,9);
		 cout<<"■";
	}

	SetPos(16*2,16);
	cout<<"俄罗斯方块";
	SetPos(16*2,17);
	cout<<"分数:"<<point;
	SetPos(16*2,18);
	cout<<"等级:"<<level;
}

void Box::DrawBox(int x,int y,int num)//绘制图形
{
	 int i;
	 int nx,ny;
	 for(i=0;i<4;i++)
	{ 
		nx=x+sharp[num][i*2];
		ny=y+sharp[num][i*2+1];
		SetPos((ny+1)*2,nx+1);//利用sharp数组相对于点x,y绘制形状
		cout<<"■";
	}
}

void Box::Redraw(int x,int y,int num)//擦除图形,原理同上
{
	 int i;
	 int nx,ny;
	 for(i=0;i<4;i++)
	{ 
		nx=x+sharp[num][i*2];
		ny=y+sharp[num][i*2+1];
		SetPos((ny+1)*2,nx+1);
		cout<<" ";
	}
}

void Box::Turn()//转动图形,单纯的该ID而已
{
	switch(ID)
	{
	   case A1: ID=A2; break;
	   case A2: ID=A1; break;

	    case B: ID=B; break;

		case C11: ID=C12; break;
		case C12: ID=C13; break;
		case C13: ID=C14; break;
		case C14: ID=C11; break;

		case C21: ID=C22; break;
		case C22: ID=C23; break;
		case C23: ID=C24; break;
		case C24: ID=C21; break;
		
		case D11: ID=D12; break;
		case D12: ID=D11; break;

		case D21: ID=D22; break;
		case D22: ID=D21; break;
	}

}

void Box::Welcome()//欢迎界面
{
	char x;
	while(1)
	{
	  system("cls");
	  cout<<"■■■■■■■■■■■■■■■■■■■"<<endl;
	  cout<<"■    俄罗斯方块控制台版(不闪屏)  ■"<<endl;
	  cout<<"■■■■■■■■■■■■■■■■■■■"<<endl;
	  cout<<"■     A,D左右移动  S向下加速       ■"<<endl;
	  cout<<"■        空格键转动方块            ■"<<endl;
	  cout<<"■■■■■■■■■■■■■■■■■■■"<<endl;
	  cout<<"■           陕西科技大学           ■"<<endl;
	  cout<<"■             1B433                ■"<<endl;
	  cout<<"■                                  ■"<<endl;
	  cout<<"■        按1-9选择等级!!         ■"<<endl;
	  cout<<"■                                  ■"<<endl;
	  cout<<"■                                  ■"<<endl;
	  cout<<"■■■■■■■■■■■■■■■■■■■"<<endl;
	  SetPos(8,10);
	  x=getch();
	  if(x<='9'&&x>='1')//设置等级
	  {
		  level=x-'0';
		  break;
	  }
	}
}

void Box::UpdataMap()//更新画面(关键)
{
	 int clear;
	 int i,j,k;
	 int nx,ny;
	 int flag;
	 for(i=0;i<4;i++)//更新map数组的信息
	{ 
		nx=hotpoint[0]+sharp[ID][i*2];
		ny=hotpoint[1]+sharp[ID][i*2+1];
		map[nx][ny]=1;
	}
	 if(hotpoint[0]<top)//如果热点高于顶点则更新顶点
		 top=hotpoint[0];
	 clear=0;//消除的格数
	 for(i=hotpoint[0];i<hotpoint[0]+high[ID];i++)
	 {
		 flag=0;
		 for(j=0;j<12;j++)//检测是否可以消除此行
		 {
			 if(map[i][j]==0)
			 {
				 flag=1;
				 break;
			 }
		 }
		 if(flag==0)//可以消除
		 {
			 for(k=i;k>=top;k--)//从当前位置向上所有的点下移一行
			 {
				 if(k==0)//最高点特殊处理
					 for(j=0;j<12;j++)
					 {
						 map[k][j]=0;
						 SetPos((j+1)*2,k+1);
						 cout<<" ";
					 }
				 else
				 {
					 for(j=0;j<12;j++)
					 {
						 map[k][j]=map[k-1][j];
						 SetPos((j+1)*2,k+1);
		                 if(map[k][j]==0)
						    cout<<" ";
						 else
							cout<<"■";
					 }
				 }

			 }
			 top++;//消除成功,最高点下移
			 clear++;
			 point+=clear*100;
		 }
	 }
       
	 SetPos(16*2,17);
	    cout<<"分数:"<<point;
}

void Box::Run()//运行游戏
{
	int i=0;
	char x;
	int Count;//计数器
	int tempID;
	int temp;
	srand((int)time(0));
	ID=rand()%15;//随机生成ID和下一个ID
	tempID=rand()%15;
	DrawBox(hotpoint[0],hotpoint[1],ID);//绘制图形
	DrawBox(3,17,tempID);
	Count=1000-level*100;//等级决定计数
	while(1)
	{
		if(i>=Count)//时间到
		{
			i=0;//计数器清零
			if(Judge(hotpoint[0]+1,hotpoint[1]))//如果下个位置无效(即到底)
			{
				 UpdataMap();//更新画面
				 ID=tempID;//生成新ID,用原等待ID替换为当前ID
				 hotpoint[0]=0;//热点更新
				 hotpoint[1]=5;
                 Redraw(3,17,tempID);
				 tempID=rand()%15;
	             DrawBox(hotpoint[0],hotpoint[1],ID);
	             DrawBox(3,17,tempID);
				 if(Judge(hotpoint[0],hotpoint[1]))//无法绘制开始图形,游戏结束
				 {
					 system("cls");
					 SetPos(25,15);
					 cout<<"游戏结束!!!最终得分为:"<<point<<endl;
					 system("pause");
					 exit(0);
				 }

            }
			else
			{
				Redraw(hotpoint[0],hotpoint[1],ID);//没有到底,方块下移一位
			    hotpoint[0]++;//热点下移
				DrawBox(hotpoint[0],hotpoint[1],ID);
			}

		}
		if(kbhit())//读取键盘信息
		{
			x=getch();
			if(x=='a'||x=='A')//左移
			{
				 if(Judge(hotpoint[0],hotpoint[1]-1)==0)
				 {
					 Redraw(hotpoint[0],hotpoint[1],ID);
					 hotpoint[1]-=1;
				     DrawBox(hotpoint[0],hotpoint[1],ID);
				 }
			}
			if(x=='d'||x=='D')//右移
			{
			     if(Judge(hotpoint[0],hotpoint[1]+1)==0)
				 {
					 Redraw(hotpoint[0],hotpoint[1],ID);
					 hotpoint[1]+=1;
				     DrawBox(hotpoint[0],hotpoint[1],ID);
				 }
			}
			if(x=='s'||x=='S')//向下加速
			{
			     if(Judge(hotpoint[0]+1,hotpoint[1])==0)
				 {
					 Redraw(hotpoint[0],hotpoint[1],ID);
					 hotpoint[0]+=1;
				     DrawBox(hotpoint[0],hotpoint[1],ID);
				 }
			}
			if(x==' ')//转动方块
			{
				temp=ID;
				Turn();
				if(Judge(hotpoint[0],hotpoint[1])==0)
				 {
					 Redraw(hotpoint[0],hotpoint[1],temp);
				     DrawBox(hotpoint[0],hotpoint[1],ID);
				 }
				else
				    ID=temp;
			}
			while(kbhit())//读掉剩下的键盘信息
				getch();
		}
		Sleep(1);//等待1毫秒
		i++;//计数器加1
    }
}

int Box::Judge(int x,int y)//判断当前是否可以绘制方块
{
	int i;
	int nx,ny;
	for(i=0;i<4;i++)
	{ 
		nx=x+sharp[ID][i*2];
		ny=y+sharp[ID][i*2+1];
		if(nx<0||nx>=23||ny<0||ny>=12||map[nx][ny]==1)//不能,返回1
			return 1;
	}
	return 0;
}

int main()//主函数
{
	Box game;
    game.Welcome();
	system("cls");
	game.DrawMap();
	game.Run();
	system("pause");
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值