Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- #include <string>
- #include <random>
- #include <Windows.h>
- using namespace std;
- const vector<vector<wstring>> tetromino = {
- // I
- {
- L"....XX......XX......XX......XX..", // 0 deg
- L"................XXXXXXXX........", // 90 deg
- L"..XX......XX......XX......XX....", // 180 deg
- L"........XXXXXXXX................" // 270 deg
- },
- // J
- {
- L"....XX......XX....XXXX..........",
- L"..........XX......XXXXXX........",
- L"..........XXXX....XX......XX....",
- L"........XXXXXX......XX.........."
- },
- // L
- {
- L"..XX......XX......XXXX..........",
- L"..........XXXXXX..XX............",
- L"..........XXXX......XX......XX..",
- L"............XX..XXXXXX.........."
- },
- // O
- {
- L"..........XXXX....XXXX..........",
- L"..........XXXX....XXXX..........",
- L"..........XXXX....XXXX..........",
- L"..........XXXX....XXXX.........."
- },
- // S
- {
- L"..XX......XXXX......XX..........",
- L"............XXXX..XXXX..........",
- L"..........XX......XXXX......XX..",
- L"..........XXXX..XXXX............"
- },
- // T
- {
- L"..XX......XXXX....XX............",
- L"..........XXXXXX....XX..........",
- L"............XX....XXXX......XX..",
- L"..........XX....XXXXXX.........."
- },
- // Z
- {
- L"....XX....XXXX....XX............",
- L"..........XXXX......XXXX........",
- L"............XX....XXXX....XX....",
- L"........XXXX......XXXX.........."
- }
- };
- const int nScreenWidth = 39;
- const int nScreenHeight = 21;
- const int nBoardWidth = 22;
- const int nBoardHeight = 21;
- const wstring detail = L" ▓█░╚╝║═";
- int random(int nMin, int nMax)
- {
- random_device rd;
- mt19937 rng(rd());
- uniform_int_distribution<int> uni(nMin, nMax);
- auto num = uni(rng);
- return num;
- }
- void Configure()
- {
- system("MODE 39, 22");
- system("color 89");
- HANDLE hConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
- CONSOLE_SCREEN_BUFFER_INFOEX csbiex;
- csbiex.cbSize = sizeof(CONSOLE_SCREEN_BUFFER_INFOEX);
- GetConsoleScreenBufferInfoEx(hConsoleOutput, &csbiex);
- csbiex.ColorTable[0] = RGB(0, 188, 212);
- csbiex.ColorTable[1] = RGB(63, 81, 181);
- csbiex.ColorTable[2] = RGB(255, 87, 34);
- csbiex.ColorTable[3] = RGB(255, 235, 59);
- csbiex.ColorTable[4] = RGB(76, 175, 80);
- csbiex.ColorTable[5] = RGB(156, 39, 176);
- csbiex.ColorTable[6] = RGB(237, 28, 36);
- csbiex.ColorTable[7] = RGB(242, 242, 242);
- csbiex.ColorTable[8] = RGB(248, 248, 248);
- csbiex.ColorTable[9] = RGB(20, 20, 20);
- SetConsoleScreenBufferInfoEx(hConsoleOutput, &csbiex);
- }
- void Frame(wchar_t*& wcBuffer, wstring wsCaption, int nWidth, int nHeight, int nPosX, int nPosY)
- {
- for (int i = nPosX; i < nWidth + nPosX; i++)
- {
- for (int j = nPosY; j < nHeight + nPosY; j++)
- {
- if (i == nPosX)
- {
- if (j == nPosY)
- {
- wcBuffer[j * nScreenWidth + i] = L'╔';
- }
- else if (j == nHeight + nPosY - 1)
- {
- wcBuffer[j * nScreenWidth + i] = L'╚';
- }
- else
- {
- wcBuffer[j * nScreenWidth + i] = L'║';
- }
- }
- else if (i == nWidth + nPosX - 1)
- {
- if (j == nPosY)
- {
- wcBuffer[j * nScreenWidth + i] = L'╗';
- }
- else if (j == nHeight + nPosY - 1)
- {
- wcBuffer[j * nScreenWidth + i] = L'╝';
- }
- else
- {
- wcBuffer[j * nScreenWidth + i] = L'║';
- }
- }
- else
- {
- if (j == nPosY || j == nHeight + nPosY - 1)
- {
- wcBuffer[j * nScreenWidth + i] = L'═';
- }
- else
- {
- wcBuffer[j * nScreenWidth + i] = L' ';
- }
- }
- }
- }
- int CapIndex = nPosY * nScreenWidth + (nPosX + 1);
- for (int i = 0; i < wsCaption.length(); i++, CapIndex++)
- {
- wcBuffer[CapIndex] = wsCaption.at(i);
- }
- }
- void Block(wchar_t*& pBuffer, WORD*& pColor, int nTetromino, int nPosX, int nPosY)
- {
- for (int j = 0; j < 4; j++)
- {
- for (int i = 0; i < 8; i++)
- {
- if (tetromino.at(nTetromino).at(0).at(j * 8 + i) != L'.')
- {
- pBuffer[(nPosY + j) * nScreenWidth + (nPosX + i)] = L'▓';
- }
- else
- {
- pBuffer[(nPosY + j) * nScreenWidth + (nPosX + i)] = L' ';
- }
- pColor[(nPosY + j) * nScreenWidth + (nPosX + i)] = 8 * 16 + nTetromino;
- }
- }
- }
- void Text(wchar_t*& pBuffer, wstring content, int nPosX, int nPosY)
- {
- for (int i = 0; i < content.length(); i++, nPosX++)
- {
- pBuffer[nPosY * nScreenWidth + nPosX] = content.at(i);
- }
- }
- bool CheckPiece(int*& pMatrix, int nTetromino, int nRotation, int nPosX, int nPosY)
- {
- for (int i = 0; i < 8; i++)
- {
- for (int j = 0; j < 4; j++)
- {
- if (nPosX + i >= 0 && nPosX + i < nBoardWidth)
- {
- if (nPosY + j >= 0 && nPosY + j < nBoardHeight)
- {
- if (tetromino.at(nTetromino).at(nRotation).at(j * 8 + i) != L'.' && pMatrix[(nPosY + j) * nBoardWidth + (nPosX + i)] != 0)
- {
- return 0;
- }
- }
- }
- }
- }
- return 1;
- }
- int main()
- {
- Configure();
- WORD* pColor = new WORD[nScreenWidth * nScreenHeight];
- wchar_t* pBuffer = new wchar_t[nScreenWidth * nScreenHeight];
- for (int i = 0; i < nScreenWidth; i++)
- {
- for (int j = 0; j < nScreenHeight; j++)
- {
- pBuffer[j * nScreenWidth + i] = L' ';
- if (i == 0 || i >= nBoardWidth - 1 || j == nBoardHeight - 1)
- {
- pColor[j * nScreenWidth + i] = 8 * 16 + 9;
- }
- else
- {
- if (j % 2 == 1)
- {
- if (i % 4 == 1 || i % 4 == 2)
- {
- pColor[j * nScreenWidth + i] = 8 * 16 + 9;
- }
- else
- {
- pColor[j * nScreenWidth + i] = 7 * 16 + 9;
- }
- }
- else
- {
- if (i % 4 == 3 || i % 4 == 0)
- {
- pColor[j * nScreenWidth + i] = 8 * 16 + 9;
- }
- else
- {
- pColor[j * nScreenWidth + i] = 7 * 16 + 9;
- }
- }
- }
- }
- }
- int* pMatrix = new int[nBoardWidth * nBoardHeight];
- for (int i = 0; i < nBoardWidth; i++)
- {
- for (int j = 0; j < nBoardHeight; j++)
- {
- if (j == nBoardHeight - 1)
- {
- if (i == 0)
- {
- pMatrix[j * nBoardWidth + i] = 4;
- }
- else if (i == nBoardWidth - 1)
- {
- pMatrix[j * nBoardWidth + i] = 5;
- }
- else
- {
- pMatrix[j * nBoardWidth + i] = 7;
- }
- }
- else
- {
- if (i == 0 || i == nBoardWidth - 1)
- {
- pMatrix[j * nBoardWidth + i] = 6;
- }
- else
- {
- pMatrix[j * nBoardWidth + i] = 0;
- }
- }
- }
- }
- HANDLE hConsole = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
- SetConsoleActiveScreenBuffer(hConsole);
- DWORD dwBytesWritten = 0;
- Frame(pBuffer, L"[ SCORE ]", 17, 3, nBoardWidth, 1);
- Frame(pBuffer, L"[ LINE ]", 17, 3, nBoardWidth, 4);
- Frame(pBuffer, L"[ NEXT ]", 17, 6, nBoardWidth, 7);
- const vector<char> key = { 'W', 'A', 'S', 'D' };
- bool bKey[4];
- int nCurrentPiece = random(0, 6);
- int nNextPiece = random(0, 6);
- int nCurrentRotation = 0;
- int nCurrentX = nBoardWidth / 2 - 4;
- int nCurrentY = 0;
- int nFrame = 10;
- int nFrameCount = 0;
- bool bForceDown = 0;
- bool bRotateHold = 1;
- int nScore = 0;
- int nScorePosX = 37;
- int nScoreComp = 10;
- int nLine = 0;
- int nLinePosX = 37;
- int nLineComp = 10;
- vector<int> vLines;
- bool bGameOver = 0;
- while (bGameOver != 1)
- {
- // GAME TIMING
- Sleep(75);
- nFrameCount++;
- if (nFrameCount == nFrame)
- {
- bForceDown = 1;
- }
- else
- {
- bForceDown = 0;
- }
- // INPUT
- for (int i = 0; i < key.size(); i++)
- {
- if ((GetKeyState(key.at(i)) & 0x8000) != 0)
- {
- bKey[i] = 1;
- }
- else
- {
- bKey[i] = 0;
- }
- }
- // GAME LOGIC
- int nLimit = 0;
- if (nCurrentPiece == 3)
- {
- nLimit = -1;
- }
- if (bKey[3] == 1 && nCurrentY >= nLimit)
- {
- if (CheckPiece(pMatrix, nCurrentPiece, nCurrentRotation, nCurrentX + 2, nCurrentY) == 1)
- {
- nCurrentX += 2;
- }
- }
- if (bKey[1] == 1 && nCurrentY >= nLimit && CheckPiece(pMatrix, nCurrentPiece, nCurrentRotation, nCurrentX - 2, nCurrentY) == 1)
- {
- nCurrentX -= 2;
- }
- if (bKey[2] == 1 && nCurrentY >= nLimit)
- {
- int i{};
- while (CheckPiece(pMatrix, nCurrentPiece, nCurrentRotation, nCurrentX, nCurrentY + i) == 1)
- {
- i++;
- }
- nCurrentY += i - 1;
- }
- if (bKey[0] == 1 && nCurrentY >= nLimit && bRotateHold == 1 && CheckPiece(pMatrix, nCurrentPiece, (nCurrentRotation + 1) % 4, nCurrentX, nCurrentY) == 1)
- {
- nCurrentRotation++;
- nCurrentRotation %= 4;
- bRotateHold = 0;
- }
- else
- {
- bRotateHold = 1;
- }
- if (bForceDown == 1)
- {
- nFrameCount = 0;
- if (CheckPiece(pMatrix, nCurrentPiece, nCurrentRotation, nCurrentX, nCurrentY + 1))
- {
- nCurrentY++;
- }
- else
- {
- if (nCurrentY < nLimit)
- {
- bGameOver = 1;
- break;
- }
- else
- {
- for (int i = 0; i < 8; i++)
- {
- for (int j = 0; j < 4; j++)
- {
- if (nCurrentY >= 0 && tetromino.at(nCurrentPiece).at(nCurrentRotation).at(j * 8 + i) != L'.')
- {
- pMatrix[(nCurrentY + j) * nBoardWidth + (nCurrentX + i)] = 2;
- if ((nCurrentY + j) % 2 == 1)
- {
- if ((nCurrentX + i) % 4 == 1 || (nCurrentX + i) % 4 == 2)
- {
- pColor[(nCurrentY + j) * nScreenWidth + (nCurrentX + i)] = 8 * 16 + nCurrentPiece;
- }
- else
- {
- pColor[(nCurrentY + j) * nScreenWidth + (nCurrentX + i)] = 7 * 16 + nCurrentPiece;
- }
- }
- else
- {
- if ((nCurrentX + i) % 4 == 3 || (nCurrentX + i) % 4 == 0)
- {
- pColor[(nCurrentY + j) * nScreenWidth + (nCurrentX + i)] = 8 * 16 + nCurrentPiece;
- }
- else
- {
- pColor[(nCurrentY + j) * nScreenWidth + (nCurrentX + i)] = 7 * 16 + nCurrentPiece;
- }
- }
- }
- }
- }
- for (int j = 0; j < 4; j++)
- {
- if (nCurrentY + j < nBoardHeight - 1)
- {
- bool bLine = 1;
- for (int i = 1; i < nBoardWidth - 1; i++)
- {
- if (pMatrix[(nCurrentY + j) * nBoardWidth + i] == 0)
- {
- bLine = 0;
- break;
- }
- }
- if (bLine == 1)
- {
- nLine++;
- for (int i = 1; i < nBoardWidth - 1; i++)
- {
- pMatrix[(nCurrentY + j) * nBoardWidth + i] = 3;
- }
- vLines.push_back(nCurrentY + j);
- }
- }
- }
- nScore += 25;
- if (!vLines.empty())
- {
- nScore += (1 << vLines.size()) * 100;
- }
- nCurrentX = nBoardWidth / 2 - 4;
- nCurrentY = -4;
- nCurrentRotation = 0;
- nCurrentPiece = nNextPiece;
- nNextPiece = random(0, 6);
- }
- }
- }
- // DISPLAY
- for (int i = 0; i < nBoardWidth; i++)
- {
- for (int j = 0; j < nBoardHeight; j++)
- {
- pBuffer[j * nScreenWidth + i] = detail[pMatrix[j * nBoardWidth + i]];
- }
- }
- for (int i = 0; i < 8; i++)
- {
- for (int j = 0; j < 4; j++)
- {
- if (tetromino.at(nCurrentPiece).at(nCurrentRotation).at(j * 8 + i) != L'.' && nCurrentY + j >= 0)
- {
- if ((nCurrentY + j) % 2 == 1)
- {
- if ((nCurrentX + i) % 4 == 1 || (nCurrentX + i) % 4 == 2)
- {
- pColor[(nCurrentY + j) * nScreenWidth + (nCurrentX + i)] = 8 * 16 + nCurrentPiece;
- }
- else
- {
- pColor[(nCurrentY + j) * nScreenWidth + (nCurrentX + i)] = 7 * 16 + nCurrentPiece;
- }
- }
- else
- {
- if ((nCurrentX + i) % 4 == 3 || (nCurrentX + i) % 4 == 0)
- {
- pColor[(nCurrentY + j) * nScreenWidth + (nCurrentX + i)] = 8 * 16 + nCurrentPiece;
- }
- else
- {
- pColor[(nCurrentY + j) * nScreenWidth + (nCurrentX + i)] = 7 * 16 + nCurrentPiece;
- }
- }
- pBuffer[(nCurrentY + j) * nScreenWidth + (nCurrentX + i)] = L'▓';
- }
- }
- }
- Block(pBuffer, pColor, nNextPiece, 26, 8);
- if (nScore >= nScoreComp)
- {
- nScorePosX--;
- nScoreComp *= 10;
- }
- Text(pBuffer, to_wstring(nScore), nScorePosX, 2);
- if (nLine >= nLineComp)
- {
- nLinePosX--;
- nLineComp *= 10;
- }
- Text(pBuffer, to_wstring(nLine), nLinePosX, 5);
- if (!vLines.empty())
- {
- WriteConsoleOutputCharacter(hConsole, pBuffer, nScreenWidth * nScreenHeight, { 0,0 }, &dwBytesWritten);
- Sleep(400);
- for (int l = 0; l < vLines.size(); l++)
- {
- for (int i = 1; i < nBoardWidth - 1; i++)
- {
- for (int j = vLines.at(l); j > 0; j--)
- {
- if (j % 2 == 0)
- {
- if (i % 4 == 1 || i % 4 == 2)
- {
- pColor[j * nScreenWidth + i] = pColor[(j - 1) * nScreenWidth + i] - 16;
- }
- else
- {
- pColor[j * nScreenWidth + i] = pColor[(j - 1) * nScreenWidth + i] + 16;
- }
- }
- else
- {
- if (i % 4 == 1 || i % 4 == 2)
- {
- pColor[j * nScreenWidth + i] = pColor[(j - 1) * nScreenWidth + i] + 16;
- }
- else
- {
- pColor[j * nScreenWidth + i] = pColor[(j - 1) * nScreenWidth + i] - 16;
- }
- }
- pMatrix[j * nBoardWidth + i] = pMatrix[(j - 1) * nBoardWidth + i];
- }
- pMatrix[i] = 0;
- }
- }
- vLines.clear();
- }
- for (int i = 0; i < nScreenWidth; i++)
- {
- for (int j = 0; j < nScreenHeight; j++)
- {
- COORD cPos;
- cPos.X = i;
- cPos.Y = j;
- WriteConsoleOutputAttribute(hConsole, &pColor[j * nScreenWidth + i], 1, cPos, &dwBytesWritten);
- }
- }
- WriteConsoleOutputCharacter(hConsole, pBuffer, nScreenWidth * nScreenHeight, { 0,0 }, &dwBytesWritten);
- }
- CloseHandle(hConsole);
- cout << "Game Over !" << "\n";
- cout << "Score: " << nScore << "\n";
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement