马克是对的。你可能想用这样的东西替换你的整个代码:
:- 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]).
有很多有趣的方法可以让你更进一步。运算符is_at
可能会使代码更具可读性:
take(X) :-
player is_at Place,
X is_at Place,
...
您还可以有一些很好的基于案例的推理来获取文章和其他内容:
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).
然后您可以将它们集成到输出例程中:
take(X) :-
...
subject(X, Subj),
format('You take ~a.~n', [Subj]),
...
你也可以用 DCG 做一些有趣的事情来生成输出:
:- use_module(library(dcg/basics)).
success(take(X)) --> "You took ", subject(X).
subject(X) --> "the ", atom(X).
您可以使用一些类似这样的表演使其更加通用:
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).
然后像这样运行:phrase(success_term(take(revolver)), X), format('~s~n', [X])
你会得到You took the revolver.
,这有点整洁。
这些文字冒险的代码很有趣。如果您还没有,我建议您阅读Amzi Prolog Nani 搜索教程。里面有很多很棒的想法!