用C语言写国际化的俄罗斯方块,C++写面向对象思想俄罗斯方块版本

因为最近在学习UNICODE编码和ANSI编码以及多字节编码在VS下是如何控制变化的,所以

用C语言写了个简单的俄罗斯方块版本,并让它兼容了UNICODE和ANSI字符集,即国际化可以在任何国家地区使用只要随setlocale函数做参数修改

(虽然没什么必要 主要是为了更好的理解字符编码)

然后又用C++写了另外一个面向对象的版本版本。。。

C语言版本我做了非常详细的注释, 初学者可以参考下。中间可能会有一些我还没发现的BUG

C++版本是我之后写的,懒得做注释了。。 因为这两游戏写了我一天,真的心很累

C++版本的俄罗斯方块:

C代码:

#include <stdio.h>
#include <conio.h>
#include <windows.h>
#include <wchar.h>
#include <process.h>
#include <stdlib.h>
#include <time.h>
#include <locale.h>

#define MYUNICODE

#if !defined(MYUNICODE)
#define _tprintf printf
#define _tsetlocale setlocale 
#define _tmemmove memmove
#define _tmemset memset
#define _tmemcpy memcpy
#define _tsystem system
#define aTEXT(s) s
#define TCHAR char
#define UTCHAR unsigned char 
#else 
#define _tprintf wprintf 
#define _tsetlocale _wsetlocale
#define _tmemmove wmemmove
#define _tmemset wmemset
#define _tmemcpy wmemcpy
#define _tsystem _wsystem
#define aTEXT(s) L##s
#define TCHAR short
#define UTCHAR unsigned short 
#endif 

#define ROW 16 // 不算墙体 0-14 15行
#define COL 12 // 不算墙体 1-10 10列
#define WALL 1
#define BLOCK 2
#define FIXEDBLOCK 3

UTCHAR g_uchMaxTetris[ROW][COL] = { '\0' };
UTCHAR g_uchBlock[][4] = {
	0, 0, 0, 0,
	0, 0, 0, 0,
	0, 0, 0, 0,
	0, 0, 0, 0
};

typedef enum _enumShape
{
	SHAPE0,
	SHAPE1,
	SHAPE2,
	SHAPE3
} enumShape, *pEnumShape;

int g_nBlockRow = 0;			 // 方块在大数组中行坐标
int g_nBlockCol = COL / 2 - 2;	 // 方块在大数组中列坐标
int g_nBlockType = 0;			 // 类型
int g_nNewCreate = 0;			 // 是否是新创
enumShape g_nBlockShape = SHAPE0; // 形状
// 代表游戏区域的15行,如果某一行到达了10即代表该行已满,可以消除
UTCHAR g_ucLineArr[ROW - 1] = { 0 };
// 总分
unsigned long g_ulScore = 0;
// 当前关卡
UTCHAR g_ucLevel = 1;
// 第一关间隔时间(毫秒)
unsigned long g_ulMiliSec = 232;

/*
类型0    类型1	    类型2
■ ■    ■ ■ ■ ■		■ ■ ■
■ ■				      ■
*/

void gotoxy(int x, int y)
{
	HANDLE hConsole = NULL;
	COORD crd;
	crd.X = y * 2;
	crd.Y = x;
	hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
	if (NULL == hConsole)
	{
		return;
	}
	SetConsoleCursorPosition(hConsole, crd);
}

void 
ClearBlock()
/*++
* @Description
* 清除块图内容
* @Param
* @Return
--*/
{
	_tmemset(&g_uchBlock[0][0], 0, 16);
}

void 
CreateType0(
	enumShape eShape
	)
/*++
* @Description
* 创建+类型的块并写入块图内
* @Param
* eShape: 代表形状
* @Return
--*/
{
	int i, j;

	ClearBlock();
	for (i = 0; i < 2; ++i)
	{
		for (j = 0; j < 2; ++j)
		{
			g_uchBlock[i][j] = 1;
		}
	}
}

void 
CreateType1(
	enumShape eShape
	)
/*++
* @Description
* 创建I类型的块并写入块图内
* @Param
* eShape: 代表形状
* @Return
--*/
{
	int i;

	ClearBlock();
	g_uchBlock[0][0] = 1;
	switch (eShape)
	{
	case SHAPE0:
	case SHAPE2:
		for (i = 1; i < 4; ++i)
		{
			g_uchBlock[0][i] = 1;
		}
		break;
	case SHAPE1:
	case SHAPE3:
		for (i = 1; i < 4; ++i)
		{
			g_uchBlock[i][0] = 1;
		}
		break;
	}
}

void 
CreateType2(
	enumShape eShape
	)
/*++
* @Description
* 创建T类型的块并写入块图内
* @Param
* eShape: 代表形状
* @Return
--*/
{
	int i;

	ClearBlock();
	g_uchBlock[1][1] = 1;
	switch (eShape)
	{
	case SHAPE0:
		g_uchBlock[0][1] = g_uchBlock[1][0] = g_uchBlock[1][2] = 1;
		break;
	case SHAPE1:
		g_uchBlock[0][0] = g_uchBlock[1][0] = g_uchBlock[2][0] = 1;
		break;
	case SHAPE2:
		for (i = 0; i < 3; ++i)
		{
			g_uchBlock[0][i] = 1;
		}
		break;
	case SHAPE3:
		g_uchBlock[0][1] = g_uchBlock[1][0] = g_uchBlock[2][1] = 1;
	}
}

int 
InitWall()
/*++
* @Description
* 在游戏地图上初始化墙体,写入WALL预定义常量
* @Param
* @Return
* 0: 成功
--*/
{
	int iIndex = 0;
	_tmemset(&g_uchMaxTetris[15][0], WALL, COL);
	for (iIndex = 0; iIndex < ROW; ++iIndex)
	{
		g_uchMaxTetris[iIndex][0] = g_uchMaxTetris[iIndex][COL - 1] = WALL;
	}

	return(0);
}

int 
ShowUI()
/*++
* @Description
* 把游戏地图的内容显示出来
* @Return
* 0: 成功
* -1: 代表根本没画
--*/
{
	int i, j;
	// 回到原点重画
	gotoxy(0, 0);
	for (i = 0; i < ROW; ++i)
	{
		for (j = 0; j < COL; ++j)
		{
			if (WALL == g_uchMaxTetris[i][j] ||
				BLOCK == g_uchMaxTetris[i][j] ||
				FIXEDBLOCK == g_uchMaxTetris[i][j])
			{
				_tprintf(aTEXT("■"));
			}
			else
			{
				_tprintf(aTEXT("  "));
			}
		}
		putchar('\n');
	}
	

	return(0);
}

int 
BlockWriteToMaxTetris()
/*++
* @Description
* 在地图上方即块出生点写入块到地图
* @Return
* 0:成功
--*/
{
	int i, j;

	for (i = 0; i < 4; ++i)
	{
		for (j = 0; j < 4; ++j)
		{
			if (1 == g_uchBlock[i][j])
			{
				g_uchMaxTetris[i + g_nBlockRow][j + g_nBlockCol] = BLOCK;
			}
		}
	}

	return(0);
}

int 
ClearBlockFromMaxTetris()
/*++
* @Description
* 如果有立马要下落的块就从游戏地图中清除该块
* @Return
* 0: 代表成功清除
--*/
{
	int i, j;

	for (i = 0; i < 4; ++i)
	{
		for (j = 0; j < 4; ++j)
		{
			if ((1 == g_uchBlock[i][j]) &&
				(BLOCK == g_uchMaxTetris[i + g_nBlockRow][j + g_nBlockCol]))
			{
				g_uchMaxTetris[i + g_nBlockRow][j + g_nBlockCol] = 0;
			}
		}
	}

	return(0);
}

int
CreateSpecificBlock(
	int iBlockType,
	int iBlockShape
)
/*++
* @Description
* 创建一种特定类型形状的块并写入游戏地图
* @Return
* 0:成功
* -1: 写入地图失败
--*/
{
	g_nBlockType = iBlockType;
	g_nBlockShape = iBlockShape;

	switch (g_nBlockType)
	{
	case 0:
		CreateType0(g_nBlockShape);
		break;
	case 1:
		CreateType1(g_nBlockShape);
		break;
	case 2:
		CreateType2(g_nBlockShape);
		break;
	}

	// 如果是新创建的块,则需要重置成初始位置
	if (g_nNewCreate)
	{
		g_nBlockRow = 0;
		g_nBlockCol = COL / 2 - 2;
		// 关闭标志位,只有再次新创建块后才会开启
		g_nNewCreate = 0;
	}
	// 写入游戏地图
	if (-1 == BlockWriteToMaxTetris())
	{
		return(-1);
	}

	return(0);
}

int
CreateBlock()
/*++
* @Description
* 创建一种随机类型随机形状的块并写入游戏地图
* @Return
* 0:成功
* -1: 写入地图失败
--*/
{
	int iRet;

	// 随机出现方块的类型和形状
	g_nBlockType = rand() % 3;
	g_nBlockShape = rand() % 4;
	// 测试
	//g_nBlockType = 1;
	//g_nBlockShape = 0;
	// 这是一个新创建的块
	g_nNewCreate = 1;

	iRet = CreateSpecificBlock(g_nBlockType,
		g_nBlockShape);

	return(iRet);
}

int
IsMoveOrRotate(int nBlockRow,
	int nBlockCol
)
/*++
* @Description
* 判断当前块能否下落或旋转
* @Param
* nBlockRow: 起始行
* nBlockCol: 起始列
* @Return
* 1:该位置代表撞了, 不能移动到该位置
* 0: 可以移动到该位置或者旋转
--*/
{
	int i, j;

	for (i = 0; i < 4; ++i)
	{
		for (j = 0; j < 4; ++j)
		{
			// 确保当前图形旋转后在游戏地图上能够不会越界
			if (1 == g_uchBlock[i][j] &&
				((WALL == g_uchMaxTetris[i + nBlockRow][j + nBlockCol]) ||
					(FIXEDBLOCK == g_uchMaxTetris[i + nBlockRow][j + nBlockCol]))
				)
			{
				return(1);
			}
		}
	}

	return(0);
}

int 
BlockRotate()
/*++
* @Description
* 判断是否可以执行旋转,可以则旋转
* @Param
* @Return
* 0: 代表成功旋转
* -1: 代表出错或留着拓展
--*/
{
	int nRet = 0;
	int nBlockOffset = 0;
	// 轮转变换形状
	int nBlockShape = (g_nBlockShape + 1) % 4;

	// 判断是否可以下落或者旋转
	nRet = IsMoveOrRotate(g_nBlockRow,
		g_nBlockCol
	);

	// 进入这里代表是旋转, 即仅仅是更改形状
	if (0 == nRet)
	{
		// 清除游戏地图上的初始块
		if (-1 == ClearBlockFromMaxTetris())
		{
			return(-1);
		}
		// 变更形状
		g_nBlockShape = nBlockShape;
		// 创建对应形状的块并写入块图内
		if (-1 == CreateSpecificBlock(g_nBlockType, g_nBlockShape))
		{
			return(-1);
		}
		// 将块图内的内容写入游戏地图内
		if (-1 == BlockWriteToMaxTetris())
		{
			return(-1);
		}
	}
	// 留着拓展
	else if (-1 == nRet)
	{
		return(-1);
	}
	// 显示游戏地图内容到屏幕,即旋转或者下落后的块
	ShowUI();

	return(0);
}


TCHAR
FindTopRowNum()
/*++
* @Description
* 获取最高行的行号
* @Param
* @Return
* >=0: 最高行号
* -1: 没有最高行号,即没有任何下落的块被固定
--*/
{
	// 确认当前最高行, 即ROW最小
	for (int iIndex = 0; iIndex <= 14; ++iIndex)
	{
		// 该行只要有一个格子被占,即最高行
		if (g_ucLineArr[iIndex] > 0)
		{
			return(iIndex);
		}
	}
	return(-1);
}

int 
BlockMoveDown()
/*++
* @Description
* 判断是否可以执行下落
* @Param
* @Return
* 0: 代表成功下来
* -1: 代表出错或留着拓展
--*/
{
	int i, j, nRet, iTopRow, iIndex;

	// 判断下个位置是否可以到底
	nRet = IsMoveOrRotate(g_nBlockRow + 1,
		g_nBlockCol);

	// 下个位置没撞可以下落
	if (0 == nRet)
	{
		// 把起始块从游戏地图上清除
		if (-1 == ClearBlockFromMaxTetris())
		{
			return(-1);
		}
		// 掉落一格
		g_nBlockRow++;
		// 写入游戏地图
		if (-1 == BlockWriteToMaxTetris())
		{
			return(-1);
		}
	}
	// 代表下个位置就撞了, 直接把块固定下来
	else if (1 == nRet)
	{
		for (i = 0; i < 4; ++i)
		{
			for (j = 0; j < 4; ++j)
			{
				if (BLOCK == g_uchMaxTetris[i + g_nBlockRow][j + g_nBlockCol] &&
					1 == g_uchBlock[i][j])
				{
					g_uchMaxTetris[i + g_nBlockRow][j + g_nBlockCol] = FIXEDBLOCK;
					// 固定的行增加其数目,代表一行已经有多少格被填满
					(g_ucLineArr[i + g_nBlockRow])++;
					// 这一行满了
					if (10 <= g_ucLineArr[i + g_nBlockRow])
					{
						// 确认当前最高行, 即ROW最小
						iTopRow = FindTopRowNum();
						if (iTopRow)
						// 从最高层往下挪动操作, 无需检查iTopRow的值因为既然已经存在满行
						// 则肯定存在最高行,当要检查最高行是不是满行
						if (i + g_nBlockRow == iTopRow)
						{
							// 如果是的话直接通过memset淹没即可
							_tmemset(&g_uchMaxTetris[iTopRow][1], 0, 10);
							// 清空对应行的格子数
							g_ucLineArr[iTopRow] = 0;
						}
						else 
						{
							// 这种清空代表最高行不是满行,则需要迭代挪动
							for (iIndex = i + g_nBlockRow; iIndex >= iTopRow; --iIndex)
							{
								// 这里不考虑填满之类的清空,这不大可能存在
								_tmemcpy(&g_uchMaxTetris[iIndex][1], &g_uchMaxTetris[iIndex - 1][1], 10);
								// 由于被消行,g_ucLineArr也需要进行
								g_ucLineArr[iIndex] = g_ucLineArr[iIndex - 1];
							}
							g_ulScore += 10;
							gotoxy(0, 16);
							_tprintf(aTEXT("%lu"), g_ulScore);
						}
					}
				}
			}
		}
		// 创建一个新块
		if (-1 == CreateBlock())
		{
			return(-1);
		}
	}
	// 可能出现问题, 拓展
	else if (-1 == nRet)
	{
		return(-1);
	}
	else
	{
		// 用于拓展
	}
	ShowUI();

	return(0);
}

int 
BlockMoveRight()
/*++
* @Description
* 判断是否可以执行右移
* @Param
* @Return
* 0: 代表成功
* -1: 代表出错或留着拓展
--*/
{
	int nRet;
	
	// 往右挪一格看一下能不能走
	nRet = IsMoveOrRotate(g_nBlockRow,
		g_nBlockCol + 1
		);

	// 可以移
	if (0 == nRet)
	{
		// 清除该块在游戏地图上本来的位置
		if (EOF == ClearBlockFromMaxTetris())
		{
			return(EOF);
		}
		// 往右挪一格
		g_nBlockCol++;
		// 写入块在游戏地图新位置
		if (-1 == BlockWriteToMaxTetris())
		{
			return(-1);
		}
	}
	else if (-1 == nRet)
	{
		return(-1);
	}
	ShowUI();

	return(0);
}

int 
BlockMoveLeft()
/*++
* @Description
* 判断是否可以执行左移
* @Param
* @Return
* 0: 代表成功
* -1: 代表出错或留着拓展
--*/
{
	int nRet = 0;

	nRet = IsMoveOrRotate(g_nBlockRow,
		g_nBlockCol - 1);
	if (0 == nRet)
	{
		if (-1 == ClearBlockFromMaxTetris())
		{
			return(-1);
		}
		g_nBlockCol--;
		if (-1 == BlockWriteToMaxTetris())
		{
			return(-1);
		}
	}
	else if (-1 == nRet)
	{
		return(-1);
	}
	ShowUI();

	return(0);
}

unsigned long 
LevelUp(
	unsigned long ulScore
	)
/*++
* @Description
* 提升游戏关卡
* @Param
* ulScore: 当前得分
* @Return
* 代表当前关卡的游戏间隔时间(ms)
--*/
{
	unsigned long ulTmp = g_ucLevel;
	// 一共5关,自己拓展
	if (ulScore >= 500 && g_ucLevel <= 4)
	{
		g_ucLevel++;
		g_ulMiliSec = 20;
	}
	else if (ulScore >= 300 && g_ucLevel <= 3)
	{
		g_ucLevel++;
		g_ulMiliSec = 50;
	}
	else if (ulScore >= 100 && g_ucLevel <= 2)
	{
		g_ucLevel++;
		g_ulMiliSec = 100;
	}
	else if (ulScore >= 10 && g_ucLevel <= 1)
	{
		g_ucLevel++;
		g_ulMiliSec = 150;
	}
	// 如果关卡变动则提升等级
	if (ulTmp < g_ucLevel)
	{
		gotoxy(1, 16);
		_tprintf(aTEXT("%d"), g_ucLevel);
	}

	return(g_ulMiliSec);
}

void 
Run()
/*++
* @Description
* 控制逻辑主函数
* @Param
* @Return
--*/
{
	unsigned long ulMiliSec = 0;
	TCHAR cPushBtn = 0;
	clock_t stFirst = 0;
	clock_t stLast = 0;
	// 初始化墙
	InitWall();
	CreateBlock();
	/*ShowUI();*/
	// 按下任意键开始
	_tprintf(aTEXT("按下任意键开始!\n"));
	cPushBtn = _getch();
	_tsystem(aTEXT("cls"));
	gotoxy(0, 12);
	_tprintf(aTEXT("总得分: "));
	gotoxy(0, 16);
	_tprintf(aTEXT("%lu"), g_ulScore);
	gotoxy(1, 12);
	_tprintf(aTEXT("关卡: "));
	gotoxy(1, 16);
	_tprintf(aTEXT("%d"), g_ucLevel);
	gotoxy(2, 12);
	_tprintf(aTEXT("按ESC退出"));
	// 如果是ESC则直接退出
	while (0x1B != cPushBtn)
	{
		// 没有输入则直接一直下降
		do
		{
			// 不管有没有按默认要下降
			BlockMoveDown();
			ulMiliSec = LevelUp(g_ulScore);
			//clock();
			Sleep(ulMiliSec);
		} while (!_kbhit());
		// 如果从键盘缓冲区内收到了输入则直接从缓冲区内获取
		cPushBtn = _getch();
		switch (cPushBtn)
		{
			// 左
		case 'a':
		case 'A':
			BlockMoveLeft();
			break;
			// 上, 代表旋转
		case 'w':
		case 'W':
			BlockRotate();
			break;
			// 右
		case 'd':
		case 'D':
			BlockMoveRight();
			break;
			// 下
		case 's':
		case 'S':
			BlockMoveDown();
			break;
		}
		
	}
	
	return;
}

int 
main()
{
	TCHAR ch = 0;

	_tsetlocale(LC_ALL, aTEXT("chs"));
	srand((unsigned)time(NULL));
	Run();

	_tsystem(aTEXT("pause"));
	
	return 0;
}

C++版本俄罗斯方块的代码:

//CBrick.h
#pragma once
#include "CBrickUnit.h"
#include "CMainGameArea.h"
#define KBRICK_UNIT_COUNT 4

// 砖块父类
class CBrick
{
public:
	CBrick(CMainGameArea *pGameArea);
	virtual ~CBrick();
	virtual bool rotate() = 0;
	void eraseBrick();
	void drawBrick();
	bool moveLeft();
	bool moveRight();
	bool moveDown();

	void setGameAreaMatrix();

protected:
	CBrickUnit m_arrBrickUnit[KBRICK_UNIT_COUNT];
	int m_iStatus;
	CMainGameArea* m_pGameArea;
private:
};


// CBrickStyle1.h
#pragma once
#include "CBrick.h"

class CBrickStyle1 : public CBrick
{
public:
	CBrickStyle1(CMainGameArea* pGameArea);

	virtual bool rotate();
private:
};


// CBrickStyle2.h
#pragma once
#include "CBrick.h"
class CBrickStyle2 : public CBrick
{
public:
	CBrickStyle2(CMainGameArea* pGameArea);
	virtual bool rotate();
};


// CBrickStyle3.h
#pragma once
#include "CBrick.h"

class CBrickStyle3 : public CBrick
{
public:
	CBrickStyle3(CMainGameArea* pGameArea);
	virtual bool rotate();
};


// CBrickStyle4.h
#pragma once
#include "CBrick.h"
class CBrickStyle4 : public CBrick
{
public:
	CBrickStyle4(CMainGameArea* pGameArea);
	virtual bool rotate();
};


// CBrickStyle5.h
#pragma once
#include "CBrick.h"
class CBrickStyle5 : public CBrick
{
public:
	CBrickStyle5(CMainGameArea* pGameArea);
	virtual bool rotate();
};


// CBrickStyle6.h
#pragma once
#include "CBrick.h"

class CBrickStyle6 : public CBrick
{
public:
	CBrickStyle6(CMainGameArea* pGameArea);
	virtual bool rotate();
};


// CBrickStyle7.h
#pragma once
#include "CBrick.h"
class CBrickStyle7 : public CBrick
{
public:
	CBrickStyle7(CMainGameArea* pGameArea);
	virtual bool rotate();
};


// CBrickUnit.h
#pragma once
// 砖块单元
class CBrickUnit
{
public:
	CBrickUnit(char image = '*');
	void drawBrickUnit();
	void eraseBrickUnit();
public:
	int m_iX;
	int m_iY;
	char m_cImage;
private:
};


// CCommFunc.h
#pragma once
class CCommFunc
{
public:
	static void gotoxy(int x, int y);
};


