问题
I'm writing an interpreter for a game. User enters its move to the interpreter and program executes that move.
Now I want to implement a time limit for each decision. Player shouldn't be able to think more than 30 seconds to write a move and press enter.
call_with_time_limit seemed relevant but it doesnt work properly as such:
call_with_time_limit( 30, read(X) ), Problem, write(Problem).
In this case, it waits for input, and when input is entered, timer starts afterwards. But I want the timer to start at the beginning.
How can I do it?
回答1:
If you are interested in I/O related timeouts please consider wait_for_input/3 or set_stream/2
. The built-in you found, call_with_time_limit/2
is not a simple and reliable interface.
Edit: I just see that you use read/1
for input. Please read in above documentation how to avoid blocking in read/1
. It is not clear to me why you need this, but a user might simply enter Return, thereby circumventing the initial timeout. read/1
would now read that '\n'
but then would wait for further input - without a timeout, while the user lavishly skims Wikipedia for the answer... might even ask the question on SO...
回答2:
Your approach seems sensible: from the SWI-Prolog docs: 'Blocking I/O can be handled using the timeout option of read_term/3. '.
That's not really informative: changing timeout on user leads to some bug (I'll test more and will report to SWI_prolog mailing list if appropriate), even under catch/3.
The following seems to work
...,
current_input(I),
wait_for_input([I], A, 30),
...
If not input given (shorter time to test here...)
?- current_input(I), wait_for_input([I],A,5).
I = <stream>(0x7fa75bb31880),
A = [].
EDIT: the variable A will keep the list will contain the list of streams with ready input: I just reported the case where the user doesn't input anything before the timeout occurs. To get the actual input, using your supplied code:
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).
HTH
来源:https://stackoverflow.com/questions/8437786/time-limit-in-prolog-user-input-read