tetris baby
This commit is contained in:
@@ -13,8 +13,8 @@ Global
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{A563C8D1-58A0-44D7-AA0C-6D3721CEEAA9}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{A563C8D1-58A0-44D7-AA0C-6D3721CEEAA9}.Debug|x64.Build.0 = Debug|x64
|
||||
{A563C8D1-58A0-44D7-AA0C-6D3721CEEAA9}.Debug|x64.ActiveCfg = Release|Win32
|
||||
{A563C8D1-58A0-44D7-AA0C-6D3721CEEAA9}.Debug|x64.Build.0 = Release|Win32
|
||||
{A563C8D1-58A0-44D7-AA0C-6D3721CEEAA9}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{A563C8D1-58A0-44D7-AA0C-6D3721CEEAA9}.Debug|x86.Build.0 = Debug|Win32
|
||||
{A563C8D1-58A0-44D7-AA0C-6D3721CEEAA9}.Release|x64.ActiveCfg = Release|x64
|
||||
|
||||
@@ -1,8 +1,234 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
#include <chrono>
|
||||
|
||||
int main()
|
||||
#include <Windows.h>
|
||||
|
||||
|
||||
|
||||
std::wstring tetromino[7];
|
||||
int nFieldWidth = 12;
|
||||
int nFieldHeight = 18;
|
||||
unsigned char* pField = nullptr;
|
||||
|
||||
int nScreenWidth = 120;
|
||||
int nScreenHeight = 30;
|
||||
|
||||
int Rotate(int px, int py, int r)
|
||||
{
|
||||
std::cout << "Hello World" << std::endl;
|
||||
switch (r % 4)
|
||||
{
|
||||
case 0: return py * 4 + px;
|
||||
case 1: return 12 + py - (px * 4);
|
||||
case 2: return 15 - (py * 4) - px;
|
||||
case 3: return 3 - py + (px * 4);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool DoesPieceFit(int nTetromino, int nRotation, int nPosX, int nPosY)
|
||||
{
|
||||
for (int px = 0; px < 4; px++)
|
||||
{
|
||||
for (int py = 0; py < 4; py++)
|
||||
{
|
||||
int pi = Rotate(px, py, nRotation);
|
||||
int fi = (nPosY + py) * nFieldWidth + (nPosX + px);
|
||||
if (nPosX + px >= 0 && nPosX + px < nFieldWidth)
|
||||
{
|
||||
if (nPosY + py >= 0 && nPosY + py < nFieldHeight)
|
||||
{
|
||||
if (tetromino[nTetromino][pi] == L'X' && pField[fi] != 0)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
wchar_t* screen = new wchar_t[nScreenWidth * nScreenHeight];
|
||||
for (int i = 0; i < nScreenWidth * nScreenHeight; i++) screen[i] = L' ';
|
||||
HANDLE hConsole = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
|
||||
SetConsoleActiveScreenBuffer(hConsole);
|
||||
DWORD dwBytesWritten = 0;
|
||||
|
||||
//create assets
|
||||
tetromino[0].append(L"..X.");
|
||||
tetromino[0].append(L"..X.");
|
||||
tetromino[0].append(L"..X.");
|
||||
tetromino[0].append(L"..X.");
|
||||
|
||||
tetromino[1].append(L"..X.");
|
||||
tetromino[1].append(L".XX.");
|
||||
tetromino[1].append(L".X..");
|
||||
tetromino[1].append(L"....");
|
||||
|
||||
tetromino[2].append(L".X..");
|
||||
tetromino[2].append(L".XX.");
|
||||
tetromino[2].append(L"..X.");
|
||||
tetromino[2].append(L"....");
|
||||
|
||||
tetromino[3].append(L"....");
|
||||
tetromino[3].append(L".XX.");
|
||||
tetromino[3].append(L".XX.");
|
||||
tetromino[3].append(L"....");
|
||||
|
||||
tetromino[4].append(L"..X.");
|
||||
tetromino[4].append(L".XX.");
|
||||
tetromino[4].append(L"..X.");
|
||||
tetromino[4].append(L"....");
|
||||
|
||||
tetromino[5].append(L"....");
|
||||
tetromino[5].append(L".XX.");
|
||||
tetromino[5].append(L"..X.");
|
||||
tetromino[5].append(L"..X.");
|
||||
|
||||
tetromino[6].append(L"....");
|
||||
tetromino[6].append(L".XX.");
|
||||
tetromino[6].append(L".X..");
|
||||
tetromino[6].append(L".X..");
|
||||
|
||||
pField = new unsigned char[nFieldWidth * nFieldHeight]; // Create play field buffer
|
||||
for (int x = 0; x < nFieldWidth; x++) // Board Boundary
|
||||
for (int y = 0; y < nFieldHeight; y++)
|
||||
pField[y * nFieldWidth + x] = (x == 0 || x == nFieldWidth - 1 || y == nFieldHeight - 1) ? 9 : 0;
|
||||
|
||||
|
||||
bool bGameOver = false;
|
||||
|
||||
bool bKey[4];
|
||||
int nCurrentPiece = 0;
|
||||
int nCurrentRotation = 0;
|
||||
int nCurrentX = nFieldWidth / 2;
|
||||
int nCurrentY = 0;
|
||||
bool bRotateHold = true;
|
||||
int nSpeedCounter = 0;
|
||||
int nSpeed = 20;
|
||||
bool bForce = false;
|
||||
std::vector<int> vLines;
|
||||
int nScore = 0;
|
||||
int nPieceCount = 0;
|
||||
while (!bGameOver)
|
||||
{
|
||||
//timing
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||
nSpeedCounter++;
|
||||
bForce = (nSpeedCounter == nSpeed);
|
||||
|
||||
|
||||
//input
|
||||
|
||||
for (int k = 0; k < 4; k++) // R L D Z
|
||||
bKey[k] = (0x8000 & GetAsyncKeyState((unsigned char)("\x27\x25\x28Z"[k]))) != 0;
|
||||
|
||||
//game logic
|
||||
|
||||
nCurrentX += (bKey[0] && DoesPieceFit(nCurrentPiece, nCurrentRotation, nCurrentX + 1, nCurrentY)) ? 1 : 0;
|
||||
nCurrentX -= (bKey[1] && DoesPieceFit(nCurrentPiece, nCurrentRotation, nCurrentX - 1, nCurrentY)) ? 1 : 0;
|
||||
nCurrentY += (bKey[2] && DoesPieceFit(nCurrentPiece, nCurrentRotation, nCurrentX, nCurrentY + 1)) ? 1 : 0;
|
||||
|
||||
if (bKey[3])
|
||||
{
|
||||
nCurrentRotation += (bRotateHold && DoesPieceFit(nCurrentPiece, nCurrentRotation + 1, nCurrentX, nCurrentY)) ? 1 : 0;
|
||||
bRotateHold = false;
|
||||
}
|
||||
else
|
||||
bRotateHold = true;
|
||||
|
||||
if (bForce)
|
||||
{
|
||||
if (DoesPieceFit(nCurrentPiece, nCurrentRotation, nCurrentX, nCurrentY + 1))
|
||||
{
|
||||
nCurrentY++;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int px = 0; px < 4; px++)
|
||||
for (int py = 0; py < 4; py++)
|
||||
if (tetromino[nCurrentPiece][Rotate(px, py, nCurrentRotation)] == L'X')
|
||||
pField[(nCurrentY + py) * nFieldWidth + (nCurrentX + px)] = nCurrentPiece + 1;
|
||||
|
||||
nPieceCount++;
|
||||
if (nPieceCount % 10 == 0)
|
||||
if (nSpeed >= 10) nSpeed++;
|
||||
|
||||
for (int py = 0; py < 4; py++)
|
||||
if (nCurrentY + py < nFieldHeight - 1)
|
||||
{
|
||||
bool bLine = true;
|
||||
for (int px = 1; px < nFieldWidth - 1; px++)
|
||||
bLine &= (pField[(nCurrentY + py) * nFieldWidth + px]) != 0;
|
||||
|
||||
if (bLine)
|
||||
{
|
||||
for (int px = 1; px < nFieldWidth - 1; px++)
|
||||
pField[(nCurrentY + py) * nFieldWidth + px] = 8;
|
||||
|
||||
vLines.push_back(nCurrentY + py);
|
||||
}
|
||||
}
|
||||
|
||||
nScore += 25;
|
||||
if (!vLines.empty())
|
||||
nScore += (1 << vLines.size()) * 100;
|
||||
|
||||
nCurrentX = nFieldWidth / 2;
|
||||
nCurrentY = 0;
|
||||
nCurrentRotation = 0;
|
||||
nCurrentPiece = rand() % 7;
|
||||
|
||||
bGameOver = !DoesPieceFit(nCurrentPiece, nCurrentRotation, nCurrentX, nCurrentY);
|
||||
|
||||
|
||||
}
|
||||
nSpeedCounter = 0;
|
||||
}
|
||||
|
||||
//render output
|
||||
|
||||
// field drawing
|
||||
for (int x = 0; x < nFieldWidth; x++)
|
||||
for (int y = 0; y < nFieldHeight; y++)
|
||||
screen[(y + 2) * nScreenWidth + (x + 2)] = L" ABCDEFG=#"[pField[y * nFieldWidth + x]];
|
||||
|
||||
for (int px = 0; px < 4; px++)
|
||||
for (int py = 0; py < 4; py++)
|
||||
if (tetromino[nCurrentPiece][Rotate(px, py, nCurrentRotation)] != L'.')
|
||||
screen[(nCurrentY + py + 2) * nScreenWidth + (nCurrentX + px + 2)] = nCurrentPiece + 65;
|
||||
|
||||
swprintf_s(&screen[2 * nScreenWidth + nFieldWidth + 6], 16, L"SCORE: %8d", nScore);
|
||||
|
||||
if (!vLines.empty())
|
||||
{
|
||||
// Display Frame (cheekily to draw lines)
|
||||
WriteConsoleOutputCharacter(hConsole, screen, nScreenWidth * nScreenHeight, { 0,0 }, &dwBytesWritten);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(400)); // Delay a bit
|
||||
|
||||
for (const auto& v : vLines)
|
||||
for (int px = 1; px < nFieldWidth - 1; px++)
|
||||
{
|
||||
|
||||
for (int py = v; py > 0; py--)
|
||||
pField[py * nFieldWidth + px] = pField[(py - 1) * nFieldWidth + px];
|
||||
|
||||
pField[px] = 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
for (int x = 0; x < nFieldWidth; x++)
|
||||
for (int y = 0; y < nFieldHeight; y++)
|
||||
screen[(y + 2) * nScreenWidth + (x + 2)] = L" ABCDEFG=#"[pField[y * nFieldWidth + x]];
|
||||
vLines.clear();
|
||||
}
|
||||
|
||||
WriteConsoleOutputCharacter(hConsole, screen, nScreenWidth * nScreenHeight, { 0,0 }, &dwBytesWritten);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -102,6 +102,7 @@
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
|
||||
Reference in New Issue
Block a user