// CInfoBoard.h
#pragma once
class CInfoBoard
{
public:
	CInfoBoard(int offsetX, int offsetY);
	void drawInfoBoard(int needLayers, int currentLayers);
	void drawInfoBoard(int needLayers, int currentLayers, int level);
private:
	int m_iOffsetX;
	int m_iOffsetY;
};


// CMainGameArea.h
#pragma once
#define KROW 19
#define KCOL 15

class CMainGameArea
{
public:
	CMainGameArea(int offsetX = 0, int offsetY = 0);
	void drawGameArea();
	void drawMatrix();
	int tryAndCutLayer();
	void resetGameArea();

	int getOffsetX() const;
	int getOffsetY() const;

	int getMatrixStatus(int row, int col) const;
	void setMatrixStatus(int row, int col, int status);
private:
	void curLayer(int row);
private:
	int m_arrAreaMatrix[KROW][KCOL];
	int m_iOffsetX;
	int m_iOffsetY;
};


// CNextBrickBoard.h
#pragma once
class CNextBrickBoard
{
public:
	CNextBrickBoard(int offsetX, int offsetY);
	void drawNextBrickBoard(int brickIndex);
private:
	int m_iOffsetX;
	int m_iOffsetY;
};


// CTetrisGame.h
#pragma once
#include "CMainGameArea.h"
#include "CInfoBoard.h"
#include "CNextBrickBoard.h"
#include "CBrick.h"

// 游戏逻辑类
class CTetrisGame
{
public:
	CTetrisGame();
	void run();
private:
	void setGameArea();
	CBrick *createNewBrick(int& brickIndex);
private:
	CMainGameArea* m_pGameArea;
	CInfoBoard* m_pInfoBoard;
	CNextBrickBoard* m_pNextBrickBoard;
	
	int m_iSpeed;
	int m_iLevel;
	int m_iLayerCount;
};


#include "CBrick.h"

CBrick::CBrick(CMainGameArea* pGameArea)
{
	m_pGameArea = pGameArea;
	m_iStatus = 0;
	m_arrBrickUnit[1].m_iX = m_pGameArea->getOffsetX() + KCOL / 2 + 1;
	m_arrBrickUnit[1].m_iY = m_pGameArea->getOffsetY() + 1;
}

CBrick::~CBrick()
{

}

void CBrick::eraseBrick()
{
	for (int i = 0; i < KBRICK_UNIT_COUNT; ++i)
		m_arrBrickUnit[i].eraseBrickUnit();
}

void CBrick::drawBrick()
{
	for (int i = 0; i < KBRICK_UNIT_COUNT; ++i)
		m_arrBrickUnit[i].drawBrickUnit();
}

bool CBrick::moveLeft()
{
	for (int k = 0; k < KBRICK_UNIT_COUNT; ++k) {
		if (m_arrBrickUnit[k].m_iX - 1 <= m_pGameArea->getOffsetX())
			return(false);
		int x = m_arrBrickUnit[k].m_iX - 1 - m_pGameArea->getOffsetX() - 1;
		int y = m_arrBrickUnit[k].m_iY - m_pGameArea->getOffsetY();
		if (m_pGameArea->getMatrixStatus(y, x) == 1)
			return(false);
	}
	this->eraseBrick();
	for (int i = 0; i < KBRICK_UNIT_COUNT; ++i) 
		m_arrBrickUnit[i].m_iX -= 1;
	this->drawBrick();

	return(true);
}

bool CBrick::moveRight()
{
	for (int k = 0; k < KBRICK_UNIT_COUNT; ++k) {
		if (m_arrBrickUnit[k].m_iX + 1 > (m_pGameArea->getOffsetX() + KCOL))
			return(false);
		int x = m_arrBrickUnit[k].m_iX - 1 - m_pGameArea->getOffsetX() + 1;
		int y = m_arrBrickUnit[k].m_iY - m_pGameArea->getOffsetY();
		if (m_pGameArea->getMatrixStatus(y, x) == 1)
			return(false);
	}
	this->eraseBrick();
	for (int i = 0; i < KBRICK_UNIT_COUNT; ++i)
		m_arrBrickUnit[i].m_iX += 1;
	this->drawBrick();

	return(true);
}

bool CBrick::moveDown()
{
	for (int k = 0; k < KBRICK_UNIT_COUNT; ++k) {
		if (m_arrBrickUnit[k].m_iY + 1 >= (m_pGameArea->getOffsetY() + KROW))
			return(false);
		int x = m_arrBrickUnit[k].m_iX - 1 - m_pGameArea->getOffsetX();
		int y = m_arrBrickUnit[k].m_iY - m_pGameArea->getOffsetY() + 1;
		if (m_pGameArea->getMatrixStatus(y, x) == 1) 
			return(false);
	}
	this->eraseBrick();
	for (int i = 0; i < KBRICK_UNIT_COUNT; ++i)
		m_arrBrickUnit[i].m_iY += 1;
	this->drawBrick();

	return(true);
}
#include <iostream>
using namespace std;

void CBrick::setGameAreaMatrix()
{
	for (int i = 0; i < KBRICK_UNIT_COUNT; ++i) {
		int x = m_arrBrickUnit[i].m_iX - 1 - m_pGameArea->getOffsetX();
		int y = m_arrBrickUnit[i].m_iY - m_pGameArea->getOffsetY();
		m_pGameArea->setMatrixStatus(y, x, 1);
	}
}

#include "CBrickStyle1.h"

/*
	**
	**
*/

CBrickStyle1::CBrickStyle1(CMainGameArea* pGameArea) : CBrick(pGameArea)
{
	m_arrBrickUnit[0].m_iX = m_arrBrickUnit[1].m_iX - 1;
	m_arrBrickUnit[0].m_iY = m_arrBrickUnit[1].m_iY;
	m_arrBrickUnit[2].m_iX = m_arrBrickUnit[1].m_iX - 1;
	m_arrBrickUnit[2].m_iY = m_arrBrickUnit[1].m_iY + 1;
	m_arrBrickUnit[3].m_iX = m_arrBrickUnit[1].m_iX;
	m_arrBrickUnit[3].m_iY = m_arrBrickUnit[1].m_iY + 1;
}

bool CBrickStyle1::rotate()
{
	return(true);
}

#include "CBrickStyle2.h"

/*
 ****
*/

CBrickStyle2::CBrickStyle2(CMainGameArea* pGameArea) : CBrick(pGameArea)
{
	m_arrBrickUnit[0].m_iX = m_arrBrickUnit[1].m_iX - 1;
	m_arrBrickUnit[0].m_iY = m_arrBrickUnit[1].m_iY;
	m_arrBrickUnit[2].m_iX = m_arrBrickUnit[1].m_iX + 1;
	m_arrBrickUnit[2].m_iY = m_arrBrickUnit[1].m_iY;
	m_arrBrickUnit[3].m_iX = m_arrBrickUnit[1].m_iX + 2;
	m_arrBrickUnit[3].m_iY = m_arrBrickUnit[1].m_iY;
}

