7

I would like to write a small text-based adventure game using Prolog (this might be a dumb idea but I am not here to discuss that).

The only problem is that I can't manage to print text on screen without the "true" and "false" values to appear as well.

For instance if I try something like:

take(desk) :- write('This thing is way too heavy for me to carry!').

where take is a one place predicate and desk a name I get as an output:

?- take(desk).
   This thing is way too heavy for me to carry!
   true.

How can I get rid of this "true" or "false" outputs?

Just to mention that I also tried with the format/1 one place predicate for simple text output and also the format/2 two place predicate (when I want to output the name of a variable) but it gives exactly the same problem.

I have also seen this answer but first it is not detailed enough (at least not for someone like me) and second, I hope deep inside that there is a simpler manner to do it.

And finally, I am using SWI-Prolog.

Thank you.

Community
  • 1
  • 1
gatsu
  • 237
  • 3
  • 8
  • I'm a prolog novice at best, but if you use the `--quiet`/`-q` switch, does that work? source: http://www.swi-prolog.org/pldoc/doc_for?object=section(2,+%272.4%27,+swi(%27/doc/Manual/cmdline.html%27)) – Gray Jun 23 '14 at 18:57
  • @Gray. Maybe I don't use it properly but basically if I launch `prolog -q game.pl`, it doesn't work. – gatsu Jun 24 '14 at 11:40

1 Answers1

10

A simplistic method would be to create a little REPL (read, evaluate, print loop) of your own. Something like this:

game :-
    repeat,
    write('> '),
    read(X),
    call(X),
    fail.

This will just prompt and execute whatever you enter at the prompt. In conjunction with your take fact (and another I added for illustration):

take(desk) :- write('This thing is way too heavy for me to carry!'), nl.
take(chair) :- write('This is easier to carry.'), nl.

You would get:

?- game.
> take(desk).
This thing is way too heavy for me to carry!
> take(chair).
This is easier to carry.
>

You don't get the true or false because the game goal doesn't resolve until you exit the loop somehow. You could add checks for a quit or bye or whatever to exit the game loop. Ctrl-C or Ctrl-D can be used as well to abort the loop. You might need to add some other "features" to make it work to your needs or liking.

lurker
  • 56,987
  • 9
  • 69
  • 103
  • That's an amazing answer and simple on top of that!! Now, I have a slight problem because I am using dynamical predicates for things. One of them is say `inventory(X)` that means that X is in my inventory. To account for it, I define the `take` predicate as follows `take(X) :- visible(X), write('done'), assert(inventory(X)), retract(visible(X)) ; inventory(X), write('I have taken it already')`. My problem is that when called in the loop you proposed `take(X)` outputs the two propositions in the disjunction regardless of their truth values (which it doesn't do outside of the loop). Why is that? – gatsu Jun 24 '14 at 11:48
  • Ok my bad, I have just realized that written in this order i.e. first (visible -> inventory) and then inventory will make the whole disjunction true as soon as an object is visible. This should not happen if I swap the two premisses. – gatsu Jun 24 '14 at 12:13