C++ Update console output

旧街凉风 提交于 2019-11-29 13:03:31

Standard C++ does not support setting individual characters at positions in the console without re-printing. This is OS-specific, and there are comments that address this.

Otherwise, the correct solution is to encapsulate your game board logic into a class. We can use a nested std::vector to handle a dynamically-sized board, and provide functions for getting and setting cells. A separate Print function allows us to print the board to the console as often as we'd like.

class Grid
{
    public:
    Grid(int size) : myGrid(size, std::vector<int>(size, 0)) // initialize grid to be correctly sized and all zeros
    {
       Randomize();
    }

    void Randomize()
    {
        for (size_t i=0;i<myGrid.size();i++)
        {
            for (size_t j=0;j<myGrid[i].size();j++)
            {
                myGrid[i][j] = rand() % 9 + 1;
            }
        }
    }

    void Print(std::ostream& out) const
    {
        out<<"\n\tPuzzle\n\t";
        for(size_t i=0;i<myGrid.size();i++)
        {
           out<<i<<" ";
        }
        out << "\n\n";
        for(size_t i=0;i<myGrid.size();i++)
        {
            out<<i<<"\t";
            for(size_t j=0;j<myGrid[i].size();j++)
            {
                out<<myGrid[i][j]<<" ";
            }
            out<<"\n";
        }
    }

    int GetValue(size_t row, size_t col) const
    {
        // use wraparound for too-large values
        // alternatively you could throw if row and/or col are too large
        return myGrid[row % myGrid.size()][col % myGrid.size()];
    }

    void SetValue(size_t row, size_t col, int val)
    {
        myGrid[row % myGrid.size()][col % myGrid.size()] = val;
    }

    private:
    std::vector<std::vector<int>> myGrid;         
};

Now you can write your main like so:

int main()
{
    srand(time(NULL));
    Grid board(10);
    size_t xValue = 0;
    size_t yValue = 0;

    // game loop. You could even abstract this behavior into another class
    while(true)
    {
        board.Print(std::cout);
        std::cout<<"\nEnter x value: ";
        if (!std::cin) // check for no input
            break;
        std::cin>>xValue;
        if (!std::cin) // check for end of input
           break;
        std::cout<<"Enter y value: ";
        std::cin>>yValue;
        if (!std::cin)
            break;
        board.SetValue(xValue, yValue, 0);

        // other game logic...
    }

    // print board one last time before exit
    std::cout << "Game over. Final board: \n";
    board.Print(std::cout);
}

Live Demo

No, output to the "cout" screen by itself doesn't allow you to change screen contents arbitrarily.

The simplest thing is to redraw the entire gameboard after each move.

To use the terminal as a window, you would have to use a library like "curses", which will understand your terminal (including things like what control codes it uses, and how large it is)

For example, see http://hughm.cs.ukzn.ac.za/~murrellh/os/notes/ncurses.html

If your console supports ANSI escape codes, you can go up multiple lines and re-print them, e. g. like this:

printf("hello\n");
printf("\x1b[A"); // you can add the number of lines: "\x1b[7A"
printf("hola \n");

This works under most linux shells, Windows, however, does not support it until Win10.

Just use system("cls");

Then update the 2D array, and reprint it.

Hope it works :).

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!