(Chrono Time) Минутная ошибка обнаружения тиков - PullRequest
0 голосов
/ 08 апреля 2020

В моем коде есть оператор if, который должен определять, превышает ли мой chrono :: duration одну минуту времени выполнения. Когда оператор if становится истинным, он должен вывести «Tick!» только один раз, но моя программа выводит "Tick!" каждый раз, когда delta__time превышает одну минуту, даже если я вычту из него 60 секунд. Возможно, вам придется посмотреть на фотографию, чтобы получить лучшее представление о проблеме. Я все еще работаю над объяснением вещей, и это только мой второй пост на сайте. Как заставить мой код печатать галочку только раз в минуту? Большое спасибо.

int main()
{
    // Create Screen Buffer
    wchar_t* screen = new wchar_t[nScreenWidth * nScreenHeight];
    HANDLE hConsole = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
    //SetConsoleActiveScreenBuffer(hConsole);
    DWORD dwBytesWritten = 0;

    wstring numberSystem[10] = {
    };

    while (1)
    {
        tp2 = chrono::system_clock::now();
        chrono::duration<long double, ratio<60>> delta__time = tp2 - tp1;

    if (delta__time >= 60s)
        {
            delta__time -= 60s;
            cout << "Tick!\t" << delta__time.count() << endl;
        }
        else {
            cout << delta__time.count() << endl;
        }
        // Handle change in time here.
    }

    return 0;
}

Ошибка определения тика в хронологическом времени

Ответы [ 3 ]

0 голосов
/ 08 апреля 2020

Как сказал @drescherjm, ваша проблема в том, что -= 60s; отбрасывается, так как вы пересчитываете время дельты для каждой итерации.

using namespace std::literals;

auto start_time = std::chrono::system_clock::now();
long ticks = 0;
while (1)
{
  auto current_time = std::chrono::system_clock::now();
  std::chrono::duration<long double, std::ratio<60>> delta_time = current_time - start_time;
  delta_time -= ticks * 60s; // note that `ticks` adds up.

  if (delta_time >= 60s)
  {
    ++ticks;
    std::cout << "Tick!\t" << delta_time.count() << std::endl;
  } else {
    std::cout << delta_time.count() << std::endl;
  }
  // Handle change in time here.
}

Я сохранил start_time как неизменное время начала и current_time То же самое, вместо того, чтобы делать что-то вроде добавления к tp1. Это заставляет задуматься о том, что эти переменные действительно просты.

0 голосов
/ 12 апреля 2020

Чтобы закрыть этот пост ... Я продолжил и добавлял 60-е к переменной tp1 для каждой минуты, которая происходит. Спасибо! :)

Здесь был окончательный код.

#include <iostream>
#include <chrono>
using namespace std;

#include <Windows.h>

int nScreenWidth = 240;
int nScreenHeight = 80;

int nMapWidth = 8;
int nMapHeight = 5;

