Untitled

mail@pastecode.io avatar
unknown
plain_text
a year ago
7.0 kB
2
Indexable
Never
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <windows.h>

int nScreenWidth = 80; // Breite der Konsole
int nScreenHeight = 30; // Höhe der Konsole
wchar_t *pScreen = NULL;

int Rotate(int px, int py, int r)
{
    int pi = 0;
    switch (r % 4)
    {
        case 0: // 0 Grad Rotation
            pi = py * 4 + px;
            break;
        case 1: // 90 Grad Rotation
            pi = 12 + py - (px * 4);
            break;
        case 2: // 180 Grad Rotation
            pi = 15 - (py * 4) - px;
            break;
        case 3: // 270 Grad Rotation
            pi = 3 - py + (px * 4);
            break;
    }
    return pi;
}

int main()
{
    // Initialisieren Sie die Konsole
    pScreen = (wchar_t *)malloc(nScreenWidth * nScreenHeight * sizeof(wchar_t));
    for (int i = 0; i < nScreenWidth * nScreenHeight; i++)
        pScreen[i] = L' ';
    HANDLE hConsole = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
    SetConsoleActiveScreenBuffer(hConsole);
    DWORD dwBytesWritten = 0;

    // Tetriminos
    wchar_t *tetromino[7];
    tetromino[0] = L"....xxxx....";
    tetromino[1] = L"..x..x..x..x";
    tetromino[2] = L"....xx..xx..";
    tetromino[3] = L"..x..xx...x.";
    tetromino[4] = L".x...xx...x.";
    tetromino[5] = L".x...x...xx.";
    tetromino[6] = L"..x...x..xx.";

    int nFieldWidth = 12;
    int nFieldHeight = 18;
    unsigned char *pField = (unsigned char *)malloc(nFieldWidth * nFieldHeight * sizeof(unsigned char));
    for (int x = 0; x < nFieldWidth; x++)
        for (int y = 0; y < nFieldHeight; y++)
            pField[y * nFieldWidth + x] = (x == 0 || x == nFieldWidth - 1 || y == nFieldHeight - 1) ? 9 : 0;

    int nCurrentPiece = 0;
    int nCurrentRotation = 0;
    int nCurrentX = nFieldWidth / 2;
    int nCurrentY = 0;

    int nSpeed = 20;
    int nSpeedCounter = 0;
    int bForceDown = false;
    int nPieceCount = 0;
    int nScore = 0;

    int *p = NULL;
    int x, y;

    int nGameOver = 0;

    while (!nGameOver)
    {
        // Steuerung
        for (x = 0; x < 4; x++)
            for (y = 0; y < 4; y++)
            {
                // Index des Tetrimino-Elements im Array
                p = tetromino[nCurrentPiece] + Rotate(x, y, nCurrentRotation);
                // Index der Spielfeld-Position
                int fi = (nCurrentY + y) * nFieldWidth + (nCurrentX + x);
                if (nCurrentX + x >= 0 && nCurrentX + x < nFieldWidth)
                {
                    if (nCurrentY + y >= 0 && nCurrentY + y < nFieldHeight)
                    {
                        if (pField[fi] != 0 && p[0] != L'.')
                        {
                            nGameOver = 1;
                        }
                    }
                }
            }

        // Tastensteuerung
        if (_kbhit())
        {
            int key = _getch();
            if (key == 'a')
            {
                nCurrentX -= (pCurrentPiece[nCurrentRotation] == L".X.." ? 2 : 1);
                if (nCurrentX < 0)
                    nCurrentX = 0;
                if (nCurrentX >= nFieldWidth - 4)
                    nCurrentX = nFieldWidth - 4;
            }
            if (key == 'd')
            {
                nCurrentX += (pCurrentPiece[nCurrentRotation] == L".X.." ? 2 : 1);
                if (nCurrentX >= nFieldWidth - 4)
                    nCurrentX = nFieldWidth - 4;
                if (nCurrentX < 0)
                    nCurrentX = 0;
            }
            if (key == 'w')
            {
                nCurrentRotation++;
                if (nCurrentRotation == 4)
                    nCurrentRotation = 0;
            }
            if (key == 's')
            {
                nSpeed = 1;
            }
            if (key == 'q')
            {
                nSpeed = 50;
            }
        }

        // Schwerkraft und Timer-Steuerung
        nSpeedCounter++;
        if (nSpeedCounter >= nSpeed)
        {
            nSpeedCounter = 0;
            nCurrentY += 1;
            if (bForceDown)
            {
                nSpeed = 20;
                nForceDown = false;
            }
        }

        // Logik des Spielfelds
        for (x = 0; x < 4; x++)
            for (y = 0; y < 4; y++)
            {
                // Index des Tetrimino-Elements im Array
                p = tetromino[nCurrentPiece] + Rotate(x, y, nCurrentRotation);
                // Index der Spielfeld-Position
                int fi = (nCurrentY + y) * nFieldWidth + (nCurrentX + x);
                if (nCurrentX + x >= 0 && nCurrentX + x < nFieldWidth)
                {
                    if (nCurrentY + y >= 0 && nCurrentY + y < nFieldHeight)
                    {
                        pField[fi] = p[0] == L'.' ? 0 : nCurrentPiece + 1;
                    }
                }
            }

        // Löschen der vollständigen Reihen
        for (y = nFieldHeight - 2; y > 0; y--)
        {
            int bLine = true;
            for (x = 1; x < nFieldWidth - 1; x++)
                bLine &= (pField[y * nFieldWidth + x]) != 0;

            if (bLine)
            {
                for (x = 1; x < nFieldWidth - 1; x++)
                    pField[y * nFieldWidth + x] = 8;
                for (int j = y; j > 0; j--)
                    for (x = 1; x < nFieldWidth - 1; x++)
                        pField[j * nFieldWidth + x] = pField[(j - 1) * nFieldWidth + x];
                nScore += 100;
            }
        }

        // Nächstes Tetrimino
        nCurrentX = nFieldWidth / 2;
        nCurrentY = 0;
        nCurrentRotation = 0;
        nCurrentPiece = rand() % 7;

        // Spielende
        nGameOver = false;
        for (x = 0; x < nFieldWidth; x++)
        {
            if (pField[x] != 0)
            {
                nGameOver = true;
            }
        }

        // Rendern des Spielfelds
        for (x = 0; x < nFieldWidth; x++)
            for (y = 0; y < nFieldHeight; y++)
                pScreen[(y + 2) * nScreenWidth + (x + 2)] = L" ABCDEFG=#"[pField[y * nFieldWidth + x]];

        // Rendern des aktuellen Tetriminos
        for (x = 0; x < 4; x++)
            for (y = 0; y < 4; y++)
            {
                p = tetromino[nCurrentPiece] + Rotate(x, y, nCurrentRotation);
                if (p[0] != L'.')
                    pScreen[(nCurrentY + y + 2) * nScreenWidth + (nCurrentX + x + 2)] = nCurrentPiece + 65;
            }

        // Ausgabe auf die Konsole
        WriteConsoleOutputCharacter(hConsole, pScreen, nScreenWidth * nScreenHeight, {0, 0}, &dwBytesWritten);

        // Punktzahl anzeigen
        wprintf(L"Score: %d", nScore);
    }

    CloseHandle(hConsole);
    wprintf(L"Game Over! Score: %d\n", nScore);
    free(pField);
    free(pScreen);

    return 0;
}