简体   繁体   English

C ++更新控制台输出

[英]C++ Update console output

I'm trying to make a program to print out a grid and given x and y co-ordinates change a value in the grid. 我正在尝试制作一个程序以打印出网格,并给出x和y坐标来更改网格中的值。 For example, if the user entered X:0 and Y:0 it would change the value '9' in the image below to a predefined value (in this case I want to change the value 9 to 0). 例如,如果用户输入X:0和Y:0,则会将下图中的值“ 9”更改为预定义值(在这种情况下,我想将值9更改为0)。

在此处输入图片说明

My question is, is it possible to update the output of the console so that the '0' would override the '9' without printing out the entire grid again. 我的问题是,是否可以更新控制台的输出,以使“ 0”将覆盖“ 9”,而无需再次打印出整个网格。 I want to be able to do this multiple times. 我希望能够多次执行此操作。

If that is not possible, how can I print out the updated grid the way I have implemented this? 如果无法做到这一点,我该如何以实现方式打印出更新的网格? If I were to put the display grid for loop in a separate function I would need to call the 2d array as a parameter which I'm sure you cannot do. 如果将显示网格循环放在一个单独的函数中,则需要调用2d数组作为参数,我确定您不能这样做。

Here is what I have: 这是我所拥有的:

void generateGrid(int diff){
        srand(time(NULL));
        int arr[maximum][maximum];
            for (int i=0;i<diff;i++)
        {
            for (int j=0;j<diff;j++)
            {
                arr[i][j] = rand() % 9 + 1;
            }
        }
        cout<<"\n\tPuzzle\n\t";
            for(int i=0;i<diff;i++)
            {
                cout<<i<<" ";
            }
                cout<<"\n\n";
            for(int i=0;i<diff;i++)
            {
                cout<<i<<"\t";
                for(int j=0;j<diff;j++)
                {
                    cout<<arr[i][j]<<" ";
                }
                    cout<<"\n";
            }
       int x, y;
        cout<<"\nEnter x value: ";
        cin>>x;
        cout<<"Enter y value: ";
        cin>>y;
        arr[x][y] = 0;
    }

Diff refers to the puzzle size (difficulty) 差异是指拼图的大小(难度)

Elsewhere: 别处:

int easy = 5;
int medium = 8;
int hard = 10;
int maximum = 10;

Standard C++ does not support setting individual characters at positions in the console without re-printing. 标准C ++不支持在控制台中的各个位置设置单个字符,而无需重新打印。 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. 我们可以使用嵌套的std::vector来处理动态尺寸的电路板,并提供获取和设置单元格的功能。 A separate Print function allows us to print the board to the console as often as we'd like. 单独的“ Print功能使我们可以根据需要多次将板子打印到控制台。

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: 现在,您可以像这样编写main

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. 不,仅输出到“ cout”屏幕本身不允许您随意更改屏幕内容。

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) 要将终端用作窗口,您必须使用“ curses”之类的库,该库将了解您的终端(包括诸如它使用什么控制代码以及它有多大等内容)。

For example, see http://hughm.cs.ukzn.ac.za/~murrellh/os/notes/ncurses.html 例如,请参见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, eg like this: 如果您的控制台支持ANSI转义码 ,则可以多行显示并重新打印它们,例如:

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. 这在大多数linux shell下都有效,但是Windows直到Win10才支持它。

Just use system("cls"); 只需使用system(“ cls”);

Then update the 2D array, and reprint it. 然后更新2D阵列,然后重新打印。

Hope it works :). 希望它能工作:)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM