C 更新控制台输出

新手上路,请多包涵

我正在尝试制作一个程序来打印出一个网格,并给定 x 和 y 坐标改变网格中的一个值。例如,如果用户输入 X:0 和 Y:0,它会将下图中的值“9”更改为预定义的值(在这种情况下,我想将值 9 更改为 0)。

在此处输入图像描述

我的问题是,是否可以更新控制台的输出,以便“0”覆盖“9”而无需再次打印出整个网格。我希望能够多次这样做。

如果这是不可能的,我怎样才能按照我实现这个的方式打印出更新的网格?如果我要将显示网格 for 循环 放在一个单独的函数中,我需要将 2d 数组作为参数调用,我确信你不能这样做。

这是我所拥有的:

 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 是指拼图大小(难度)

别处:

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

原文由 GordanAndrews 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.2k
2 个回答

标准 C++ 不支持在控制台中的位置设置单个字符而不重新打印。这是特定于操作系统的,并且有一些评论可以解决这个问题。

否则,正确的解决方案是将您的游戏板逻辑封装到一个类中。我们可以使用嵌套的 std::vector 来处理动态大小的板,并提供获取和设置单元格的功能。一个单独的 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;
};

现在你可以像这样写你的 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);
}

现场演示

原文由 AndyG 发布,翻译遵循 CC BY-SA 3.0 许可协议

如果 您的控制台支持 ANSI 转义码,您可以向上多行并重新打印它们,例如:

 printf("hello\n");
printf("\x1b[A");  // you can add the number of lines: "\x1b[7A"
printf("hola \n"); // add sufficient spaces to overwrite previous output!

这适用于大多数 linux shell,但是 Windows 直到 Win10 才支持它。

原文由 Aconcagua 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题