문제

I try to create a simple program in prolog, but i have a problem:

:- dynamic at/2, i_am_holding/1, i_am_at/1.

/* some lines of code */

i_am_at(room1).

at(revolver, room1).

take(revolver) :- write('You picked up the revolver.'),nl.

take(X):- i_am_at(Place),
      assert(i_am_holding(X)),
      retract(at(X,Place)).

/* some lines of code */

I want the user to pick up the revolver,and then (the revolver)to be retracted from the place where he is in, so he won't be able to pick it up again.

When I run my code, the take(revolver) query runs, but the take(X) does not.

도움이 되었습니까?

해결책

Mark is right on the money. You probably want to replace your whole code with something like this:

:- dynamic at/2, holding/1.

at(player, room1).
at(revolver, room1).

take(X) :-
    at(player, Place),
    at(X, Place),
    !,
    format('You pick up the ~a.~n', [X]),
    retract(at(X,Place)),
    assert(holding(X)).

take(X) :-
    holding(X),
    !,
    format('You''re already holding the ~a!~n', [X]).

There are a lot of interesting ways you could take this further. An operator is_at might make the code more readable:

take(X) :-
  player is_at Place,
  X is_at Place,
  ...

You could also have some nice case-based reasoning for getting the articles and whatnot right:

subject(X, Some_X) :- mass_noun(X), !, atom_concat('some ', X, Some_X).
subject(X, The_X)  :- atom_concat('the ', X, The_X).

mass_noun(water).

then you could integrate these into the output routines:

take(X) :- 
  ...
  subject(X, Subj),
  format('You take ~a.~n', [Subj]),
  ...

You could do some fun stuff with DCGs to generate the output too:

:- use_module(library(dcg/basics)).

success(take(X)) --> "You took ", subject(X).
subject(X) --> "the ", atom(X).

You can make that even more generic with some histrionics like this:

success_term(Command) --> { Command =.. CommandList }, success(CommandList).
success([Command, DirectObject]) --> 
  "You ", past_tense(Command), " ", subject(DirectObject), ".".

subject(Noun) --> "the ", atom(Noun).
past_tense(X) --> { past_tense(X, Y) }, atom(Y).

past_tense(take, took).
past_tense(X, Xed) :- atom_concat(X, 'ed', Xed).

Then run that like so: phrase(success_term(take(revolver)), X), format('~s~n', [X]) and you'll get You took the revolver., which is kind of neat.

These text adventures are a lot of fun to code. I recommend you go through the Amzi Prolog Nani Search tutorial if you haven't yet. There are a lot of great ideas in there!

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top