首页 > 解决方案 > 如何正确更新控制台输出?

问题描述

我有一个扫雷代码(不是我的),我对其进行了一些改进,但我无法真正理解如何正确更新控制台输出,因此在输入值后网格不会打印很多次。这将真正优化游戏并实时显示计时器。有人可以解释一下吗?

#include<iostream>
#include<time.h>
#include<stdlib.h>
#include<stdio.h>
#include<iomanip>
#include <time.h>

using namespace std;

void reveal(int, int);  
void create_mine_positions();
void cell_number(); 
void create_table(); 
void open_cell(); 
void game();
void print_table(char); 

char table[10][10]; 
char table_mine_positions[10][10]; 
char symbol; 
int flag_counter = 0;
int mines_flagged_counter = 0;
bool end_game_lose = false;
time_t time_since_epoch = time(0);
time_t game_time;

void cell_number(int i, int j)
{
    if (i >= 0 && i < 10 && j >= 0 && j < 10 && table_mine_positions[i][j] != 'X')
        table_mine_positions[i][j]++;
}

void create_mine_positions()
{
    int counter = 0;
    srand(time(NULL));

    for (int i = 0;i < 10;i++)
        for (int j = 0;j < 10;j++)
            table_mine_positions[i][j] = '0';

    int i = 0;
    int j = 0;
    while (counter < 10)
    {
        int i = rand() % 10;
        int j = rand() % 10;
        if (table_mine_positions[i][j] == '0') {
            table_mine_positions[i][j] = 'X';

            cell_number(i - 1, j);
            cell_number(i + 1, j);
            cell_number(i, j - 1);
            cell_number(i, j + 1);
            cell_number(i - 1, j - 1);
            cell_number(i - 1, j + 1);
            cell_number(i + 1, j - 1);
            cell_number(i + 1, j + 1);
            counter++;
        }
    }
}

void create_table()
{
    for (int i = 0;i < 10;i++)
        for (int j = 0;j < 10;j++)
            table[i][j] = '*';
}

void print_table(char arr[10][10])
{
    cout << "    ";
    for (int i = 0;i < 10;i++)
        cout << setw(3) << i;

    cout << endl << "  ";
    for (int i = 0;i < 32;i++)
        cout << "_";
    cout << endl;

    for (int i = 0;i < 10;i++) {
        cout << setw(3) << i << "|";
        for (int j = 0;j < 10;j++)
            cout << setw(3) << arr[i][j];
        cout << endl;
    }
}

void open_cell()
{
    int i, j;

    do
        cin >> i >> j;
    while (i < 0 || i>9 || j < 0 || j>9);

    if (table_mine_positions[i][j] == 'X')
    {
        table[i][j] = 'X';
        end_game_lose = true;

        for (int i = 0;i < 10;i++)
            for (int j = 0;j < 10;j++)
                if (table_mine_positions[i][j] == 'X')
                    table[i][j] = 'X';
    }
    else
        reveal(i, j);
}

void place_or_remove_flag()
{
    int i, j;
    do {
        cin >> i >> j;
        if (cin.fail())
        {
            cin.clear();
            cin.ignore();
        }
    } while (i < 0 || i>9 || j < 0 || j>9);

    if (table[i][j] == '*')
    {
        table[i][j] = 'F';
        flag_counter++;

        if (table_mine_positions[i][j] == 'X')
            mines_flagged_counter++;
    }

    else if (table[i][j] == 'F')
    {
        table[i][j] = '*';
        flag_counter--;
        if (table_mine_positions[i][j] == 'X')
            mines_flagged_counter--;
    }
}

void input_symbol()
{
    cin >> symbol;
    switch (symbol) {
    case 'o': open_cell(); break;
    case 'f': place_or_remove_flag(); break;
    default: input_symbol();
    }
}

void reveal(int i, int j)
{
    if (table[i][j] == '*' && table_mine_positions[i][j] != 'X' && i >= 0 && i < 10 && j >= 0 && j < 10)
    {
        table[i][j] = table_mine_positions[i][j];

        if (table_mine_positions[i][j] == '0')
        {
            reveal(i, j - 1);
            reveal(i, j + 1);
            reveal(i - 1, j - 1);
            reveal(i + 1, j - 1);
            reveal(i + 1, j + 1);
            reveal(i - 1, j + 1);
            reveal(i - 1, j);
            reveal(i + 1, j);
        }
    }
}

bool end_game_win_check()
{
    if (flag_counter == 10 && mines_flagged_counter == 10)
        return 1;
    else
        return 0;
}

void game()
{
    create_table();
    create_mine_positions();

    while (!end_game_lose && !end_game_win_check())
    {
        game_time = time(0);
        print_table(table);
        cout << endl << "Flags:" << flag_counter << endl;
        cout << "Time:" << game_time - time_since_epoch << endl;
        input_symbol();
    }

    if (end_game_lose) {
        print_table(table);
        cout << endl << "GAME OVER" << endl;
    }

    if (end_game_win_check())
        cout << "Time to complete:" << game_time - time_since_epoch << endl;
    cout << endl << "YOU WIN!" << endl;
}

int main()
{
    cout
        << "C O N S O L E - B A S E D   M I N E S W E E P E R"
        << endl << "How to play:"
        << endl << "Enter 'o' , then enter value of i and j to open cell[i][j]."
        << endl << "Enter 'f' ,then enter value of i and j to place "
        << "or remove flag on cell [i][j]."
        << endl << endl;

    game();

    return 0;
}

网格下方还有一个计时器,它仅在移除图块后才会更新,如果控制台以某种方式不断更新,这样即使与游戏没有任何交互,计时器也会继续运行。

输出:

首先是游戏名称

然后指令

然后网格

标志(如果使用)

然后是仅在给出值时才更新的计时器。

标签: c++

解决方案


推荐阅读