bool CBrickStyle2::rotate()
{
	/*
	****
	*/
	this->eraseBrick();
	switch (m_iStatus) {
	case 0: // 0 -> 1
		m_arrBrickUnit[0].m_iX = m_arrBrickUnit[1].m_iX;
		m_arrBrickUnit[0].m_iY = m_arrBrickUnit[1].m_iY - 1;
		m_arrBrickUnit[2].m_iX = m_arrBrickUnit[1].m_iX;
		m_arrBrickUnit[2].m_iY = m_arrBrickUnit[1].m_iY + 1;
		m_arrBrickUnit[3].m_iX = m_arrBrickUnit[1].m_iX;
		m_arrBrickUnit[3].m_iY = m_arrBrickUnit[1].m_iY + 2;
		break;
	case 1:
		m_arrBrickUnit[0].m_iX = m_arrBrickUnit[1].m_iX - 1;
		m_arrBrickUnit[0].m_iY = m_arrBrickUnit[1].m_iY;
		m_arrBrickUnit[2].m_iX = m_arrBrickUnit[1].m_iX + 1;
		m_arrBrickUnit[2].m_iY = m_arrBrickUnit[1].m_iY;
		m_arrBrickUnit[3].m_iX = m_arrBrickUnit[1].m_iX + 2;
		m_arrBrickUnit[3].m_iY = m_arrBrickUnit[1].m_iY;
		break;
	}
	this->drawBrick();

	m_iStatus = (m_iStatus + 1) % 2;

	return(true);
}


#include "CBrickStyle3.h"

/*

***
 *

*/

CBrickStyle3::CBrickStyle3(CMainGameArea* pGameArea) : CBrick(pGameArea)
{
	m_arrBrickUnit[0].m_iX = m_arrBrickUnit[1].m_iX - 1;
	m_arrBrickUnit[0].m_iY = m_arrBrickUnit[1].m_iY;
	m_arrBrickUnit[2].m_iX = m_arrBrickUnit[1].m_iX + 1;
	m_arrBrickUnit[2].m_iY = m_arrBrickUnit[1].m_iY;
	m_arrBrickUnit[3].m_iX = m_arrBrickUnit[1].m_iX;
	m_arrBrickUnit[3].m_iY = m_arrBrickUnit[1].m_iY + 1;
}

bool CBrickStyle3::rotate()
{
	this->eraseBrick();

	switch (m_iStatus) {
	case 0: // 0 -> 1
		m_arrBrickUnit[0].m_iX = m_arrBrickUnit[1].m_iX;
		m_arrBrickUnit[0].m_iY = m_arrBrickUnit[1].m_iY - 1;
		m_arrBrickUnit[2].m_iX = m_arrBrickUnit[1].m_iX;
		m_arrBrickUnit[2].m_iY = m_arrBrickUnit[1].m_iY + 1;
		m_arrBrickUnit[3].m_iX = m_arrBrickUnit[1].m_iX + 1;
		m_arrBrickUnit[3].m_iY = m_arrBrickUnit[1].m_iY;
		break;
	case 1: // 1 -> 2
		m_arrBrickUnit[0].m_iX = m_arrBrickUnit[1].m_iX - 1;
		m_arrBrickUnit[0].m_iY = m_arrBrickUnit[1].m_iY;
		m_arrBrickUnit[2].m_iX = m_arrBrickUnit[1].m_iX + 1;
		m_arrBrickUnit[2].m_iY = m_arrBrickUnit[1].m_iY;
		m_arrBrickUnit[3].m_iX = m_arrBrickUnit[1].m_iX;
		m_arrBrickUnit[3].m_iY = m_arrBrickUnit[1].m_iY + 1;
		break;
	case 2: // 2 -> 3
		m_arrBrickUnit[0].m_iX = m_arrBrickUnit[1].m_iX;
		m_arrBrickUnit[0].m_iY = m_arrBrickUnit[1].m_iY - 1;
		m_arrBrickUnit[2].m_iX = m_arrBrickUnit[1].m_iX;
		m_arrBrickUnit[2].m_iY = m_arrBrickUnit[1].m_iY + 1;
		m_arrBrickUnit[3].m_iX = m_arrBrickUnit[1].m_iX - 1;
		m_arrBrickUnit[3].m_iY = m_arrBrickUnit[1].m_iY;
		break;
	case 3: // 3 -> 0
		m_arrBrickUnit[0].m_iX = m_arrBrickUnit[1].m_iX - 1;
		m_arrBrickUnit[0].m_iY = m_arrBrickUnit[1].m_iY;
		m_arrBrickUnit[2].m_iX = m_arrBrickUnit[1].m_iX + 1;
		m_arrBrickUnit[2].m_iY = m_arrBrickUnit[1].m_iY;
		m_arrBrickUnit[3].m_iX = m_arrBrickUnit[1].m_iX;
		m_arrBrickUnit[3].m_iY = m_arrBrickUnit[1].m_iY + 1;
		break;
	}
	m_iStatus = (m_iStatus + 1) % 4;
	drawBrick();


	return(true);
}

#include "CBrickStyle4.h"

/*

***
  *

*/


CBrickStyle4::CBrickStyle4(CMainGameArea* pGameArea) : CBrick(pGameArea)
{
	m_arrBrickUnit[0].m_iX = m_arrBrickUnit[1].m_iX - 1;
	m_arrBrickUnit[0].m_iY = m_arrBrickUnit[1].m_iY;
	m_arrBrickUnit[2].m_iX = m_arrBrickUnit[1].m_iX + 1;
	m_arrBrickUnit[2].m_iY = m_arrBrickUnit[1].m_iY;
	m_arrBrickUnit[3].m_iX = m_arrBrickUnit[1].m_iX + 1;
	m_arrBrickUnit[3].m_iY = m_arrBrickUnit[1].m_iY + 1;
}


bool CBrickStyle4::rotate()
{
	eraseBrick();

	switch (m_iStatus) {
	case 0: // 0 -> 1
		m_arrBrickUnit[0].m_iX = m_arrBrickUnit[1].m_iX;
		m_arrBrickUnit[0].m_iY = m_arrBrickUnit[1].m_iY - 1;
		m_arrBrickUnit[2].m_iX = m_arrBrickUnit[1].m_iX;
		m_arrBrickUnit[2].m_iY = m_arrBrickUnit[1].m_iY + 1;
		m_arrBrickUnit[3].m_iX = m_arrBrickUnit[1].m_iX - 1;
		m_arrBrickUnit[3].m_iY = m_arrBrickUnit[1].m_iY + 1;
		break;
	case 1: // 1 -> 2
		m_arrBrickUnit[0].m_iX = m_arrBrickUnit[1].m_iX + 1;
		m_arrBrickUnit[0].m_iY = m_arrBrickUnit[1].m_iY;
		m_arrBrickUnit[2].m_iX = m_arrBrickUnit[1].m_iX - 1;
		m_arrBrickUnit[2].m_iY = m_arrBrickUnit[1].m_iY;
		m_arrBrickUnit[3].m_iX = m_arrBrickUnit[1].m_iX - 1;
		m_arrBrickUnit[3].m_iY = m_arrBrickUnit[1].m_iY - 1;
		break;
	case 2: // 2 -> 3
		m_arrBrickUnit[0].m_iX = m_arrBrickUnit[1].m_iX;
		m_arrBrickUnit[0].m_iY = m_arrBrickUnit[1].m_iY + 1;
		m_arrBrickUnit[2].m_iX = m_arrBrickUnit[1].m_iX;
		m_arrBrickUnit[2].m_iY = m_arrBrickUnit[1].m_iY - 1;
		m_arrBrickUnit[3].m_iX = m_arrBrickUnit[1].m_iX + 1;
		m_arrBrickUnit[3].m_iY = m_arrBrickUnit[1].m_iY - 1;
		break;
	case 3: // 3 -> 1
		m_arrBrickUnit[0].m_iX = m_arrBrickUnit[1].m_iX - 1;
		m_arrBrickUnit[0].m_iY = m_arrBrickUnit[1].m_iY;
		m_arrBrickUnit[2].m_iX = m_arrBrickUnit[1].m_iX + 1;
		m_arrBrickUnit[2].m_iY = m_arrBrickUnit[1].m_iY;
		m_arrBrickUnit[3].m_iX = m_arrBrickUnit[1].m_iX + 1;
		m_arrBrickUnit[3].m_iY = m_arrBrickUnit[1].m_iY + 1;
		break;
	}

	m_iStatus = (m_iStatus + 1) % 4;
	drawBrick();

	return(true);
}


#include "CBrickStyle5.h"

/*

***
*

*/

CBrickStyle5::CBrickStyle5(CMainGameArea* pGameArea) : CBrick(pGameArea)
{
	m_arrBrickUnit[0].m_iX = m_arrBrickUnit[1].m_iX - 1;
	m_arrBrickUnit[0].m_iY = m_arrBrickUnit[1].m_iY;
	m_arrBrickUnit[2].m_iX = m_arrBrickUnit[1].m_iX + 1;
	m_arrBrickUnit[2].m_iY = m_arrBrickUnit[1].m_iY;
	m_arrBrickUnit[3].m_iX = m_arrBrickUnit[1].m_iX - 1;
	m_arrBrickUnit[3].m_iY = m_arrBrickUnit[1].m_iY + 1;
}



bool CBrickStyle5::rotate()
{
	eraseBrick();

	switch (m_iStatus) {
	case 0: // 0 -> 1
		m_arrBrickUnit[0].m_iX = m_arrBrickUnit[1].m_iX;
		m_arrBrickUnit[0].m_iY = m_arrBrickUnit[1].m_iY - 1;
		m_arrBrickUnit[2].m_iX = m_arrBrickUnit[1].m_iX;
		m_arrBrickUnit[2].m_iY = m_arrBrickUnit[1].m_iY + 1;
		m_arrBrickUnit[3].m_iX = m_arrBrickUnit[1].m_iX - 1;
		m_arrBrickUnit[3].m_iY = m_arrBrickUnit[1].m_iY + 1;
		break;
	case 1: // 1 -> 2
		m_arrBrickUnit[0].m_iX = m_arrBrickUnit[1].m_iX + 1;
		m_arrBrickUnit[0].m_iY = m_arrBrickUnit[1].m_iY;
		m_arrBrickUnit[2].m_iX = m_arrBrickUnit[1].m_iX - 1;
		m_arrBrickUnit[2].m_iY = m_arrBrickUnit[1].m_iY;
		m_arrBrickUnit[3].m_iX = m_arrBrickUnit[1].m_iX + 1;
		m_arrBrickUnit[3].m_iY = m_arrBrickUnit[1].m_iY - 1;
		break;
	case 2: // 2 -> 3
		m_arrBrickUnit[0].m_iX = m_arrBrickUnit[1].m_iX;
		m_arrBrickUnit[0].m_iY = m_arrBrickUnit[1].m_iY + 1;
		m_arrBrickUnit[2].m_iX = m_arrBrickUnit[1].m_iX;
		m_arrBrickUnit[2].m_iY = m_arrBrickUnit[1].m_iY - 1;
		m_arrBrickUnit[3].m_iX = m_arrBrickUnit[1].m_iX + 1;
		m_arrBrickUnit[3].m_iY = m_arrBrickUnit[1].m_iY + 1;
		break;
	case 3: // 3 -> 1
		m_arrBrickUnit[0].m_iX = m_arrBrickUnit[1].m_iX - 1;
		m_arrBrickUnit[0].m_iY = m_arrBrickUnit[1].m_iY;
		m_arrBrickUnit[2].m_iX = m_arrBrickUnit[1].m_iX + 1;
		m_arrBrickUnit[2].m_iY = m_arrBrickUnit[1].m_iY;
		m_arrBrickUnit[3].m_iX = m_arrBrickUnit[1].m_iX - 1;
		m_arrBrickUnit[3].m_iY = m_arrBrickUnit[1].m_iY + 1;
		break;
	}

	m_iStatus = (m_iStatus + 1) % 4;
	drawBrick();
	return(true);
}

#include "CBrickStyle6.h"

CBrickStyle6::CBrickStyle6(CMainGameArea* pGameArea) : CBrick(pGameArea)
{
	m_arrBrickUnit[0].m_iX = m_arrBrickUnit[1].m_iX - 1;
	m_arrBrickUnit[0].m_iY = m_arrBrickUnit[1].m_iY;
	m_arrBrickUnit[2].m_iX = m_arrBrickUnit[1].m_iX;
	m_arrBrickUnit[2].m_iY = m_arrBrickUnit[1].m_iY + 1;
	m_arrBrickUnit[3].m_iX = m_arrBrickUnit[1].m_iX + 1;
	m_arrBrickUnit[3].m_iY = m_arrBrickUnit[1].m_iY + 1;
}

/*

**
 **
 
*/

bool CBrickStyle6::rotate()
{
	eraseBrick();

	switch (m_iStatus) {
	case 0: // 0 -> 1
		m_arrBrickUnit[0].m_iX = m_arrBrickUnit[1].m_iX;
		m_arrBrickUnit[0].m_iY = m_arrBrickUnit[1].m_iY - 1;
		m_arrBrickUnit[2].m_iX = m_arrBrickUnit[1].m_iX - 1;
		m_arrBrickUnit[2].m_iY = m_arrBrickUnit[1].m_iY;
		m_arrBrickUnit[3].m_iX = m_arrBrickUnit[1].m_iX - 1;
		m_arrBrickUnit[3].m_iY = m_arrBrickUnit[1].m_iY + 1;
		break;
	case 1: // 1 -> 2
		m_arrBrickUnit[0].m_iX = m_arrBrickUnit[1].m_iX + 1;
		m_arrBrickUnit[0].m_iY = m_arrBrickUnit[1].m_iY;
		m_arrBrickUnit[2].m_iX = m_arrBrickUnit[1].m_iX;
		m_arrBrickUnit[2].m_iY = m_arrBrickUnit[1].m_iY - 1;
		m_arrBrickUnit[3].m_iX = m_arrBrickUnit[1].m_iX - 1;
		m_arrBrickUnit[3].m_iY = m_arrBrickUnit[1].m_iY - 1;
		break;
	case 2: // 2 -> 3
		m_arrBrickUnit[0].m_iX = m_arrBrickUnit[1].m_iX;
		m_arrBrickUnit[0].m_iY = m_arrBrickUnit[1].m_iY + 1;
		m_arrBrickUnit[2].m_iX = m_arrBrickUnit[1].m_iX + 1;
		m_arrBrickUnit[2].m_iY = m_arrBrickUnit[1].m_iY;
		m_arrBrickUnit[3].m_iX = m_arrBrickUnit[1].m_iX + 1;
		m_arrBrickUnit[3].m_iY = m_arrBrickUnit[1].m_iY - 1;
		break;
	case 3: // 3 -> 1
		m_arrBrickUnit[0].m_iX = m_arrBrickUnit[1].m_iX - 1;
		m_arrBrickUnit[0].m_iY = m_arrBrickUnit[1].m_iY;
		m_arrBrickUnit[2].m_iX = m_arrBrickUnit[1].m_iX;
		m_arrBrickUnit[2].m_iY = m_arrBrickUnit[1].m_iY + 1;
		m_arrBrickUnit[3].m_iX = m_arrBrickUnit[1].m_iX + 1;
		m_arrBrickUnit[3].m_iY = m_arrBrickUnit[1].m_iY + 1;
		break;
	}

	m_iStatus = (m_iStatus + 1) % 4;
	drawBrick();
	return(true);
}



#include "CBrickStyle7.h"

CBrickStyle7::CBrickStyle7(CMainGameArea* pGameArea) : CBrick(pGameArea)
{
	m_arrBrickUnit[0].m_iX = m_arrBrickUnit[1].m_iX - 1;
	m_arrBrickUnit[0].m_iY = m_arrBrickUnit[1].m_iY;
	m_arrBrickUnit[2].m_iX = m_arrBrickUnit[1].m_iX;
	m_arrBrickUnit[2].m_iY = m_arrBrickUnit[1].m_iY - 1;
	m_arrBrickUnit[3].m_iX = m_arrBrickUnit[1].m_iX + 1;
	m_arrBrickUnit[3].m_iY = m_arrBrickUnit[1].m_iY - 1;
}


/*

 **
**

*/

bool CBrickStyle7::rotate()
{
	eraseBrick();

	switch (m_iStatus) {
	case 0: // 0 -> 1
		m_arrBrickUnit[0].m_iX = m_arrBrickUnit[1].m_iX;
		m_arrBrickUnit[0].m_iY = m_arrBrickUnit[1].m_iY - 1;
		m_arrBrickUnit[2].m_iX = m_arrBrickUnit[1].m_iX + 1;
		m_arrBrickUnit[2].m_iY = m_arrBrickUnit[1].m_iY;
		m_arrBrickUnit[3].m_iX = m_arrBrickUnit[1].m_iX + 1;
		m_arrBrickUnit[3].m_iY = m_arrBrickUnit[1].m_iY + 1;
		break;
	case 1: // 1 -> 2
		m_arrBrickUnit[0].m_iX = m_arrBrickUnit[1].m_iX + 1;
		m_arrBrickUnit[0].m_iY = m_arrBrickUnit[1].m_iY;
		m_arrBrickUnit[2].m_iX = m_arrBrickUnit[1].m_iX;
		m_arrBrickUnit[2].m_iY = m_arrBrickUnit[1].m_iY + 1;
		m_arrBrickUnit[3].m_iX = m_arrBrickUnit[1].m_iX - 1;
		m_arrBrickUnit[3].m_iY = m_arrBrickUnit[1].m_iY + 1;
		break;
	case 2: // 2 -> 3
		m_arrBrickUnit[0].m_iX = m_arrBrickUnit[1].m_iX;
		m_arrBrickUnit[0].m_iY = m_arrBrickUnit[1].m_iY + 1;
		m_arrBrickUnit[2].m_iX = m_arrBrickUnit[1].m_iX - 1;
		m_arrBrickUnit[2].m_iY = m_arrBrickUnit[1].m_iY;
		m_arrBrickUnit[3].m_iX = m_arrBrickUnit[1].m_iX - 1;
		m_arrBrickUnit[3].m_iY = m_arrBrickUnit[1].m_iY - 1;
		break;
	case 3: // 3 -> 1
		m_arrBrickUnit[0].m_iX = m_arrBrickUnit[1].m_iX - 1;
		m_arrBrickUnit[0].m_iY = m_arrBrickUnit[1].m_iY;
		m_arrBrickUnit[2].m_iX = m_arrBrickUnit[1].m_iX;
		m_arrBrickUnit[2].m_iY = m_arrBrickUnit[1].m_iY - 1;
		m_arrBrickUnit[3].m_iX = m_arrBrickUnit[1].m_iX + 1;
		m_arrBrickUnit[3].m_iY = m_arrBrickUnit[1].m_iY - 1;
		break;
	}

	m_iStatus = (m_iStatus + 1) % 4;
	drawBrick();

	return(true);
}


#include "CBrickUnit.h"
#include "CCommFunc.h"
#include <iostream>

using namespace std;

CBrickUnit::CBrickUnit(char image /*= '*'*/) : m_cImage(image), m_iX(0), m_iY(0)
{

}

void CBrickUnit::drawBrickUnit()
{
	CCommFunc::gotoxy(m_iX, m_iY);
	cout << this->m_cImage;
}

void CBrickUnit::eraseBrickUnit()
{
	CCommFunc::gotoxy(m_iX, m_iY);
	cout << " ";
}




#include "CCommFunc.h"
#include <windows.h>
#include <iostream>
using namespace std;

void CCommFunc::gotoxy(int x, int y)
{
	COORD cd;
	cd.X = x;
	cd.Y = y;

	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), cd);
}


#include "CInfoBoard.h"
#include "CCommFunc.h"
#include <iostream>

using namespace std;

CInfoBoard::CInfoBoard(int offsetX, int offsetY) : m_iOffsetX(offsetX), m_iOffsetY(offsetY)
{

}

void CInfoBoard::drawInfoBoard(int needLayers, int currentLayers)
{
	CCommFunc::gotoxy(this->m_iOffsetX, this->m_iOffsetY);
	cout << "-------------------";
	CCommFunc::gotoxy(this->m_iOffsetX, this->m_iOffsetY + 1);
	cout << "	NEED: " << needLayers << "    ";
	CCommFunc::gotoxy(this->m_iOffsetX, this->m_iOffsetY + 2);
	cout << "	NOW : " << currentLayers << "    ";
	CCommFunc::gotoxy(this->m_iOffsetX, this->m_iOffsetY + 3);
	cout << "-------------------";
}

void CInfoBoard::drawInfoBoard(int needLayers, int currentLayers, int level)
{
	
}

#include "CMainGameArea.h"
#include "CCommFunc.h"
#include <iostream>

using namespace std;

CMainGameArea::CMainGameArea(int offsetX /*= 0*/, int offsetY /*= 0*/) 
	: m_iOffsetX(offsetX), m_iOffsetY(offsetY)
{
	resetGameArea();
}

void CMainGameArea::drawGameArea()
{
	for (int i = 0; i < KROW; ++i) {
		CCommFunc::gotoxy(m_iOffsetX, m_iOffsetY + i);
		cout << "|";
		for (int j = 0; j < KCOL; ++j) {
			cout << " ";
		}
		cout << "|";
	}
	CCommFunc::gotoxy(m_iOffsetX, m_iOffsetY + KROW);
	for (int k = 0; k < KCOL + 2; ++k) {
		cout << "-";
	}
}

void CMainGameArea::drawMatrix()
{
	for (int i = 0; i < KROW; ++i) {
		CCommFunc::gotoxy(m_iOffsetX + 1, m_iOffsetY + i);
		for (int j = 0; j < KCOL; ++j) {
			if (m_arrAreaMatrix[i][j] == 1) {
				cout << "*";
			}
			else
				cout << " ";
		}
	}
}

int CMainGameArea::tryAndCutLayer()
{
	int cutLayers = 0;
	for (int i = 0; i < KROW; ++i) {
		int unitCount = 0;
		for (int j = 0; j < KCOL; ++j) 
			unitCount += this->m_arrAreaMatrix[i][j];
		if (unitCount == KCOL) {
			curLayer(i);
			cutLayers++;
			drawMatrix();
		}
	}

	return(cutLayers);
}

void CMainGameArea::resetGameArea()
{
	for (int i = 0; i < KROW; ++i)
		for (int j = 0; j < KCOL; ++j)
			m_arrAreaMatrix[i][j] = 0;
	drawMatrix();
}

int CMainGameArea::getOffsetX() const
{
	return(m_iOffsetX);
}

int CMainGameArea::getOffsetY() const
{
	return(m_iOffsetY);
}

int CMainGameArea::getMatrixStatus(int row, int col) const
{
	return(this->m_arrAreaMatrix[row][col]);
}

void CMainGameArea::setMatrixStatus(int row, int col, int status) 
{
	this->m_arrAreaMatrix[row][col] = status;
}

