Search code examples
c++visual-studiovisual-studio-express

VS Express dosen't compile the code properly (?)


So I used to use Code::Blocks IDE, and like it a lot. Recently I switched to Visual Studio. I downloaded VS Express, it was 600mb and I can only use 1gb data per day, I don't have Wi-Fi, so I that was my only option.I inserted the same code that compiled properly in Code::Blocks in it , it took a few tweaks to make it work in VS, but when I finally check it, the output was totally different, Instead of a command line Tetris, it glitched and filled the command prompt with strange characters.

This is the code I tweaked a bit to make it work in VS:

#include <iostream>
#include <time.h>
#include <string>
#include <windows.h>
using namespace std;

int nScreenHeight = 30;
int nScreenWidth = 80;
int nFieldWidth = 10;
int nFieldHeight = 25;
unsigned char *pField = NULL;
wstring tetromine[7];

int currentPiece = 0;
int currentRotation = 0;
int currentX = (nFieldWidth/2);
int currentY = 0;
unsigned int score = 0;

int pieceCounter = 0;
int speed = 20;
int speedCounter = 0;
bool forcePieceDown =false;
bool key[4];
bool shiftGridDown = false;

int rotate(int px,int py,int r)
{
    switch(r/90)
    {
    case 0:
        return py*4+px;//0 degs
    case 1:
        return 12+py - (px*4);//90 degs
    case 2:
        return 15 - (py*4) - px;//180 degs
    case 3:
        return 3 - py + (px*4);//270 degs
    }
    return 0;
}

int doesPieceFit(int id,int rot, int x, int y)
{
    for(int px = 0;px<4;px++){
        for(int py = 0;py<4;py++){
            int pi = rotate(px,py,rot);
            int fi = (y+py) * nFieldWidth + (x+px);
            if(x + px>= 0 && x+px < nFieldWidth){
                if(tetromine[id][pi] == L'X' && pField[fi]!=0){
                    return false;
                }
            }
        }
    }
    return true;
}

void lineCheck(){
    bool line = true;
    int lines = 0;
    for(int y = 0; y<= nFieldHeight-1;y++){
        for(int x = 1; x< nFieldWidth-1;x++){
            if(pField[(y)*nFieldWidth+x]!=0){
                line &= true;
            } else line &= false;
        }
        if(line) lines++;
        if(line){
            for(int x = 1; x< nFieldWidth-1;x++){
                pField[(y)*nFieldWidth+x] = 8;
            }
        }
    }
}


int main()
{

    //assets
    tetromine[0].append(L"..X.");
    tetromine[0].append(L"..X.");
    tetromine[0].append(L"..X.");
    tetromine[0].append(L"..X.");

    tetromine[1].append(L"..X.");
    tetromine[1].append(L".XX.");
    tetromine[1].append(L".X..");
    tetromine[1].append(L"....");

    tetromine[2].append(L".X..");
    tetromine[2].append(L".XX.");
    tetromine[2].append(L"..X.");
    tetromine[2].append(L"....");

    tetromine[3].append(L"....");
    tetromine[3].append(L".XX.");
    tetromine[3].append(L".XX.");
    tetromine[3].append(L"....");

    tetromine[4].append(L"..X.");
    tetromine[4].append(L".XX.");
    tetromine[4].append(L"..X.");
    tetromine[4].append(L"....");

    tetromine[5].append(L"....");
    tetromine[5].append(L".XX.");
    tetromine[5].append(L"..X.");
    tetromine[5].append(L"..X.");

    tetromine[6].append(L"....");
    tetromine[6].append(L".XX.");
    tetromine[6].append(L".X..");
    tetromine[6].append(L".X..");

    pField = new unsigned char[nFieldWidth*nFieldHeight];
    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;
        }
    }

    char *screen = new char [nScreenWidth * nScreenHeight];
    HANDLE hConsole = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
    SetConsoleActiveScreenBuffer(hConsole);
    DWORD dwBytesWritten = 0;

    //Display frame
    COORD here;
    here.X = 0;
    here.Y = 0;
    WriteConsoleOutputCharacter(hConsole, (LPCWSTR)screen, nScreenWidth * nScreenHeight,here, &dwBytesWritten);

    bool gameOver = false;

    while(!gameOver)
    {
        Sleep(100);
        speedCounter++;
        if(speedCounter>=speed){
            forcePieceDown = true;
            speedCounter = 0;
        } else {
            forcePieceDown = false;
        }

        if(shiftGridDown){
            score++;
            for(int y = nFieldHeight-2;y > 0;y--){
                for(int x = 1;x<nFieldWidth -1;x++){
                    if((pField[(y)*nFieldWidth+x]) != 0){
                        pField[(y+1)*nFieldWidth+x] = pField[(y)*nFieldWidth+x];
                        pField[(y)*nFieldWidth+x] = 0;
                    }
                }
            }
            shiftGridDown = false;
            lineCheck();
        }

        for(int x = 1; x< nFieldWidth-1;x++){
            if(pField[(nFieldHeight-2)*nFieldWidth+x]==8){
                pField[(nFieldHeight-2)*nFieldWidth+x]=0;
                if(x==nFieldWidth-2){
                    shiftGridDown = true;
                    score+=100;
                }
            }
        }

        for(int k = 0;k<4;k++){                              //  R   L   D  Z
            key[k] = (0x8000 & GetAsyncKeyState((unsigned char)("DASZ"[k]))) != 0;
        }
        if(key[1]){
            if(doesPieceFit(currentPiece,currentRotation,currentX-1,currentY)){
                currentX = currentX-1;
            }
        }else if(key[0]){
            if(doesPieceFit(currentPiece,currentRotation,currentX+1,currentY)){
                currentX = currentX+1;
            }
        }if(key[2]){
            speedCounter = speed;
        }
        if(key[3]&&doesPieceFit(currentPiece,currentRotation+90,currentX,currentY)){
            (currentRotation+90<=270)?currentRotation+=90:currentRotation=0;
        }

        if(forcePieceDown){
            if(doesPieceFit(currentPiece,currentRotation,currentX,currentY+1))
                currentY++;
            else {
                //lock piece
                pieceCounter++;
                if(pieceCounter%5==0){
                    speed-=1;
                }
                for(int px = 0;px<4;px++){
                    for(int py = 0;py<4;py++){
                        if(tetromine[currentPiece][rotate(px,py,currentRotation)]==L'X'){
                            pField[(currentY+py)*nFieldWidth+(currentX+px)] = currentPiece+1;
                        }
                    }
                }
                score+=20;
                //check lines
                lineCheck();

                //get next piece
                currentX = nFieldWidth/2;
                currentY = 0;
                currentRotation = 0;
                srand(time(0));
                currentPiece = rand() % 7;

                //check game over
                gameOver = !doesPieceFit(currentPiece,currentRotation,currentX,currentY);
            }
        }

        //draw field
        for(int x = 0; x < nFieldWidth; x++)
        {
            for(int y = 0; y < nFieldHeight; y++)
            {
                screen[(y+2)*nScreenWidth + (x+  2)] = L" xxxxxxx=#"[pField[y*nFieldWidth + x]];
            }
        }

        //draw piece
        for(int px = 0;px<4;px++){
            for(int py = 0;py<4;py++){
                    if(tetromine[currentPiece][rotate(px,py,currentRotation)] == L'X'){
                        screen[(currentY+py+2)*nScreenWidth+(currentX+px+2)] = '+';
                    }
            }
        }
        string s("Score -> ");
        string num;
        int tmp = score;
        while(tmp!=0){
            int rem = tmp%10;
            tmp /= 10;
            num = ((char)(48+rem)) + num;
        }
        s+=num;
        for(int i = 0; i<s.size();i++){
            screen[i] = s[i];
        }

        //display frame
        WriteConsoleOutputCharacter(hConsole, (LPCWSTR)screen, nScreenWidth * nScreenHeight,here, &dwBytesWritten);
    }

    return 0;
}

This is the origional code :

#include <iostream>
#include <time.h>
#include <string>
#include <windows.h>
using namespace std;

int nScreenHeight = 30;
int nScreenWidth = 80;
int nFieldWidth = 10;
int nFieldHeight = 25;
unsigned char *pField = NULL;
wstring tetromine[7];

int currentPiece = 0;
int currentRotation = 0;
int currentX = (nFieldWidth/2);
int currentY = 0;
unsigned int score = 0;

int pieceCounter = 0;
int speed = 20;
int speedCounter = 0;
bool forcePieceDown =false;
bool key[4];
bool shiftGridDown = false;

int rotate(int px,int py,int r)
{
    switch(r/90)
    {
    case 0:
        return py*4+px;//0 degs
    case 1:
        return 12+py - (px*4);//90 degs
    case 2:
        return 15 - (py*4) - px;//180 degs
    case 3:
        return 3 - py + (px*4);//270 degs
    }
    return 0;
}

int doesPieceFit(int id,int rot, int x, int y)
{
    for(int px = 0;px<4;px++){
        for(int py = 0;py<4;py++){
            int pi = rotate(px,py,rot);
            int fi = (y+py) * nFieldWidth + (x+px);
            if(x + px>= 0 && x+px < nFieldWidth){
                if(tetromine[id][pi] == L'X' && pField[fi]!=0){
                    return false;
                }
            }
        }
    }
    return true;
}

void lineCheck(){
    bool line = true;
    int lines = 0;
    for(int y = 0; y<= nFieldHeight-1;y++){
        for(int x = 1; x< nFieldWidth-1;x++){
            if(pField[(y)*nFieldWidth+x]!=0){
                line &= true;
            } else line &= false;
        }
        if(line) lines++;
        if(line){
            for(int x = 1; x< nFieldWidth-1;x++){
                pField[(y)*nFieldWidth+x] = 8;
            }
        }
    }
}


int main()
{

    //assets
    tetromine[0].append(L"..X.");
    tetromine[0].append(L"..X.");
    tetromine[0].append(L"..X.");
    tetromine[0].append(L"..X.");

    tetromine[1].append(L"..X.");
    tetromine[1].append(L".XX.");
    tetromine[1].append(L".X..");
    tetromine[1].append(L"....");

    tetromine[2].append(L".X..");
    tetromine[2].append(L".XX.");
    tetromine[2].append(L"..X.");
    tetromine[2].append(L"....");

    tetromine[3].append(L"....");
    tetromine[3].append(L".XX.");
    tetromine[3].append(L".XX.");
    tetromine[3].append(L"....");

    tetromine[4].append(L"..X.");
    tetromine[4].append(L".XX.");
    tetromine[4].append(L"..X.");
    tetromine[4].append(L"....");

    tetromine[5].append(L"....");
    tetromine[5].append(L".XX.");
    tetromine[5].append(L"..X.");
    tetromine[5].append(L"..X.");

    tetromine[6].append(L"....");
    tetromine[6].append(L".XX.");
    tetromine[6].append(L".X..");
    tetromine[6].append(L".X..");

    pField = new unsigned char[nFieldWidth*nFieldHeight];
    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;
        }
    }

    char *screen = new char [nScreenWidth * nScreenHeight];
    HANDLE hConsole = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
    SetConsoleActiveScreenBuffer(hConsole);
    DWORD dwBytesWritten = 0;

    //Display frame

    WriteConsoleOutputCharacter(hConsole, screen, nScreenWidth * nScreenHeight, {0,0}, &dwBytesWritten);

    bool gameOver = false;

    while(!gameOver)
    {
        Sleep(100);
        speedCounter++;
        if(speedCounter>=speed){
            forcePieceDown = true;
            speedCounter = 0;
        } else {
            forcePieceDown = false;
        }

        if(shiftGridDown){
            score++;
            for(int y = nFieldHeight-2;y > 0;y--){
                for(int x = 1;x<nFieldWidth -1;x++){
                    if((pField[(y)*nFieldWidth+x]) != 0){
                        pField[(y+1)*nFieldWidth+x] = pField[(y)*nFieldWidth+x];
                        pField[(y)*nFieldWidth+x] = 0;
                    }
                }
            }
            shiftGridDown = false;
            lineCheck();
        }

        for(int x = 1; x< nFieldWidth-1;x++){
            if(pField[(nFieldHeight-2)*nFieldWidth+x]==8){
                pField[(nFieldHeight-2)*nFieldWidth+x]=0;
                if(x==nFieldWidth-2){
                    shiftGridDown = true;
                    score+=100;
                }
            }
        }

        for(int k = 0;k<4;k++){                              //  R   L   D  Z
            key[k] = (0x8000 & GetAsyncKeyState((unsigned char)("DASZ"[k]))) != 0;
        }
        if(key[1]){
            if(doesPieceFit(currentPiece,currentRotation,currentX-1,currentY)){
                currentX = currentX-1;
            }
        }else if(key[0]){
            if(doesPieceFit(currentPiece,currentRotation,currentX+1,currentY)){
                currentX = currentX+1;
            }
        }if(key[2]){
            speedCounter = speed;
        }
        if(key[3]&&doesPieceFit(currentPiece,currentRotation+90,currentX,currentY)){
            (currentRotation+90<=270)?currentRotation+=90:currentRotation=0;
        }

        if(forcePieceDown){
            if(doesPieceFit(currentPiece,currentRotation,currentX,currentY+1))
                currentY++;
            else {
                //lock piece
                pieceCounter++;
                if(pieceCounter%5==0){
                    speed-=1;
                }
                for(int px = 0;px<4;px++){
                    for(int py = 0;py<4;py++){
                        if(tetromine[currentPiece][rotate(px,py,currentRotation)]==L'X'){
                            pField[(currentY+py)*nFieldWidth+(currentX+px)] = currentPiece+1;
                        }
                    }
                }
                score+=20;
                //check lines
                lineCheck();

                //get next piece
                currentX = nFieldWidth/2;
                currentY = 0;
                currentRotation = 0;
                srand(time(0));
                currentPiece = rand() % 7;

                //check game over
                gameOver = !doesPieceFit(currentPiece,currentRotation,currentX,currentY);
            }
        }

        //draw field
        for(int x = 0; x < nFieldWidth; x++)
        {
            for(int y = 0; y < nFieldHeight; y++)
            {
                screen[(y+2)*nScreenWidth + (x+  2)] = L" xxxxxxx=#"[pField[y*nFieldWidth + x]];
            }
        }

        //draw piece
        for(int px = 0;px<4;px++){
            for(int py = 0;py<4;py++){
                    if(tetromine[currentPiece][rotate(px,py,currentRotation)] == L'X'){
                        screen[(currentY+py+2)*nScreenWidth+(currentX+px+2)] = '+';
                    }
            }
        }
        string s("Score -> ");
        string num;
        int tmp = score;
        while(tmp!=0){
            int rem = tmp%10;
            tmp /= 10;
            num = ((char)(48+rem)) + num;
        }
        s+=num;
        for(int i = 0; i<s.size();i++){
            screen[i] = s[i];
        }

        //display frame
        WriteConsoleOutputCharacter(hConsole, screen, nScreenWidth * nScreenHeight, { 0, 0}, &dwBytesWritten);
    }

    return 0;
}

Solution

  • You have a mix of narrow and wide characters. The cast (LPCWSTR)screen in your call to WriteConsoleOutputCharacter is an indication something isn't right.

    In this case, screen is a char but you want it to be wchar_t instead. You're already using wstring for tetromine, and L prefixed character strings. You just need to ensure the rest of the code is also using wide characters.