#include <iostream> #include <windows.h> #include <vector> #include <mmsystem.h> #pragma comment(lib, "winmm.lib") using namespace std; #define GameW 10 #define GameH 20 const int CtrlLeft = GameW\*2+4 + 3; struct Point { Point(){} Point(int x, int y) {\_x = x, \_y = y;} int \_x, \_y; }; HANDLE g\_hOutput = GetStdHandle(STD\_OUTPUT\_HANDLE); HANDLE g\_hInput = GetStdHandle(STD\_INPUT\_HANDLE); Point g\_ptCursor(0,0); BOOL isChecking = FALSE; BOOL g\_bGameOver = FALSE; int g\_nGameBack[GameH][GameW], Case; int nowKeyInfo = -1; int g\_nDiff = 1; int g\_nLife = 2; int g\_nScore = 0; void SetCursor(COORD cd) { SetConsoleCursorPosition(g\_hOutput, cd); } void SetCursor(int x, int y){ COORD cd = {x, y}; SetCursor(cd); } void SetBlockCursor(int x, int y){ COORD cd = {2\*x + 2, y + 1}; SetCursor(cd); } void SetBack(int x, int y, BOOL bk) { SetBlockCursor(x, y); if (bk) printf("%s", "■"); else printf(" "); } bool Out(int x, int y) { return x < 0 || y < 0 || x >= GameW || y >= GameH; } struct xBlock { public: int len; int nowRotateID; BOOL mask[4][4][4]; static vector <xBlock> List; xBlock() { len = 0; } xBlock(int l, char \*str) { int i, j, k; len = l; memset(mask, FALSE, sizeof(mask)); for(i = 0; i < l; i++) { for(j = 0; j < l; j++) { mask[0][i][j] = str[i\*l + j] - '0'; } } for(k = 1; k < 4; k++) { for(i = 0; i < len; i++) { for(j = 0; j < len; j++) { mask[k][i][j] = mask[k-1][j][len-1-i]; } } } nowRotateID = rand() % 4; } void rotate() { nowRotateID ++; if (nowRotateID >= 4) nowRotateID = 0; } BOOL getUnit(int x, int y, int roID) { if (roID == -1) { roID = nowRotateID; } return mask[roID][y][x]; } }; vector <xBlock> xBlock::List; class Block { public: int x, y; int ID; xBlock bk; void reset(xBlock \*pbk) { bk = \*pbk; x = 4, y = 0; ID = ++ Case; if(collide(0,0)) { lifeDown(); } draw(); \*pbk = xBlock::List[rand() % xBlock::List.size()]; } void lifeDown() { int i, j; for(i = 0; i < GameH; i++) { for(j = 0; j < GameW; j++) { SetBack(j, i, TRUE); Sleep(10); } } if(g\_nLife) { g\_nLife --; for(i = g\_nLife; i < 6; i++) { SetCursor(CtrlLeft + i, 15); printf("%c", ' '); } for(i = GameH-1; i >= 0; i--) { for(j = GameW-1; j >= 0; j--) { SetBack(j, i, FALSE); Sleep(10); g\_nGameBack[i][j] = 0; } } }else { g\_bGameOver = TRUE; } } void erase() { int i, j; for(i = 0; i < bk.len; i++) { for(j = 0; j < bk.len; j++) { if (bk.getUnit(j, i, -1)) { if(!Out(j+x, i+y) && g\_nGameBack[i+y][j+x]) { SetBack(j+x, i+y, FALSE); g\_nGameBack[i+y][j+x] = 0; } } } } } void draw() { int i, j; for(i = 0; i < bk.len; i++) { for(j = 0; j < bk.len; j++) { if (bk.getUnit(j, i, -1)) { if(!Out(j+x, i+y) && !g\_nGameBack[i+y][j+x]) { SetBack(j+x, i+y, TRUE); g\_nGameBack[i+y][j+x] = ID; } } } } } void draw(int x, int y) { int i, j; for(i = 0; i < 4; i++) { for(j = 0; j < 4; j++) { SetCursor(x + 2\*j, y + i); if (bk.getUnit(j, i, -1)) { printf("%s", "■"); }else printf(" "); } } } bool collide(int dx, int dy, int roID = -1) { int i, j; for(i = 0; i < bk.len; i++) { for(j = 0; j < bk.len; j++) { if (bk.getUnit(j, i, roID)) { Point ptPos(j + x + dx, i + y + dy); if(Out(ptPos.\_x, ptPos.\_y) || g\_nGameBack[ptPos.\_y][ptPos.\_x] && ID != g\_nGameBack[ptPos.\_y][ptPos.\_x]) { return TRUE; } } } } return FALSE; } void rotate(int nTimes = 1) { int nextro = (bk.nowRotateID + nTimes) % 4; if(collide(0, 0, nextro)) { return ; } Beep(12000, 50); erase(); bk.nowRotateID = nextro; draw(); } BOOL changepos(int dx, int dy) { if(collide(dx, dy)) { return FALSE; } erase(); x += dx; y += dy; draw(); return TRUE; } }; void GameInit() { CONSOLE\_CURSOR\_INFO cursor\_info; cursor\_info.bVisible = FALSE; cursor\_info.dwSize = 100; SetConsoleCursorInfo(g\_hOutput, &cursor\_info); xBlock::List.push\_back(xBlock(3, "010111000")); xBlock::List.push\_back(xBlock(3, "110110000")); xBlock::List.push\_back(xBlock(3, "111001000")); xBlock::List.push\_back(xBlock(3, "111100000")); xBlock::List.push\_back(xBlock(3, "110011000")); xBlock::List.push\_back(xBlock(3, "011110000")); xBlock::List.push\_back(xBlock(4, "1000100010001000")); } void DrawFrame(int x, int y, int nWidth, int nHeight) { int i; for(i = 0; i < nWidth; i++) { SetCursor(x + 2\*i + 2, y); printf("%s", "一"); SetCursor(x + 2\*i + 2, y + nHeight+1); printf("%s", "┄"); } for(i = 0; i < nHeight; i++) { SetCursor(x, y + i + 1); printf("%s", "┆"); SetCursor(x + nWidth\*2+2, y + i + 1); printf("%s", "┆"); } SetCursor(x, y); printf("%s", "┌"); SetCursor(x, y + nHeight+1); printf("%s", "└"); SetCursor(x + nWidth\*2+2, y); printf("%s", "┐"); SetCursor(x + nWidth\*2+2, y + nHeight+1); printf("%s", "┘"); } void MissionInit() { memset(g\_nGameBack, FALSE, sizeof(g\_nGameBack)); Case = 1; int i; DrawFrame(0, 0, GameW, GameH); DrawFrame(GameW\*2+4, 0, 4, GameH); SetCursor(CtrlLeft, 2); printf("Next"); SetCursor(CtrlLeft, 8); printf("Speed"); for(i = 0; i < g\_nDiff; i++) { SetCursor(CtrlLeft + i, 9); printf("%c", 1); } SetCursor(CtrlLeft, 11); printf("Score"); SetCursor(CtrlLeft, 12); printf("%d", g\_nScore); SetCursor(CtrlLeft, 14); printf("Life"); for(i = 0; i < g\_nLife; i++) { SetCursor(CtrlLeft + i, 15); printf("%c", 3); } SetCursor(CtrlLeft-1, 19); printf("@Metaphu"); SetCursor(CtrlLeft-1, 20); printf("Revised"); } void Check() { isChecking = TRUE; int i, j, k; vector <int> line; for(i = 0; i < GameH; i++) { for(j = 0; j < GameW; j++) { if(!g\_nGameBack[i][j]) break; } if(j == GameW) { line.push\_back(i); } } if(line.size()) { int nCount = 7; while(nCount --) { for(i = 0; i < line.size(); i++) { for(j = 0; j < GameW; j++) { SetBack(j, line[i], nCount&1); } } Sleep(70); } for(i = 0; i < line.size(); i++) { for(j = 0; j < GameW; j++) { g\_nGameBack[line[i]][j] = 0; } } for(i = 0; i < GameW; i++) { int next = GameH-1; for(j = GameH-1; j >= 0; j--) { for(k = next; k >= 0; k--) { if(g\_nGameBack[k][i]) break; } next = k - 1; BOOL is = (k >= 0); SetBack(i, j, is); g\_nGameBack[j][i] = is; } } g\_nScore += 2\*line.size()-1; SetCursor(CtrlLeft, 12); printf("%d", g\_nScore); if( g\_nScore >= g\_nDiff \* g\_nDiff \* 10) { if(g\_nDiff <= 6) g\_nDiff ++; } if( g\_nScore >= 50 \* (g\_nLife+1)) { if(g\_nLife <= 6) g\_nLife ++; } } isChecking = FALSE; } int main() { Block\* obj = new Block(); Block\* buf = new Block(); BOOL bCreateNew = FALSE; int nTimer = GetTickCount(); int LastKeyDownTime = GetTickCount(); GameInit(); MissionInit(); buf->bk = xBlock::List[rand() % xBlock::List.size()]; while(1) { if(!bCreateNew) { bCreateNew = TRUE; obj->reset(&buf->bk); if(g\_bGameOver) break; buf->draw(CtrlLeft - 1, 4); } if (GetTickCount() - nTimer >= 1000 / g\_nDiff) { nTimer = GetTickCount(); if (!obj->collide(0, 1)) obj->changepos(0, 1); else { Check(); bCreateNew = FALSE; } } if (GetTickCount() - LastKeyDownTime >= 100) { if(FALSE == isChecking) { LastKeyDownTime = GetTickCount(); if (GetAsyncKeyState(VK\_UP)) { obj->rotate(); } if (GetAsyncKeyState(VK\_LEFT)) { obj->changepos(-1, 0); } if (GetAsyncKeyState(VK\_RIGHT)) { obj->changepos(1, 0); } if (GetAsyncKeyState(VK\_DOWN)) { if( FALSE == obj->changepos(0, 2) ) obj->changepos(0, 1); } } } } SetCursor(8, 10); printf("Game Over"); SetCursor(0, GameH+3); printf("按ESC键退出游戏"); while(1) { if (GetAsyncKeyState(VK\_ESCAPE)) break; } return 0; }