继上篇,俄罗斯方块代码

              另附,EASYX库百度一下就好了。

             

// EasyXText.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <graphics.h>
#include <conio.h>
#include <iostream>
#include <time.h>
#include <stdlib.h>
#include <math.h>
#include <wchar.h>

using namespace std;
//  不能出现魔鬼数字,把魔鬼数字全部宏定义!
#define brickLenth 10
#define wallLenth 5
const unsigned int brick[9][4]={{36352,51328,57856,17600},
{61440,34952,0,0},
{19968,17984,58368,19520},
{32768,1,1,1},
{52224,1,1,1},
{11776,35008,59392,50240},
{35840,51200,50176,19456},
{50688,19584,0,0},
{27648,35904,0,0}};   // 所有方块
const int brickColor[9]={0xAA0000,0x00AA00,0xAAAA00,0x0000AA,0xAA00AA,0x0055AA,0xFF5555,0x55FF55,0x55FFFF};
int isGridempty[48][32]; // 记录当前点是否有方块,并记录颜色
struct nowbrick
{
	int color;   //  方块颜色
	int coordinate[4][4];  //  每个正方形的坐标
	int lenth;   // 当前方块的正方形个数
	int which;   //  当前方块的状态
	int brick;  //  当前是哪种方块在运行
}now;
enum order
{
	Rotate,Left,Right,Down,
	Quit,
	Restart,
	Drop,
	Pause
};
void initUI()
{
	initgraph(640,480);
	setorigin(320,240);
	memset(isGridempty,0,sizeof(isGridempty));
	setlinecolor(0xFFFFFF);
	line(0,240,0,-240);
	int x=-320,y=-315,a=-240,b=-235,c=240,d=235;
	setlinecolor(0x555555);
	setfillcolor(0x555555);
	for(int i=0;i<64;i++)
	{
		fillrectangle(x,a,y,b);
		fillrectangle(x,d,y,c);
		x+=wallLenth;
		y+=wallLenth;
	}
	x=-235,y=-230,a=-320,b=-315,c=-5,d=0;
	for(int j=0;j<94;j++)
	{
		fillrectangle(a,x,b,y);
		fillrectangle(c,x,d,y);
		x+=wallLenth;
		y+=wallLenth;
	}
	// 下面还要完成右侧说明区域
    settextstyle(20,0,_T("宋体"));
	outtextxy(100,-235,_T("操作说明"));
	outtextxy(100,-200,_T("上(w):旋转"));
	outtextxy(100,-165,_T("左(a):左移"));
	outtextxy(100,-130,_T("右(d):右移"));
	outtextxy(100,-95,_T("下(s):下移"));
	outtextxy(100,-60,_T("空格:暂停"));
	outtextxy(100,-25,_T("z: 退出"));
	outtextxy(100,10,_T("f: 重新开始"));
	outtextxy(100,45,_T("x: 快速下降"));
	setfillcolor(0x555555);
	setlinecolor(0x555555);
	x=60,y=170,a=240,b=5;
	for(int k=0;k<40;k++)
	{
		fillrectangle(x,y-5,x-5,y);
		fillrectangle(x,a-5,x-5,a);
		x+=wallLenth;
	}
	x=55,a=250,y=175,b=5;
	for(int k=0;k<13;k++)
	{
		fillrectangle(x,y-5,x+5,y);
		fillrectangle(a,y-5,a+5,y);
		y+=wallLenth;
	}
	outtextxy(100,195,_T("得分:0"));
}
void randomBrick()
{
	srand(time(NULL));
	int trp = rand()%8+0;  //  随机一个俄罗块方块
	int flag=0;  //  记录正方形的数量
	int x,y;
	unsigned int br = brick[trp][0];
	now.which = 0;
	now.brick = trp;
    now.color = brickColor[trp];
	setfillcolor(now.color);
	for(int i=15;i>=0;i--)
	{
		if(br&1)
		{
			x=i/4+1,y=i%4+1;
			int left=-165+y*brickLenth,top=-235+x*brickLenth,right=-155+y*brickLenth,bottom=-225+x*brickLenth;
			fillrectangle(left,top,right,bottom);
			now.coordinate[flag][0]=left,now.coordinate[flag][1]=top,now.coordinate[flag][2]=right,now.coordinate[flag][3]=bottom;
			flag++;
		}
		
		br >>= 1;
	}
	now.lenth=flag;
}
const int xlborder = -315;
const int xrborder = -5;
const int ybborder = 235;
const int ytborder = -235;
int score=0;
char index[30] = "得分:";
int get_y(int l) // 获得正方形的位置 左位置   列算
{
	return -((31-l)*brickLenth+5);
}
int get_x(int l) // 获得正方形的位置  下位置   行算
{
	return ((l+1)*10)-235;
}
int getY(int l)  //获得正方形的虚拟位置 列
{
	int t=l;
	t = 31 + t/brickLenth;
	if(t>=0 && t<31) return t;
	else return -1;
}
int getX(int l)  // //获得正方形的虚拟位置 行
{
	int t=l;
	t = t>0 ? t/brickLenth+23 : 22-(t/-brickLenth);
	if(t>=0 && t<47) return t;
	else return -1;
}
void onRestart()
{
	int x,y;
	for(int i=0;i<47;i++)
	{
		for(int j=0;j<31;j++)
		{
			if(isGridempty[i][j])
			{
				x=get_x(i);   //  下
				y=get_y(j);   // 左
				clearrectangle(y,x-10,y+10,x);
			}
		}
	}
	for(int k=0;k<now.lenth;k++)
	{
		clearrectangle(now.coordinate[k][0],now.coordinate[k][1],now.coordinate[k][2],now.coordinate[k][3]);
	}
	//  把分数重置一下
	score=0;
	outtextxy(100,195,_T("得分:0"));
	memset(isGridempty,0,sizeof(isGridempty));
	randomBrick();
}
bool ifdeath()
{
	int sum=0;
	for(int i=0;i<4;i++)
	{
		for(int j=15;j<19;j++)
		{
			if(isGridempty[i][j]) sum++;
		}
	}
	if(sum>3)
	{
		//  提示已死亡,请重新开始
		return true;
	}
	else return false;
}
void clearfullRow()
{
	int flag = 0;
	int y,x,color;
	int left = -315;
	for(int i=0;i<47;i++)
	{
		flag=0;
		for(int j=0;j<31;j++)
		{
			if(isGridempty[i][j] == 0) 
			{
				flag=1;
				break;
			}
		}
		if(flag == 0)
		{
			x = get_x(i);
			for(int p=0;p<31;p++)
			{
				isGridempty[i][p]=0;
				clearrectangle(left,x-10,left+10,x);
				left += 10;
			}
			for(int k=i-1;k>=0;k--)
			{
				for(int z=0;z<31;z++)
				{
					color=isGridempty[k][z];
					if(color)
					{
						y = get_y(z); //  左位置
						x = get_x(k);  // 下位置
						clearrectangle(y,x-10,y+10,x);
						setfillcolor(color);
						isGridempty[k][z]=0;
						fillrectangle(y,x,y+10,x+10);
						isGridempty[k+1][z]=color;
					}
				}
			}
	score++;
	int sum = brickLenth*score;
	TCHAR s[30];
	_stprintf_s(s,_T("%d"),sum);
	outtextxy(155,195,s);
		}
	}

}
void fastenBrick()   //  函数功能:原位置固定方块
{
	for(int i=0;i<now.lenth;i++)
	{
		int y = getY(now.coordinate[i][0]);
		int x = getX(now.coordinate[i][3]);
		if(x!=-1 && y!=-1)
		{
			isGridempty[x][y]=now.color;
		}
	}
	if(ifdeath())
	{
		if(_kbhit())
		{
			if(_getch()=='f')
			{
				onRestart();
				return;
			}
		}
	}
	clearfullRow();
	randomBrick();
}
void onRotate()
{
	if(brick[now.brick][now.which+1]==1)
	{
		return;
	}
	unsigned int tempmemory[4][4];  // 记录位置,前16位记录横坐标(列),后16位记录纵坐标(行)
	unsigned int temp = brick[now.brick][now.which];
	int l = 0;
	int x,y;
	for(int i=15;i>=0;i--)
	{
		tempmemory[i/4][i%4]=0;
		if(temp&1)
		{
			y = getY(now.coordinate[l][0]);  // 列
			x = getX(now.coordinate[l][3]);  // 行
			y <<= 16;
			tempmemory[i/4][i%4] = x|y;
			l++;
		}
		temp >>= 1;
	}
	for(int j=0;j<4;j++)  //  4*4*4  可以接受的  这有重复计算!
	{
		for(int k=0;k<4;k++)
		{
			if(tempmemory[j][k])
			{
				for(int i1=0;i1<k;i1++)
				{
					if(tempmemory[j][i1]) continue;
					tempmemory[j][i1] = tempmemory[j][k] - ((k-i1)<<16);
				}
				for(int i2=k+1;i2<4;i2++)
				{
					if(tempmemory[j][i2]) continue;
					tempmemory[j][i2] = tempmemory[j][k] + ((i2-k)<<16);
				}
				for(int i3=0;i3<j;i3++)
				{
					if(tempmemory[i3][k]) continue;
					tempmemory[i3][k] = tempmemory[j][k] + (j-i3);
				}
				for(int i4=j+1;i4<4;i4++)
				{
					if(tempmemory[i4][k]) continue;
					tempmemory[i4][k] = tempmemory[j][k] + (i4-j);
				}
			}
		}
	}
	unsigned int temp2;
	int x1,y1,l1=0;
	if(now.which == 3) now.which=0;
	else now.which++;
	temp = brick[now.brick][now.which];
	if(temp == 0u)
	{
		now.which=0;
		temp=brick[now.brick][now.which];
	}
	for(int k1=0;k1<now.lenth;k1++)
		clearrectangle(now.coordinate[k1][0],now.coordinate[k1][1],now.coordinate[k1][2],now.coordinate[k1][3]);
	setfillcolor(now.color);
	for(int j1=15;j1>=0;j1--)
	{
		if(temp&1)
		{
			temp2 = tempmemory[j1/4][j1%4];
			y1 = temp2 >> 16;  // 列
			x1 = temp2 & 65535u;  // 行
			y1 = get_y(y1);
			x1 = get_x(x1);
			fillrectangle(y1,x1-10,y1+10,x1);
			now.coordinate[l1][0]=y1,now.coordinate[l1][1]=x1-10,now.coordinate[l1][2]=y1+10,now.coordinate[l1][3]=x1;
			l1++;
		}
		temp >>= 1;
	}
	now.lenth=l1;
}
void onLeft()
{
	for(int k=0;k<now.lenth;k++)
	{
		if(now.coordinate[k][0] - brickLenth < xlborder)   //  判断是否到底
		{
			return;
		}
		int y = getY(now.coordinate[k][0] - brickLenth);   //  通过横坐标算出来的是列  纵坐标算出来的是行
		int x = getX(now.coordinate[k][3]);
		if(x!=-1 && y!=-1)
		{
			if(isGridempty[x][y])
			{
				return;
			}
		}
	}
	setfillcolor(now.color);
	for(int j=0;j<now.lenth;j++)
	{
		clearrectangle(now.coordinate[j][0],now.coordinate[j][1],now.coordinate[j][2],now.coordinate[j][3]);
		now.coordinate[j][0]-=brickLenth,now.coordinate[j][2]-=brickLenth;
		fillrectangle(now.coordinate[j][0],now.coordinate[j][1],now.coordinate[j][2],now.coordinate[j][3]);
	}
}
void onRight()
{
	for(int k=0;k<now.lenth;k++)
	{
		if(now.coordinate[k][2] + brickLenth > xrborder)   //  判断是否到底
		{
			return;
		}
		int y = getY(now.coordinate[k][0] + brickLenth);   //  通过横坐标算出来的是列  纵坐标算出来的是行
		int x = getX(now.coordinate[k][3]);
		if(x!=-1 && y!=-1)
		{
			if(isGridempty[x][y])
			{
				return;
			}
		}
	}
	setfillcolor(now.color);
	for(int j=0;j<now.lenth;j++)
	{
		clearrectangle(now.coordinate[j][0],now.coordinate[j][1],now.coordinate[j][2],now.coordinate[j][3]);
		now.coordinate[j][0]+=brickLenth,now.coordinate[j][2]+=brickLenth;
		fillrectangle(now.coordinate[j][0],now.coordinate[j][1],now.coordinate[j][2],now.coordinate[j][3]);
	}
}
bool onDown()
{
	for(int k=0;k<now.lenth;k++)
	{
		if(now.coordinate[k][3] + brickLenth > ybborder)   //  判断是否到底
		{

	     	fastenBrick();
			return true;
		}
		int y = getY(now.coordinate[k][0]);   //  通过横坐标算出来的是列  纵坐标算出来的是行
		int x = getX(now.coordinate[k][3] + brickLenth);
		if(x!=-1 && y!=-1)
		{
			if(isGridempty[x][y])
			{
				fastenBrick();
				return true;
			}
		}
	}
	setfillcolor(now.color);
	for(int j=0;j<now.lenth;j++)
	{
		clearrectangle(now.coordinate[j][0],now.coordinate[j][1],now.coordinate[j][2],now.coordinate[j][3]);
		now.coordinate[j][1]+=brickLenth,now.coordinate[j][3]+=brickLenth;
		fillrectangle(now.coordinate[j][0],now.coordinate[j][1],now.coordinate[j][2],now.coordinate[j][3]);
	}
	return false;
}
void onDrop()  //  急落
{
	while(true)
	{
		if(onDown()) break;
		Sleep(20);
	}
}
void onQuit()
{
	exit(0);
}
void onPause()
{
	while(true)
	{
		if(_kbhit())
		{
			if(_getch() == VK_SPACE) break;
		}
	}
}
DWORD fronttime;
order keyboardListener()
{
	while(true)  //  这必须是死循环
	{
		DWORD nowtime = GetTickCount();
		if(nowtime - fronttime >= 1000)
		{
			fronttime = nowtime;
			return Down;
		}
		else if(_kbhit())
		{
			switch(_getch())
			{
			case 'a':
			case 'A':
				return Left;
			case 'w':
			case 'W':
				return Rotate;
			case 's':
			case 'S':
				return Down;
			case 'd':
			case 'D':
				return Right;
			case 'z':
			case 'Z':
				return Quit;
			case 'f':
			case 'F':
				return Restart;
			case 'x':
			case 'X':
				return Drop;
			case VK_SPACE:
				return Pause;
			case 0:
			case 0xE0:
					switch(_getch())
					{
					case 72:	return Rotate;
					case 75:	return Left;
					case 77:	return Right;
					case 80:	return Down;
					}
			}
		}
		Sleep(20);
	}
}
void execute(order o)
{
	switch(o)
	{
	case Rotate: 
		onRotate();
		break;
	case Left:
		onLeft();
		break;
	case Right:
		onRight();
		break;
	case Down:
		onDown();
		break;
	case Drop:
		onDrop();
		break;
	case Quit:
		onQuit();
		break;
	case Pause:
		onPause();
		break;
	case Restart:
		onRestart();
		break;
	}
}
int _tmain(int argc, _TCHAR* argv[])
{

	initUI();
	randomBrick();
	while(true)
	{
		//键盘监听器 如果长时间无动作执行默认操作
		order o = keyboardListener();
		execute(o);
	}
	return 0;
}

你可能感兴趣的:(继上篇,俄罗斯方块代码)