3

私は現在 C++ で Tetris をプログラミングしています。現在、プログラムを書き終えた段階ですが、いくつかのバグを修正してパフォーマンスを最適化する必要があります。

そうは言っても、私のプログラムの欠点の 1 つは、1 秒間に 1 回のキー操作しか処理できないことです。少なくとも3つを処理する必要があります。このコードで示された欠陥を確認できます。

//Most headers only pertain to my main program.
#include <iostream>
#include <termios.h>
#include <pthread.h>
#include <time.h>
#include <cstring>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

using namespace std;

//Timer function.
void *Timer(void*) {

    time_t time1, time2;

    time1 = time(NULL);

    while (time2 - time1 < 1) {
        time2 = time(NULL);
    }

    pthread_exit(NULL);
}

int main() {

    //Remove canonical buffering.
    struct termios t_old, t_new;
    tcgetattr(STDIN_FILENO, &t_old);
    t_new = t_old;
    t_new.c_lflag &= (~ICANON & ~ECHO);
    tcsetattr(STDIN_FILENO, TCSANOW, &t_new);

    const int STDIN = 0;

    struct timeval tv, tv1;
    fd_set readfds, readfds2, master;
    tv.tv_sec = 1;
    tv.tv_usec = 0;
    FD_ZERO(&readfds);
    FD_ZERO(&master);    
    FD_SET(STDIN, &readfds);
    FD_SET(STDIN, &master);
    char buffer[1];

    while(buffer[0] != 'q') {

        pthread_t inputTimer;

        pthread_create(&inputTimer, NULL, Timer, NULL);

        readfds = master;

        memcpy(&tv1, &tv, sizeof(tv));

        if (select(STDIN+1, &readfds, NULL, NULL, &tv1) == -1) {
            perror("select");
        }
        if (FD_ISSET(STDIN, &readfds)) {
            buffer[0] = cin.get();
            cout << "You entered: " << buffer << endl;

        }

        pthread_join(inputTimer, NULL);


        cout << "Timed out.\n" << endl;

    }

    cout << "Game Over." << endl;

    return 0;

}

ご覧のとおり、プログラムは 1 秒のインターバル タイマーと timeval を設定することによって動作します。両方のタイマーは int を使用して経過時間を判断するため、1 秒よりも正確にすることはできません。プログラムをより正確に修正するにはどうすればよいですか?

私の考えは、キーが押された場合に の値を 3 番目の値にコピーし、tv1再び入力を待つことtv1でした。たとえば、0.5 秒しか残っていないときにキーを押すと、値0.5tv1別の変数から取得されてコピーされます。その場合、プログラムは 1 秒ではなく、0.5 秒だけ入力を待ちます。ただし、これは機能しませんでしtv1た。10

4

2 に答える 2

5

と を使用struct timevalしてみてくださいgettimeofday() in sys/time.h。マイクロ秒の分解能を達成できます。

マンページ: http://linux.die.net/man/3/gettimeofday

詳細情報: http://www.gnu.org/software/libc/manual/html_node/Elapsed-Time.html

EDIT : Linux (Windows では MinGW に移植できません) では、ミリ秒待機できるpoll()(こちらを参照) を使用することもできます。pollタイムアウトになるまでスレッドの実行を中断するため、より効率的です。

//Timer function.
void *Timer(void*) {
    poll(0, 0, 100); //Suspend thread for 100 ms. 
    pthread_exit(NULL);
}

poll関数はで宣言されていますpoll.h

于 2012-08-19T17:36:11.017 に答える
0

ここでの問題はpthread_join、タイマースレッドが完了するまでメインスレッドを一時停止することです。したがって、参加中または参加後に行われるユーザー入力を見逃すことになります。すでにを使用しているので、ステートメントselectに組み込まれているタイムアウトを利用することもできます。select経過時間を監視していれば、タイマースレッドがなくても同じ効果が得られます。

于 2012-08-19T18:02:08.043 に答える