Ограничение по времени при вводе данных пользователем Пролога (чтение) - PullRequest
4 голосов
/ 09 декабря 2011

Я пишу переводчик для игры. Пользователь вводит свой ход в интерпретатор, и программа выполняет этот ход.

Теперь я хочу установить ограничение по времени для каждого решения. Игрок не должен думать больше 30 секунд, чтобы написать ход и нажать ввод.

call_with_time_limit показался актуальным, но он не работает должным образом:

call_with_time_limit (30, чтение (X)), Проблема, запись (Проблема).

В этом случае он ожидает ввода, а когда вводится, таймер запускается позже. Но я хочу, чтобы таймер запускался с самого начала.

Как я могу это сделать?

Ответы [ 2 ]

3 голосов
/ 09 декабря 2011

Если вас интересуют тайм-ауты, связанные с вводом / выводом, пожалуйста, рассмотрите wait_for_input/3 или set_stream/2.call_with_time_limit/2 не простой и надежный интерфейс, который вы обнаружили.

Редактировать: Я просто вижу, что вы используете read/1 для ввода.Пожалуйста, прочитайте в документации выше, как избежать блокировки в read/1.Мне не ясно, зачем вам это нужно, но пользователь может просто ввести Return , тем самым обойдя начальный тайм-аут.read/1 теперь будет читать это '\n', но затем будет ждать дальнейшего ввода - без тайм-аута, в то время как пользователь щедро просматривает Википедию для ответа ... может даже задать вопрос о SO ...

1 голос
/ 09 декабря 2011

Ваш подход кажется разумным: из документов SWI-Prolog: «Блокирующий ввод / вывод может быть обработан с использованием опции тайм-аута read_term / 3. .

Это не совсем информативно: изменение времени ожидания пользователя приводит к некоторой ошибке (я протестирую больше и сообщу в список рассылки SWI_prolog, если это необходимо), даже в catch / 3.

Кажется, работает следующее

...,
current_input(I),
wait_for_input([I], A, 30),
...

Если не указан ввод данных (более короткое время для проверки здесь ...)

?- current_input(I), wait_for_input([I],A,5).
I = <stream>(0x7fa75bb31880),
A = [].

РЕДАКТИРОВАТЬ : переменная A будет хранить список, который будет содержать список потоков с готовым вводом: я только что сообщил о случае, когда пользователь ничего не вводил до истечения времени ожидания. Чтобы получить фактический ввод, используя ваш код:

tql :-
    current_player(I),
    writef('Its %d. players turn: ', [I]),
    flush_output,
    current_input(Input),
    wait_for_input([Input], [Input], 5),
    read(Input, Move),
    writeln(Move).

current_player(1).

НТН

...