void CMainGameArea::curLayer(int row)
{
	int i = row; 
	while (i > 0) {
		for (int k = 0; k < KCOL; ++k) {
			m_arrAreaMatrix[i][k] = m_arrAreaMatrix[i - 1][k];
		}
		--i;
	}
}


#include "CNextBrickBoard.h"
#include "CCommFunc.h"
#include <iostream>

using namespace std;

CNextBrickBoard::CNextBrickBoard(int offsetX, int offsetY) : 
	m_iOffsetX(offsetX), m_iOffsetY(offsetY)
{

}

void CNextBrickBoard::drawNextBrickBoard(int brickIndex)
{
	CCommFunc::gotoxy(this->m_iOffsetX, this->m_iOffsetY);
	cout << "-------------------";

	CCommFunc::gotoxy(this->m_iOffsetX + 8, this->m_iOffsetY + 1);
	cout << "          ";
	CCommFunc::gotoxy(this->m_iOffsetX + 8, this->m_iOffsetY + 2);
	cout << "          ";
	switch (brickIndex) {
	case 0:
		CCommFunc::gotoxy(this->m_iOffsetX + 8, this->m_iOffsetY + 1);
		cout << "**";
		CCommFunc::gotoxy(this->m_iOffsetX + 8, this->m_iOffsetY + 2);
		cout << "**";
		break;
	case 1:
		CCommFunc::gotoxy(this->m_iOffsetX + 8, this->m_iOffsetY + 1);
		cout << "****";
		break;
	case 2:
		CCommFunc::gotoxy(this->m_iOffsetX + 8, this->m_iOffsetY + 1);
		cout << "***";
		CCommFunc::gotoxy(this->m_iOffsetX + 8, this->m_iOffsetY + 2);
		cout << " *";
		break;
	case 3:
		CCommFunc::gotoxy(this->m_iOffsetX + 8, this->m_iOffsetY + 1);
		cout << "***";
		CCommFunc::gotoxy(this->m_iOffsetX + 8, this->m_iOffsetY + 2);
		cout << "  *";
		break;
	case 4:
		CCommFunc::gotoxy(this->m_iOffsetX + 8, this->m_iOffsetY + 1);
		cout << "***";
		CCommFunc::gotoxy(this->m_iOffsetX + 8, this->m_iOffsetY + 2);
		cout << "*";
		break;
	case 5:
		CCommFunc::gotoxy(this->m_iOffsetX + 8, this->m_iOffsetY + 1);
		cout << "**";
		CCommFunc::gotoxy(this->m_iOffsetX + 8, this->m_iOffsetY + 2);
		cout << " **";
		break;
	case 6:
		CCommFunc::gotoxy(this->m_iOffsetX + 8, this->m_iOffsetY + 1);
		cout << " **";
		CCommFunc::gotoxy(this->m_iOffsetX + 8, this->m_iOffsetY + 2);
		cout << "**";
		break;
	}
	CCommFunc::gotoxy(this->m_iOffsetX, this->m_iOffsetY + 3);
	cout << "-------------------";
}


#include "CTetrisGame.h"
#include "CBrickStyle1.h"
#include "CBrickStyle2.h"
#include "CBrickStyle3.h"
#include "CBrickStyle4.h"
#include "CBrickStyle5.h"
#include "CBrickStyle6.h"
#include "CBrickStyle7.h"
#include <ctime>
#include <cstdlib>
#include <windows.h>
#include <conio.h>

#define KLAYERS_PER_LEVEL 10

CTetrisGame::CTetrisGame() : m_iLayerCount(0), m_iSpeed(1000), m_iLevel(1)
{
	setGameArea();
}

void CTetrisGame::run()
{
	CBrick* pBrick = NULL;
	static int brickIndex = 0;
	pBrick = createNewBrick(brickIndex);
	m_pNextBrickBoard->drawNextBrickBoard(brickIndex);
	pBrick->drawBrick();
	char key = 0;
	while (key != 0x1b) { // 按下的不是ESC
		// 暂停功能
		if (key == ' ') {
			key = _getch();
			while (key != ' ') 
				key = _getch();
		}
		while (!_kbhit()) {
			if (!pBrick->moveDown()) {
				pBrick->setGameAreaMatrix();
				delete pBrick;
				pBrick = NULL;
				// 检查是否需要消层,如果要则消层刷新
				m_iLayerCount += m_pGameArea->tryAndCutLayer();
				// 判断是否可以到下关
				if (m_iLayerCount >= m_iLevel * KLAYERS_PER_LEVEL) {
					// 当前关卡数增加
					m_iLevel++;
					// 重新设置主游戏区
					m_pGameArea->resetGameArea();
				}
				// 检查层高是否导致输掉游戏

				// 刷新信息面板
				m_pInfoBoard->drawInfoBoard(m_iLevel * KLAYERS_PER_LEVEL, m_iLayerCount);
				// 刷新下一块砖的浏览面板
			
				pBrick = createNewBrick(brickIndex);
				m_pNextBrickBoard->drawNextBrickBoard(brickIndex);

				pBrick->drawBrick();
			}
			Sleep(500);
		}
		key = _getch();
		switch (key) {
			// 变形
		case 'w':
			pBrick->rotate();
			break;
			// 下降
		case 's':
			pBrick->moveDown();
			break;
			// 向左
		case 'a':
			pBrick->moveLeft();
			break;
			// 向右
		case 'd':
			pBrick->moveRight();
			break;
		default:
			break;
		}
	}
}

void CTetrisGame::setGameArea()
{
	m_pGameArea = new CMainGameArea(50, 0);
	m_pGameArea->drawGameArea();

	m_pInfoBoard = new CInfoBoard(15, 13);
	m_pInfoBoard->drawInfoBoard(m_iLevel * KLAYERS_PER_LEVEL, m_iLayerCount);

	m_pNextBrickBoard = new CNextBrickBoard(15, 4);
	m_pNextBrickBoard->drawNextBrickBoard(0);
}


CBrick *CTetrisGame::createNewBrick(int& brickIndex)
{
	srand((unsigned)time(NULL));
	switch (brickIndex) {	
	case 0:
		brickIndex = rand() % 7;
		return(new CBrickStyle1(m_pGameArea));
	case 1:
		brickIndex = rand() % 7;
		return(new CBrickStyle2(m_pGameArea));
	case 2:
		brickIndex = rand() % 7;
		return(new CBrickStyle3(m_pGameArea));
	case 3:
		brickIndex = rand() % 7;
		return(new CBrickStyle4(m_pGameArea));
	case 4:
		brickIndex = rand() % 7;
		return(new CBrickStyle5(m_pGameArea));
	case 5:
		brickIndex = rand() % 7;
		return(new CBrickStyle6(m_pGameArea));
	case 6:
		brickIndex = rand() % 7;
		return(new CBrickStyle7(m_pGameArea));
	}
	
	return(NULL); // 不可能的情况
}


#include <iostream>
#include "CInfoBoard.h"
#include "CNextBrickBoard.h"
#include "CMainGameArea.h"
#include "CTetrisGame.h"
#include "CBrickStyle1.h"
#include "CBrickStyle2.h"
#include "CBrickStyle3.h"
#include "CBrickStyle4.h"
#include "CBrickStyle5.h"
#include "CBrickStyle6.h"
#include "CBrickStyle7.h"
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <conio.h>

int main() {
	CTetrisGame* pGame = new CTetrisGame;

	pGame->run();

	getchar();
	
	return(0);
}

(完)

 

 

 

 

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值