Martijn de Jong
Martijn de Jong

Reputation: 1

Trying to make a primitive console snake game. 0 warnings/erros. Why does my program crash? (C++)

Thank you for reading this thread. I am a beginning programmer and am trying to make a simple snake game with C++. It isn't finished yet, but I think I got a nice start to it. However, when I try to run the program it instantly crashes. (The compiler says there are 0 warnings and errors. I am using the Code::Blocks IDE. Does anyone know why my program isn't working? I think it may have something to do with the "vector coordHistory", but I can't tell for sure. At least that is the last thing I added to the program.

This is my code:

    #include <iostream>
    #include <cstdlib>
    #include <string>
    #include <cstdio>
    #include <windows.h>
    #include <conio.h>
    #include <vector>

    #define MAXX 156 //Number of columns that fits on my screen
    #define MAXY 62 //Number of rows that fits on my screen

    using namespace std;

    // This function clears the console window
    void clearConsole()
    {
        system("cls"); //empties console window
    };

    // This function returns the x position of the cursor
    int getcursorX()
    {
        CONSOLE_SCREEN_BUFFER_INFO csbi;
        if(GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi)) {
            return csbi.dwCursorPosition.X;
        }
    };

    // This function returns the y position of the cursor
    int getcursorY()
    {
        CONSOLE_SCREEN_BUFFER_INFO csbi;
        if(GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi)) {
            return csbi.dwCursorPosition.Y;
        }
    };

    // This function sets the x position of the cursor
    void setcursorX(int x)
    {
        COORD coord = {x, getcursorY()};
        SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
    }

    // This function sets the y position of the cursor
    void setcursorY(int y)
    {
        COORD coord = {getcursorX(), y};
        SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
    }

    // The snake class contains the coordinates of the snake and direction         in which it is moving
    class Snake
    {
    private:
        bool isAlive;
        int snakexCoord;
        int snakeyCoord;
        char snakeDirection;
        int snakeLength;

    public:
        //getters
        int getsnakexCoord() { return snakexCoord; };
        int getsnakeyCoord() { return snakeyCoord; };
        char getsnakeDirection() { return snakeDirection; };
        bool getisAlive() { return isAlive; };
        int getsnakeLength() { return snakeLength; };
        //setters
        void setsnakexCoord(int newsnakexCoord) { snakexCoord = newsnakexCoord;};
        void setsnakeyCoord(int newsnakeyCoord) { snakeyCoord = newsnakeyCoord;};
        void setsnakeDirection(char newsnakeDirection) { snakeDirection = newsnakeDirection;};
        void setisAlive(bool newisAlive) { isAlive = newisAlive; };
        void setsnakeLength(int newsnakeLength) { snakeLength = newsnakeLength; };
        //constructor
        Snake()
        {
            snakexCoord = MAXX / 2;
            snakeyCoord = MAXY / 2;
            snakeDirection = 'E';
            isAlive = true;
            snakeLength = 1;
        };
        //destructor
        ~Snake(){};
    };

    int main()
    {
        int i; //iterator
        system("mode 650"); //makes console window full-screen
        Snake snake; //initializes Snake object snake
        char c; //char that stores user input to change snake direction
        vector<int[2]> coordHistory; //vector of arrays that stores previous         locations of snake
        while (snake.getisAlive())
        {
            //Adds snake coordinates to coordHistory
            coordHistory[coordHistory.size()][0] = snake.getsnakexCoord();
            coordHistory[coordHistory.size()-1][1] = snake.getsnakeyCoord();

            //Iterates backwards through coordHistory and draws an "O" until the snake is as long as it should be
            for(i = coordHistory.size() - 1; i > coordHistory.size() - 1 - snake.getsnakeLength(); i--)
            {
                setcursorX(coordHistory[i][0]);
                setcursorY(coordHistory[i][1]);
                cout << "O";
            }

            //Allows user to change snake direction
            c = _getch();
            switch (c){
            case 'w':
                snake.setsnakeDirection('N');
                break;
            case 'd':
                snake.setsnakeDirection('E');
                break;
            case 's':
                snake.setsnakeDirection('S');
                break;
            case 'a':
                snake.setsnakeDirection('W');
                break;
            }

            //Checks in which direction snake is going and changes coordinates accordingly
            switch (snake.getsnakeDirection())
            {
            case 'N':
                snake.setsnakeyCoord(snake.getsnakeyCoord()-1);
                break;
            case 'E':
                snake.setsnakexCoord(snake.getsnakexCoord()+1);
                break;
            case 'S':
                snake.setsnakeyCoord(snake.getsnakeyCoord()+1);
                break;
            case 'W':
                snake.setsnakexCoord(snake.getsnakexCoord()-1);
                break;
            }
            //Checks if snake goes out of boundaries
            if ((snake.getsnakexCoord() > MAXX) || (snake.getsnakexCoord() < 0) || (snake.getsnakeyCoord() > MAXY) || (snake.getsnakeyCoord() < 0))
            {
                snake.setisAlive(false);
            }
            //Sleep(200); Ignore WIP
            clearConsole();
        }
        return 0;
    }

Upvotes: 0

Views: 111

Answers (1)

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385405

Your vector usage is wrong.

coordHistory[coordHistory.size()][0] = snake.getsnakexCoord();
coordHistory[coordHistory.size()-1][1] = snake.getsnakeyCoord();

You appear to assume that vector[n-1] will automatically create as many elements as needed to result in a vector of size n. It doesn't.

You are twice accessing the first element of vector coordHistory, a vector which is actually empty.

To add elements, in general use the member function push_back or emplace_back. You're really going to struggle with a vector of arrays, though, since arrays are neither assignable nor copyable. That's why I can't use push_back here; I have to explicitly resize the vector then access the newly-created elements as you were doing before:

coordHistory.resize(1);
coordHistory[0][0] = snake.getsnakexCoord();
coordHistory[0][1] = snake.getsnakeyCoord();

This is pretty awkward. why don't you instead store a nice delicious class type with x and y members?

std::vector<deliciousClassType> coordHistory;
coordHistory.emplace_back(
   snake.getsnakexCoord(),
   snake.getsnakeyCoord()
);

Upvotes: 1

Related Questions