int main()
{
    // Create Screen Buffer
    wchar_t* screen = new wchar_t[nScreenWidth * nScreenHeight];
    HANDLE hConsole = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
    SetConsoleActiveScreenBuffer(hConsole);
    DWORD dwBytesWritten = 0;

    // Current Time
    int hourDoubleDigit = 1;
    int hourSingleDigit = 2;
    int minuteDoubleDigit = 0;
    int minuteSingleDigit = 0;

    // Character Mapping
    wstring numberSystem[10] = {
    };

    numberSystem[0] += L"########"; numberSystem[1] += L"      ##"; numberSystem[2] += L"########";
    numberSystem[0] += L"##   ###"; numberSystem[1] += L"      ##"; numberSystem[2] += L"      ##";
    numberSystem[0] += L"## ## ##"; numberSystem[1] += L"      ##"; numberSystem[2] += L"########";
    numberSystem[0] += L"###   ##"; numberSystem[1] += L"      ##"; numberSystem[2] += L"##      ";
    numberSystem[0] += L"########"; numberSystem[1] += L"      ##"; numberSystem[2] += L"########";

    numberSystem[3] += L"########"; numberSystem[4] += L"##    ##"; numberSystem[5] += L"########";
    numberSystem[3] += L"      ##"; numberSystem[4] += L"##    ##"; numberSystem[5] += L"##      ";
    numberSystem[3] += L"########"; numberSystem[4] += L"########"; numberSystem[5] += L"########";
    numberSystem[3] += L"      ##"; numberSystem[4] += L"      ##"; numberSystem[5] += L"      ##";
    numberSystem[3] += L"########"; numberSystem[4] += L"      ##"; numberSystem[5] += L"########";

    numberSystem[6] += L"########"; numberSystem[7] += L"########"; numberSystem[8] += L"########"; numberSystem[9] += L"########";
    numberSystem[6] += L"##      "; numberSystem[7] += L"      ##"; numberSystem[8] += L"##    ##"; numberSystem[9] += L"##    ##";
    numberSystem[6] += L"########"; numberSystem[7] += L"      ##"; numberSystem[8] += L"########"; numberSystem[9] += L"########";
    numberSystem[6] += L"##    ##"; numberSystem[7] += L"      ##"; numberSystem[8] += L"##    ##"; numberSystem[9] += L"      ##";
    numberSystem[6] += L"########"; numberSystem[7] += L"      ##"; numberSystem[8] += L"########"; numberSystem[9] += L"########";

    // Keeping Track of System Time
    auto tp1 = chrono::system_clock::now();
    auto tp2 = chrono::system_clock::now();

    auto TickInterval = 60s;

    while (1)
    {
        for (int xy = 0; xy <= nScreenWidth * nScreenHeight; xy++) screen[xy] = ' ';//To prevent buggy character spawning...
        // You don't always have to write this above line if you're already making use of writing characters to every space in the screen, but I'm not!


        // Let the program know a minute has passed... (Time passes too much too often)
        tp2 = chrono::system_clock::now();
        chrono::duration<long double> delta__time = tp2 - tp1;
        bool TICKhasOCCURED = false;

        if (delta__time >= TickInterval)
        {
            tp1 += TickInterval;
            TICKhasOCCURED = true;
        }

        if (TICKhasOCCURED)
        {
            if (minuteSingleDigit >= 9)
            {
                if (minuteDoubleDigit >= 5)
                {

                    if (hourSingleDigit >= 9 && hourDoubleDigit == 0)
                    {
                        hourDoubleDigit++;
                        hourSingleDigit = 0;
                        minuteDoubleDigit = 0;
                        minuteSingleDigit = 0;
                    }
                    else if (hourSingleDigit >= 2 && hourDoubleDigit == 1)
                    {
                        hourDoubleDigit = 0;
                        hourSingleDigit = 1;
                        minuteDoubleDigit = 0;
                        minuteSingleDigit = 0;

                    }
                    else {
                        hourSingleDigit++;
                        minuteDoubleDigit = 0;
                        minuteSingleDigit = 0;
                    }//After 59 minutes check the hour and change it.
                }
                else {
                    minuteDoubleDigit++;
                    minuteSingleDigit = 0;
                }
            }
            else {
                minuteSingleDigit++;
            }
        }


        // The Current Time is then drawn out using the mapped characters.
        for(int ix = 0; ix < nMapWidth; ix++)
            for (int iy = 0; iy < nMapHeight; iy++)
            {
                screen[00 + ix + (nScreenWidth * iy)] = numberSystem[hourDoubleDigit][ix + (nMapWidth * iy)];
                screen[10 + ix + (nScreenWidth * iy)] = numberSystem[hourSingleDigit][ix + (nMapWidth * iy)];
                screen[20 + ix + (nScreenWidth * iy)] = numberSystem[minuteDoubleDigit][ix + (nMapWidth * iy)];
                screen[30 + ix + (nScreenWidth * iy)] = numberSystem[minuteSingleDigit][ix + (nMapWidth * iy)];
            }


        //Debug
        //cout << hourDoubleDigit << "\t" << hourSingleDigit << "\t" << minuteDoubleDigit << "\t" << minuteSingleDigit << endl;
        TICKhasOCCURED = false;

        screen[nScreenWidth * nScreenHeight-1] = '\0';
        WriteConsoleOutputCharacter(hConsole, screen, nScreenWidth * nScreenHeight, { 0,0 }, &dwBytesWritten);
    }

    return 0;
}
0 голосов
/ 08 апреля 2020

delta__time пересчитывается в начале каждой итерации l oop, поэтому изменения в нем не будут иметь длительного эффекта (хотя это влияет на cout сразу после него, поэтому ваши значения кажутся низкими ).

Можно вместо sh добавить 60 с tp1 (или установить now(), хотя это приводит к ошибкам).

...