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?
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...
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
Related
I have stumbled upon a piece of code that I can't quite understand. It looks like this:
% spawn process which waits for a message and prints it
Pid = spawn(fun() ->
receive
X -> io:fwrite("I received: ~p~n", [X])
end
end),
% send a message to the new process
Pid ! {message, "Hello"}.
In the last line, is "message" an atom that is defined in the module? I can't really understand that part.
My attempt at understanding it would be this: we save things in tuples where the first element is descriptive of the content. For example: {celsius, 55}. What is less clear is that the atom message is not defined in the module. Do you have to define it? No declaration is necessary so I guess you don't have to define the atom before using it. Am I correct?
Thanks for the help!
The code is from here.
Correct- you just use atoms at will. They're not "defined" anywhere.
Basically, You understood right. You can use everything atom you want, they are not defined anywhere. Except some reserved words in Erlang:
receive, case, if, throw, catch, else...
Atoms can be used at will, Every unique atom will be entered into an atom table. The atom table is never garbage collected. The default max atom count for an ERTS instance is 1048576. This limit can be increased by using +t option on startup.
more information regarding limits. For diagnostic purpose you can use erlang:memory(atom) - elrang:memory(atom_used) calls, to ensure you haven't exhausted the available atoms. If the atoms are exhausted it leads to immediate termination of the ERTS without warning.
This is my code in Prolog.
do(cinema):- parents(yes); (parents(no),weather(windy),money(less)).
do(play):- parents(no),weather(sunny).
do(stay):- parents(no),weather(rainy).
do(shopping):- parents(no),weather(windy),money(more).
start:- write('Parents: '),read(X),assert(parents(X)), write('Weather: '),read(Y),assert(weather(Y)), write('Money: '),read(Z),assert(money(Z)).
clear:- retract(parents(X));retract(weather(X));retract(money(X)).
I'm trying to accept data from user and then use decision tree to find out what task will be done.
I'm running the code as:
?-start, do(X).
But it does not write Weather after reading input for parents and keeps reading data.
There is nothing really wrong with your program. See http://swish.swi-prolog.org/p/JDAJcUhq.pl. The most likely cause is already mentioned: not finishing your term with a ".". clear/0 is indeed wrong, but not needed in the web version as each new query is executed in a fresh environment.
At least in SWI-Prolog there is no need to flush before a read operation from the terminal as flushing the console output streams is always done before the read.
Try putting some flush goals after the write goals and then remember to add a full stop on your input as you are using read/1 which wants a term.
I am about to write a text based adventure game in Prolog, therefore i have tons of writeline statements. I was wondering if i could slow down the output processing of my text. So imagine the following scenario:
I have a Textblock A that gets printed and i want a 2 sec delay afterwards.
So Textblock B gets printed 2 sec later, without the :- sign in Prolog.
My first idea was to write a loop that compares the current time with currenttime + 2 s but i cant get rid of the :- sign.
Unfortunately; I am a newbie in Prolog and Ii don't have any clue about the thread handling.
That statement might be useful but it doesn't work at all:
delayText([H|T]) :-
put_char(H),
flush_output,
sleep(0.1),
delayText(T).
delayText([]).
Neither flush output nor sleep seem to work.
I'm using ProDT in Eclipse.
Thanks in advance,
Chris.
I'm not sure as to how you want to realise the writing for your game, but sleep/1 as used in the example code in your question can be used together with a simple write like so:
delayText([]).
delayText([H|T]) :-
write(H),
sleep(1), % Time in seconds
delayText(T).
I am making it so that it stops asking for input upon CTRL-C.
What I have currently is that a separate go-routine, upon receiving a CTRL-C, changes the value of a variable so it won't ask for another line. However, I can't seem to find a way around the current line.
i.e. I still have to press enter once, to get out of the current iteration of reading for \n.
Is there perhaps a way to push a "\n" into stdin for the reader.ReadString to read. Or a way to stop its execution altogether.
The only decent mechanism that Go gives you to proceed when either of two things happens is select, and select only selects on channel reads, so your only option is to change your signal-handler goroutine to write to a channel, and add another goroutine that handles stdin and passes lines of input to a channel, then select on the two channels.
However, that still leaves your question half-unanswered: your main program can stop waiting for input on a Ctrl-C, but the goroutine that's reading input will still be waiting for input. In some cases that might be okay... if you will never need stdin again, or if you will go right back to processing lines in the same exact way. But if you want to do something other than ReadString from that reader, you're stuck... literally. The only solution I see would be to write your own state machine around Read or ReadByte that is capable of changing its behavior in response to external conditions, but that can easily get horribly complicated.
Basically, this looks like a case where Go simplifies things compared to the underlying system (not exposing anything like EINTR, not allowing select on filehandles), but ends up providing less power to the programmer.
Is there a way to check programmatically whether the FrontEnd considers evaluation still running?
Or even better: is there a way to check whether the FrontEnd has some pending inputs to be sent to the kernel?
P.S. This question has arisen from previous question.
EDIT
When evaluating a Cell in the FrontEnd we usually create a queue of inputs for the kernel.
I need a function that will return True if the FrontEnd has sent to the kernel the last input of the queue of inputs from the EvaluationNotebook[]. Or in other words I need a function that returns True if this current input is the last input of the queue of inputs generated by the FrontEnd.
This should work. Of course, you have to run it in a different kernel than the one that is performing the evaluation you want to check for.
NotebookEvaluatingQ[nb_] := (
SelectionMove[nb, All, Notebook];
Or ## Map["Evaluating" /. # &, Developer`CellInformation[nb]]
)
Obviously, it's best to set things up before hand using a tool like Monitor. For example,
Monitor[
Do[Pause[6], {i, 10}],
i]
will allow you to observe the progress of the index variable i. If you haven't set things up before hand, you might be able to do something using the "Interrupt Evaluation" button under the Evaluation menu. For example, try the following:
Do[Pause[6], {i, 10}]
Now, wait six or more seconds and then select "Interrupt Evaluation". You can then examine the state of i to see how far along it is. You resume evaluation using Continue under "Debugger Controls".