tetris baby

This commit is contained in:
2022-04-09 22:41:38 +10:00
parent 287d037d5c
commit 67bea29788
3 changed files with 231 additions and 4 deletions

View File

@@ -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

View File

@@ -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);
}
}

View File

@@ -102,6 +102,7 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>