因为最近在学习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);
}
(完)