Advertisement
DeltaJoseph

Tetris_2.cpp

Aug 2nd, 2020 (edited)
1,575
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 13.35 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <string>
  4. #include <random>
  5. #include <Windows.h>
  6.  
  7. using namespace std;
  8.  
  9. const vector<vector<wstring>> tetromino = {
  10.     // I
  11.     {
  12.         L"....XX......XX......XX......XX..", //   0 deg
  13.         L"................XXXXXXXX........", //  90 deg
  14.         L"..XX......XX......XX......XX....", // 180 deg
  15.         L"........XXXXXXXX................"  // 270 deg
  16.     },
  17.  
  18.     // J
  19.     {
  20.         L"....XX......XX....XXXX..........",
  21.         L"..........XX......XXXXXX........",
  22.         L"..........XXXX....XX......XX....",
  23.         L"........XXXXXX......XX.........."
  24.     },
  25.  
  26.     // L
  27.     {
  28.         L"..XX......XX......XXXX..........",
  29.         L"..........XXXXXX..XX............",
  30.         L"..........XXXX......XX......XX..",
  31.         L"............XX..XXXXXX.........."
  32.     },
  33.  
  34.     // O
  35.     {
  36.         L"..........XXXX....XXXX..........",
  37.         L"..........XXXX....XXXX..........",
  38.         L"..........XXXX....XXXX..........",
  39.         L"..........XXXX....XXXX.........."
  40.     },
  41.  
  42.     // S
  43.     {
  44.         L"..XX......XXXX......XX..........",
  45.         L"............XXXX..XXXX..........",
  46.         L"..........XX......XXXX......XX..",
  47.         L"..........XXXX..XXXX............"
  48.     },
  49.  
  50.     // T
  51.     {
  52.         L"..XX......XXXX....XX............",
  53.         L"..........XXXXXX....XX..........",
  54.         L"............XX....XXXX......XX..",
  55.         L"..........XX....XXXXXX.........."
  56.     },
  57.  
  58.     // Z
  59.     {
  60.         L"....XX....XXXX....XX............",
  61.         L"..........XXXX......XXXX........",
  62.         L"............XX....XXXX....XX....",
  63.         L"........XXXX......XXXX.........."
  64.     }
  65. };
  66.  
  67. const int nScreenWidth = 39;
  68. const int nScreenHeight = 21;
  69.  
  70. const int nBoardWidth = 22;
  71. const int nBoardHeight = 21;
  72.  
  73. const wstring detail = L" ▓█░╚╝║═";
  74.  
  75. int random(int nMin, int nMax)
  76. {
  77.     random_device rd;
  78.     mt19937 rng(rd());
  79.     uniform_int_distribution<int> uni(nMin, nMax);
  80.  
  81.     auto num = uni(rng);
  82.     return num;
  83. }
  84.  
  85. void Configure()
  86. {
  87.     system("MODE 39, 22");
  88.     system("color 89");
  89.  
  90.     HANDLE hConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
  91.  
  92.     CONSOLE_SCREEN_BUFFER_INFOEX csbiex;
  93.     csbiex.cbSize = sizeof(CONSOLE_SCREEN_BUFFER_INFOEX);
  94.     GetConsoleScreenBufferInfoEx(hConsoleOutput, &csbiex);
  95.     csbiex.ColorTable[0] = RGB(0, 188, 212);
  96.     csbiex.ColorTable[1] = RGB(63, 81, 181);
  97.     csbiex.ColorTable[2] = RGB(255, 87, 34);
  98.     csbiex.ColorTable[3] = RGB(255, 235, 59);
  99.     csbiex.ColorTable[4] = RGB(76, 175, 80);
  100.     csbiex.ColorTable[5] = RGB(156, 39, 176);
  101.     csbiex.ColorTable[6] = RGB(237, 28, 36);
  102.     csbiex.ColorTable[7] = RGB(242, 242, 242);
  103.     csbiex.ColorTable[8] = RGB(248, 248, 248);
  104.     csbiex.ColorTable[9] = RGB(20, 20, 20);
  105.  
  106.     SetConsoleScreenBufferInfoEx(hConsoleOutput, &csbiex);
  107. }
  108.  
  109. void Frame(wchar_t*& wcBuffer, wstring wsCaption, int nWidth, int nHeight, int nPosX, int nPosY)
  110. {
  111.     for (int i = nPosX; i < nWidth + nPosX; i++)
  112.     {
  113.         for (int j = nPosY; j < nHeight + nPosY; j++)
  114.         {
  115.             if (i == nPosX)
  116.             {
  117.                 if (j == nPosY)
  118.                 {
  119.                     wcBuffer[j * nScreenWidth + i] = L'╔';
  120.                 }
  121.                 else if (j == nHeight + nPosY - 1)
  122.                 {
  123.                     wcBuffer[j * nScreenWidth + i] = L'╚';
  124.                 }
  125.                 else
  126.                 {
  127.                     wcBuffer[j * nScreenWidth + i] = L'║';
  128.                 }
  129.             }
  130.             else if (i == nWidth + nPosX - 1)
  131.             {
  132.                 if (j == nPosY)
  133.                 {
  134.                     wcBuffer[j * nScreenWidth + i] = L'╗';
  135.                 }
  136.                 else if (j == nHeight + nPosY - 1)
  137.                 {
  138.                     wcBuffer[j * nScreenWidth + i] = L'╝';
  139.                 }
  140.                 else
  141.                 {
  142.                     wcBuffer[j * nScreenWidth + i] = L'║';
  143.                 }
  144.             }
  145.             else
  146.             {
  147.                 if (j == nPosY || j == nHeight + nPosY - 1)
  148.                 {
  149.                     wcBuffer[j * nScreenWidth + i] = L'═';
  150.                 }
  151.                 else
  152.                 {
  153.                     wcBuffer[j * nScreenWidth + i] = L' ';
  154.                 }
  155.  
  156.             }
  157.         }
  158.     }
  159.  
  160.     int CapIndex = nPosY * nScreenWidth + (nPosX + 1);
  161.     for (int i = 0; i < wsCaption.length(); i++, CapIndex++)
  162.     {
  163.         wcBuffer[CapIndex] = wsCaption.at(i);
  164.     }
  165. }
  166.  
  167. void Block(wchar_t*& pBuffer, WORD*& pColor, int nTetromino, int nPosX, int nPosY)
  168. {
  169.     for (int j = 0; j < 4; j++)
  170.     {
  171.         for (int i = 0; i < 8; i++)
  172.         {
  173.             if (tetromino.at(nTetromino).at(0).at(j * 8 + i) != L'.')
  174.             {
  175.                 pBuffer[(nPosY + j) * nScreenWidth + (nPosX + i)] = L'▓';
  176.             }
  177.             else
  178.             {
  179.                 pBuffer[(nPosY + j) * nScreenWidth + (nPosX + i)] = L' ';
  180.             }
  181.             pColor[(nPosY + j) * nScreenWidth + (nPosX + i)] = 8 * 16 + nTetromino;
  182.         }
  183.     }
  184. }
  185.  
  186. void Text(wchar_t*& pBuffer, wstring content, int nPosX, int nPosY)
  187. {
  188.     for (int i = 0; i < content.length(); i++, nPosX++)
  189.     {
  190.         pBuffer[nPosY * nScreenWidth + nPosX] = content.at(i);
  191.     }
  192. }
  193.  
  194. bool CheckPiece(int*& pMatrix, int nTetromino, int nRotation, int nPosX, int nPosY)
  195. {
  196.     for (int i = 0; i < 8; i++)
  197.     {
  198.         for (int j = 0; j < 4; j++)
  199.         {
  200.             if (nPosX + i >= 0 && nPosX + i < nBoardWidth)
  201.             {
  202.                 if (nPosY + j >= 0 && nPosY + j < nBoardHeight)
  203.                 {
  204.                     if (tetromino.at(nTetromino).at(nRotation).at(j * 8 + i) != L'.' && pMatrix[(nPosY + j) * nBoardWidth + (nPosX + i)] != 0)
  205.                     {
  206.                         return 0;
  207.                     }
  208.                 }
  209.             }
  210.         }
  211.     }
  212.  
  213.     return 1;
  214. }
  215.  
  216. int main()
  217. {
  218.     Configure();
  219.  
  220.     WORD* pColor = new WORD[nScreenWidth * nScreenHeight];
  221.     wchar_t* pBuffer = new wchar_t[nScreenWidth * nScreenHeight];
  222.     for (int i = 0; i < nScreenWidth; i++)
  223.     {
  224.         for (int j = 0; j < nScreenHeight; j++)
  225.         {
  226.             pBuffer[j * nScreenWidth + i] = L' ';
  227.             if (i == 0 || i >= nBoardWidth - 1 || j == nBoardHeight - 1)
  228.             {
  229.                 pColor[j * nScreenWidth + i] = 8 * 16 + 9;
  230.             }
  231.             else
  232.             {
  233.                 if (j % 2 == 1)
  234.                 {
  235.                     if (i % 4 == 1 || i % 4 == 2)
  236.                     {
  237.                         pColor[j * nScreenWidth + i] = 8 * 16 + 9;
  238.                     }
  239.                     else
  240.                     {
  241.                         pColor[j * nScreenWidth + i] = 7 * 16 + 9;
  242.                     }
  243.                 }
  244.                 else
  245.                 {
  246.                     if (i % 4 == 3 || i % 4 == 0)
  247.                     {
  248.                         pColor[j * nScreenWidth + i] = 8 * 16 + 9;
  249.                     }
  250.                     else
  251.                     {
  252.                         pColor[j * nScreenWidth + i] = 7 * 16 + 9;
  253.                     }
  254.                 }
  255.             }
  256.         }
  257.     }
  258.  
  259.     int* pMatrix = new int[nBoardWidth * nBoardHeight];
  260.     for (int i = 0; i < nBoardWidth; i++)
  261.     {
  262.         for (int j = 0; j < nBoardHeight; j++)
  263.         {
  264.             if (j == nBoardHeight - 1)
  265.             {
  266.                 if (i == 0)
  267.                 {
  268.                     pMatrix[j * nBoardWidth + i] = 4;
  269.                 }
  270.                 else if (i == nBoardWidth - 1)
  271.                 {
  272.                     pMatrix[j * nBoardWidth + i] = 5;
  273.                 }
  274.                 else
  275.                 {
  276.                     pMatrix[j * nBoardWidth + i] = 7;
  277.                 }
  278.             }
  279.             else
  280.             {
  281.                 if (i == 0 || i == nBoardWidth - 1)
  282.                 {
  283.                     pMatrix[j * nBoardWidth + i] = 6;
  284.                 }
  285.                 else
  286.                 {
  287.                     pMatrix[j * nBoardWidth + i] = 0;
  288.                 }
  289.             }
  290.         }
  291.     }
  292.  
  293.     HANDLE hConsole = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
  294.     SetConsoleActiveScreenBuffer(hConsole);
  295.     DWORD dwBytesWritten = 0;
  296.  
  297.     Frame(pBuffer, L"[ SCORE ]", 17, 3, nBoardWidth, 1);
  298.     Frame(pBuffer, L"[ LINE ]", 17, 3, nBoardWidth, 4);
  299.     Frame(pBuffer, L"[ NEXT ]", 17, 6, nBoardWidth, 7);
  300.  
  301.     const vector<char> key = { 'W', 'A', 'S', 'D' };
  302.     bool bKey[4];
  303.  
  304.     int nCurrentPiece = random(0, 6);
  305.     int nNextPiece = random(0, 6);
  306.     int nCurrentRotation = 0;
  307.     int nCurrentX = nBoardWidth / 2 - 4;
  308.     int nCurrentY = 0;
  309.    
  310.     int nFrame = 10;
  311.     int nFrameCount = 0;
  312.     bool bForceDown = 0;
  313.    
  314.     bool bRotateHold = 1;
  315.  
  316.     int nScore = 0;
  317.     int nScorePosX = 37;
  318.     int nScoreComp = 10;
  319.  
  320.     int nLine = 0;
  321.     int nLinePosX = 37;
  322.     int nLineComp = 10;
  323.  
  324.     vector<int> vLines;
  325.     bool bGameOver = 0;
  326.  
  327.     while (bGameOver != 1)
  328.     {
  329.         // GAME TIMING
  330.         Sleep(75);
  331.         nFrameCount++;
  332.         if (nFrameCount == nFrame)
  333.         {
  334.             bForceDown = 1;
  335.         }
  336.         else
  337.         {
  338.             bForceDown = 0;
  339.         }
  340.  
  341.         // INPUT
  342.         for (int i = 0; i < key.size(); i++)
  343.         {
  344.             if ((GetKeyState(key.at(i)) & 0x8000) != 0)
  345.             {
  346.                 bKey[i] = 1;
  347.             }
  348.             else
  349.             {
  350.                 bKey[i] = 0;
  351.             }
  352.         }
  353.  
  354.         // GAME LOGIC
  355.         int nLimit = 0;
  356.         if (nCurrentPiece == 3)
  357.         {
  358.             nLimit = -1;
  359.         }
  360.  
  361.         if (bKey[3] == 1 && nCurrentY >= nLimit)
  362.         {
  363.             if (CheckPiece(pMatrix, nCurrentPiece, nCurrentRotation, nCurrentX + 2, nCurrentY) == 1)
  364.             {
  365.                 nCurrentX += 2;
  366.             }
  367.  
  368.         }
  369.  
  370.         if (bKey[1] == 1 && nCurrentY >= nLimit && CheckPiece(pMatrix, nCurrentPiece, nCurrentRotation, nCurrentX - 2, nCurrentY) == 1)
  371.         {
  372.             nCurrentX -= 2;
  373.         }
  374.  
  375.         if (bKey[2] == 1 && nCurrentY >= nLimit)
  376.         {
  377.             int i{};
  378.             while (CheckPiece(pMatrix, nCurrentPiece, nCurrentRotation, nCurrentX, nCurrentY + i) == 1)
  379.             {
  380.                 i++;
  381.             }
  382.             nCurrentY += i - 1;
  383.         }
  384.  
  385.         if (bKey[0] == 1 && nCurrentY >= nLimit && bRotateHold == 1 && CheckPiece(pMatrix, nCurrentPiece, (nCurrentRotation + 1) % 4, nCurrentX, nCurrentY) == 1)
  386.         {
  387.             nCurrentRotation++;
  388.             nCurrentRotation %= 4;
  389.             bRotateHold = 0;
  390.         }
  391.         else
  392.         {
  393.             bRotateHold = 1;
  394.         }
  395.  
  396.         if (bForceDown == 1)
  397.         {
  398.             nFrameCount = 0;
  399.  
  400.             if (CheckPiece(pMatrix, nCurrentPiece, nCurrentRotation, nCurrentX, nCurrentY + 1))
  401.             {
  402.                 nCurrentY++;
  403.             }
  404.             else
  405.             {
  406.                 if (nCurrentY < nLimit)
  407.                 {
  408.                     bGameOver = 1;
  409.                     break;
  410.                 }
  411.                 else
  412.                 {
  413.                     for (int i = 0; i < 8; i++)
  414.                     {
  415.                         for (int j = 0; j < 4; j++)
  416.                         {
  417.                             if (nCurrentY >= 0 && tetromino.at(nCurrentPiece).at(nCurrentRotation).at(j * 8 + i) != L'.')
  418.                             {
  419.                                 pMatrix[(nCurrentY + j) * nBoardWidth + (nCurrentX + i)] = 2;
  420.                                 if ((nCurrentY + j) % 2 == 1)
  421.                                 {
  422.                                     if ((nCurrentX + i) % 4 == 1 || (nCurrentX + i) % 4 == 2)
  423.                                     {
  424.                                         pColor[(nCurrentY + j) * nScreenWidth + (nCurrentX + i)] = 8 * 16 + nCurrentPiece;
  425.                                     }
  426.                                     else
  427.                                     {
  428.                                         pColor[(nCurrentY + j) * nScreenWidth + (nCurrentX + i)] = 7 * 16 + nCurrentPiece;
  429.                                     }
  430.                                 }
  431.                                 else
  432.                                 {
  433.                                     if ((nCurrentX + i) % 4 == 3 || (nCurrentX + i) % 4 == 0)
  434.                                     {
  435.                                         pColor[(nCurrentY + j) * nScreenWidth + (nCurrentX + i)] = 8 * 16 + nCurrentPiece;
  436.                                     }
  437.                                     else
  438.                                     {
  439.                                         pColor[(nCurrentY + j) * nScreenWidth + (nCurrentX + i)] = 7 * 16 + nCurrentPiece;
  440.                                     }
  441.                                 }
  442.                             }
  443.                         }
  444.                     }
  445.  
  446.                     for (int j = 0; j < 4; j++)
  447.                     {
  448.                         if (nCurrentY + j < nBoardHeight - 1)
  449.                         {
  450.                             bool bLine = 1;
  451.                             for (int i = 1; i < nBoardWidth - 1; i++)
  452.                             {
  453.                                 if (pMatrix[(nCurrentY + j) * nBoardWidth + i] == 0)
  454.                                 {
  455.                                     bLine = 0;
  456.                                     break;
  457.                                 }
  458.                             }
  459.  
  460.                             if (bLine == 1)
  461.                             {
  462.                                 nLine++;
  463.  
  464.                                 for (int i = 1; i < nBoardWidth - 1; i++)
  465.                                 {
  466.                                     pMatrix[(nCurrentY + j) * nBoardWidth + i] = 3;
  467.                                 }
  468.                                 vLines.push_back(nCurrentY + j);
  469.                             }
  470.                         }
  471.                     }
  472.  
  473.                     nScore += 25;
  474.                     if (!vLines.empty())
  475.                     {
  476.                         nScore += (1 << vLines.size()) * 100;
  477.                     }
  478.  
  479.                     nCurrentX = nBoardWidth / 2 - 4;
  480.                     nCurrentY = -4;
  481.                     nCurrentRotation = 0;
  482.                     nCurrentPiece = nNextPiece;
  483.                     nNextPiece = random(0, 6);
  484.                 }
  485.             }
  486.         }
  487.  
  488.         // DISPLAY
  489.         for (int i = 0; i < nBoardWidth; i++)
  490.         {
  491.             for (int j = 0; j < nBoardHeight; j++)
  492.             {
  493.                 pBuffer[j * nScreenWidth + i] = detail[pMatrix[j * nBoardWidth + i]];
  494.             }
  495.         }
  496.  
  497.         for (int i = 0; i < 8; i++)
  498.         {
  499.             for (int j = 0; j < 4; j++)
  500.             {
  501.                 if (tetromino.at(nCurrentPiece).at(nCurrentRotation).at(j * 8 + i) != L'.' && nCurrentY + j >= 0)
  502.                 {
  503.                     if ((nCurrentY + j) % 2 == 1)
  504.                     {
  505.                         if ((nCurrentX + i) % 4 == 1 || (nCurrentX + i) % 4 == 2)
  506.                         {
  507.                             pColor[(nCurrentY + j) * nScreenWidth + (nCurrentX + i)] = 8 * 16 + nCurrentPiece;
  508.                         }
  509.                         else
  510.                         {
  511.                             pColor[(nCurrentY + j) * nScreenWidth + (nCurrentX + i)] = 7 * 16 + nCurrentPiece;
  512.                         }
  513.                     }
  514.                     else
  515.                     {
  516.                         if ((nCurrentX + i) % 4 == 3 || (nCurrentX + i) % 4 == 0)
  517.                         {
  518.                             pColor[(nCurrentY + j) * nScreenWidth + (nCurrentX + i)] = 8 * 16 + nCurrentPiece;
  519.                         }
  520.                         else
  521.                         {
  522.                             pColor[(nCurrentY + j) * nScreenWidth + (nCurrentX + i)] = 7 * 16 + nCurrentPiece;
  523.                         }
  524.                     }
  525.                     pBuffer[(nCurrentY + j) * nScreenWidth + (nCurrentX + i)] = L'▓';
  526.                 }
  527.             }
  528.         }
  529.  
  530.         Block(pBuffer, pColor, nNextPiece, 26, 8);
  531.  
  532.         if (nScore >= nScoreComp)
  533.         {
  534.             nScorePosX--;
  535.             nScoreComp *= 10;
  536.         }
  537.            
  538.         Text(pBuffer, to_wstring(nScore), nScorePosX, 2);
  539.  
  540.         if (nLine >= nLineComp)
  541.         {
  542.             nLinePosX--;
  543.             nLineComp *= 10;
  544.         }
  545.            
  546.         Text(pBuffer, to_wstring(nLine), nLinePosX, 5);
  547.  
  548.         if (!vLines.empty())
  549.         {
  550.             WriteConsoleOutputCharacter(hConsole, pBuffer, nScreenWidth * nScreenHeight, { 0,0 }, &dwBytesWritten);
  551.             Sleep(400);
  552.  
  553.             for (int l = 0; l < vLines.size(); l++)
  554.             {
  555.                 for (int i = 1; i < nBoardWidth - 1; i++)
  556.                 {
  557.                     for (int j = vLines.at(l); j > 0; j--)
  558.                     {
  559.                         if (j % 2 == 0)
  560.                         {
  561.                             if (i % 4 == 1 || i % 4 == 2)
  562.                             {
  563.                                 pColor[j * nScreenWidth + i] = pColor[(j - 1) * nScreenWidth + i] - 16;
  564.                             }
  565.                             else
  566.                             {
  567.                                 pColor[j * nScreenWidth + i] = pColor[(j - 1) * nScreenWidth + i] + 16;
  568.                             }
  569.                         }
  570.                         else
  571.                         {
  572.                             if (i % 4 == 1 || i % 4 == 2)
  573.                             {
  574.                                 pColor[j * nScreenWidth + i] = pColor[(j - 1) * nScreenWidth + i] + 16;
  575.                             }
  576.                             else
  577.                             {
  578.                                 pColor[j * nScreenWidth + i] = pColor[(j - 1) * nScreenWidth + i] - 16;
  579.                             }
  580.                         }
  581.                         pMatrix[j * nBoardWidth + i] = pMatrix[(j - 1) * nBoardWidth + i];
  582.                     }
  583.                     pMatrix[i] = 0;
  584.                 }
  585.             }
  586.             vLines.clear();
  587.         }
  588.  
  589.         for (int i = 0; i < nScreenWidth; i++)
  590.         {
  591.             for (int j = 0; j < nScreenHeight; j++)
  592.             {
  593.                 COORD cPos;
  594.                 cPos.X = i;
  595.                 cPos.Y = j;
  596.                 WriteConsoleOutputAttribute(hConsole, &pColor[j * nScreenWidth + i], 1, cPos, &dwBytesWritten);
  597.             }
  598.         }
  599.         WriteConsoleOutputCharacter(hConsole, pBuffer, nScreenWidth * nScreenHeight, { 0,0 }, &dwBytesWritten);
  600.     }
  601.  
  602.     CloseHandle(hConsole);
  603.  
  604.     cout << "Game Over !" << "\n";
  605.     cout << "Score: " << nScore << "\n";
  606.  
  607.     return 0;
  608. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement