提交源码

编译环境 MinGW gcc 7.2.0
This commit is contained in:
筱傑
2018-09-24 13:05:24 +08:00
committed by GitHub
parent 3ae470b557
commit 30fd245e7e
5 changed files with 393 additions and 0 deletions

287
Tetris.cpp Normal file
View File

@@ -0,0 +1,287 @@
/* Tetris.cpp -- file */
#include "Tetris.h"
bool printNextBoxVal = true; // <20>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
bool printMapVal = true; // <20>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD>µ<EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
bool isGameOver = false; // <20>Ƿ<EFBFBD><C7B7><EFBFBD>Ϸʧ<CFB7><CAA7>
char Map[mapWidth][mapHeight] = {0};
int speed = 400;
HANDLE hStdOut;
Box thisBox, nextBox;
// <20><><EFBFBD><EFBFBD><EFBFBD>÷<EFBFBD><C3B7><EFBFBD><EFBFBD>ڵ<EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>
bool isFeasible(const Box &target)
{
for(int YOffset = 0; YOffset < 4; ++YOffset)
{
for(int XOffset = 0; XOffset < 4; ++XOffset)
{
if(target.getShape() & (0x8000 >> (YOffset*4 + XOffset)))
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>Խ<EFBFBD><D4BD> <20><><EFBFBD><EFBFBD>false
if(target.x + XOffset < 0 || target.x + XOffset >= mapWidth
|| target.y + YOffset < 0 || target.y + YOffset >= mapHeight)
return false;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE>з<EFBFBD><D0B7><EFBFBD>
if(Map[target.x + XOffset][target.y + YOffset])
return false;
}
}
}
return true;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̶<EFBFBD><CCB6>ڵ<EFBFBD>ͼ<EFBFBD><CDBC>
void fixedPos(const Box &target)
{
for(int YOffset = 0; YOffset < 4; ++YOffset)
{
for(int XOffset = 0; XOffset < 4; ++XOffset)
{
// <20><><EFBFBD><EFBFBD><EFBFBD>жϵ<D0B6>λ<EFBFBD><CEBB>Խ<EFBFBD><D4BD>
if(target.x + XOffset < 0 || target.x + XOffset >= mapWidth
|| target.y + YOffset < 0 || target.y + YOffset >= mapHeight)
continue;
if(target.getShape() & (0x8000 >> (YOffset*4 + XOffset)))
{
Map[target.x + XOffset][target.y + YOffset] = 1;
clearCompleted();
}
}
}
}
bool move(Box &A, char XOffset, char YOffset)
{
char oldX = A.x, oldY = A.y;
printBox(A, " ");
A.x += XOffset, A.y += YOffset;
if(!isFeasible(A))
{
A.x = oldX, A.y = oldY;
printBox(A, "<EFBFBD><EFBFBD>");
if(YOffset > 0){ // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
fixedPos(A);
A = nextBox;
printNextBoxVal = true; // ֪ͨ <20><>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if(!isFeasible(A)) // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɵķ<C9B5><C4B7><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE>з<EFBFBD><D0B7><EFBFBD>ж<EFBFBD><D0B6><EFBFBD>Ϸʧ<CFB7><CAA7>
{
isGameOver = true;
}
}
return false;
}
printBox(A, "<EFBFBD><EFBFBD>");
return true;
}
bool rotate(Box &A)
{
char oldDir = A.dir;
A.dir = (A.dir + 1) % 4;
if(!isFeasible(A))
{
A.dir = oldDir;
return false;
}
A.dir = oldDir;
printBox(A, " ");
A.dir = (A.dir + 1) % 4;
printBox(A, "<EFBFBD><EFBFBD>");
return true;
}
void clearCompleted()
{
for(int y = mapHeight-1, x = 0; y >= 0; )
{
for(x = 0; x < mapWidth; ++x)
{
if(!Map[x][y])
break;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if(x == mapWidth)
{
// <20>Ѹò<D1B8><C3B2><EFBFBD><EFBFBD>ϵ<EFBFBD><CFB5><EFBFBD><EFBFBD>з<EFBFBD><D0B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƶ<EFBFBD>һ<EFBFBD><D2BB>
for(int j = y; j > 0; --j)
{
for(int i = 0; i < mapWidth; ++i)
{
Map[i][j] = Map[i][j-1];
}
}
// <20><><EFBFBD>ն<EFBFBD><D5B6><EFBFBD>
for(int i = 0; i < mapWidth; ++i)
Map[i][0] = 0;
if(speed > 200)
speed -= 10;
printMapVal = true; // ֪ͨ<CDA8><D6AA><EFBFBD>µ<EFBFBD>ͼ
}else{ //δ<><CEB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͽ<EFBFBD><CDBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϼ<EFBFBD><CFBC><EFBFBD>
--y;
}
}
}
void restart()
{
for(int i = 0; i < mapWidth; ++i)
for(int j = 0; j < mapHeight; ++j)
Map[i][j] = 0;
printMapVal = true;
thisBox.randGenerateNewBox();
printNextBoxVal = true;
speed = 400;
isGameOver = false;
}
void printXY(COORD coord, std::string str)
{
SetConsoleCursorPosition(hStdOut, coord);
WriteConsole(hStdOut, str.c_str(), str.length(), NULL, NULL);
}
// <20><>ָ<EFBFBD><D6B8>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>飬x,yȱʡΪ0<CEAA><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ0<CEAA><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Box<6F><78><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void printBox(const Box &target, std::string printChar, short x, short y)
{
short posX = x?x:target.x * 2 + 2; // +2<><32><EFBFBD><EFBFBD>Ϊ<EFBFBD>߿<EFBFBD>ռ<EFBFBD><D5BC>2<EFBFBD><32><EFBFBD><EFBFBD>
short posY = y?y:target.y;
for(int YOffset = 0; YOffset < 4; ++YOffset)
{
for(int XOffset = 0; XOffset < 4; ++XOffset)
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD>ò<EFBFBD><C3B2>Ϸ<EFBFBD>
if(posX + XOffset < 0 || posY + YOffset < 0)
continue;
if(target.getShape() & (0x8000 >> (YOffset*4 + XOffset)))
printXY({posX + XOffset*2, posY + YOffset}, printChar);
}
}
}
void showMap(short _x, short _y)
{
for(short x = 0; x <= mapWidth+1; ++x)
{
printXY({_x + x*2, _y + mapHeight}, "<EFBFBD><EFBFBD>");
}
for(short y = 0; y < mapHeight; ++y)
{
printXY({_x, _y + y}, "<EFBFBD><EFBFBD>");
printXY({_x + mapWidth * 2 + 2, _y + y}, "<EFBFBD><EFBFBD>");
for(short x = 0; x < mapWidth; ++x)
{
printXY({_x + 2 + x*2, _y + y}, (Map[x][y] ? "<EFBFBD><EFBFBD>" : " "));
}
}
}
void input()
{
char tempPos = 0;
switch(getch())
{
case 'w':
case 'W':
rotate(thisBox);
break;
case 'a':
case 'A':
move(thisBox, -1, 0);
break;
case 'd':
case 'D':
move(thisBox, 1, 0);
break;
case 's':
case 'S':
move(thisBox, 0, 1);
break;
case ' ':
while(move(thisBox, 0, 1));
break;
case 'z':
case 'Z':
for(int i = 0; i < mapWidth; ++i)
Map[i][mapHeight-1] = 1;
clearCompleted();
break;
case 'r':
case 'R':
restart();
break;
case '\n':
case '\r':
printXY({30, 14}, "<EFBFBD><EFBFBD>ͣ<EFBFBD><EFBFBD>...");
printXY({30, 15}, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
getch();
printXY({30, 14}, " ");
printXY({30, 15}, " ");
break;
case 'q':
case 'Q':
exit(1);
break;
}
}
void GameLoop()
{
thisBox.randGenerateNewBox();
nextBox.randGenerateNewBox();
system("cls");
printXY({30, 5}, "w <20><>ת");
printXY({30, 6}, "s <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>");
printXY({30, 7}, "a <20><><EFBFBD><EFBFBD> d <20><><EFBFBD><EFBFBD>");
printXY({30, 8}, "<EFBFBD>ո<EFBFBD> ֱ<><D6B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
printXY({30, 9}, "r <20><><EFBFBD>¿<EFBFBD>ʼ");
printXY({30, 10}, "<EFBFBD>س<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͣ");
printXY({30, 11}, "q <20>˳<EFBFBD>");
while(!isGameOver)
{
if(printMapVal)
{
showMap(0, 0);
printMapVal = false;
}
if(printNextBoxVal)
{
printXY({30, 0}, "next:");
printBox(nextBox, " ", 30, 1);
nextBox.randGenerateNewBox();
printBox(nextBox, "<EFBFBD><EFBFBD>", 30, 1);
printNextBoxVal = false;
}
printBox(thisBox, "<EFBFBD><EFBFBD>");
move(thisBox, 0, 1);
while(kbhit())
input();
if(isGameOver)
{
printXY({6, 10}, "<EFBFBD><EFBFBD>Ϸ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
printXY({4, 11}, "<EFBFBD><EFBFBD><EFBFBD>¿<EFBFBD>ʼ<EFBFBD>밴R");
char ch = getch();
if(ch == 'r' || ch == 'R')
restart();
}
Sleep(speed);
}
}
int main()
{
hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
srand(std::time(NULL));
GameLoop();
return 0;
}