Darkstar3000
Programmer
Hello, I have been following this tutorial ( in an attempt to create my own version of "nani search" the only problem I have now is the last chapter which deals with Definite clause grammar, every single time I try to use DCG in my program while in the command_loop, e.g take the apple. I get error messages like : "ERROR: Stream user_input:7:436 Syntax error: Operator expected" or "ERROR: Stream user_input:7:424 Syntax error: Operator expected" I'm using SWI-prolog to write this program. I have a predicate get_command which also points to command/2 but after following the tutorial command/2 no longer exists and I tried modifying command(CL,L) to command(CL,L,[]) but I still get errors. Here is my source code.
Code:
:-dynamic (location/2),(here/1),(have/1),(turned_off/1),(turned_on/1).
%%%%%%%%%%%%%%%%%%%%%%%%%RULES AND FACTS%%%%%%%%%%%%%%%%%%%%%%%%%
%%Fact defining the Rooms
room(kitchen).
room(office).
room(hall).
room('dining room').
room(cellar).
location(object(desk,big), office).
location(object(apple,small), kitchen).
location(object(flashlight,small), desk).
location(object('washing machine',big), cellar).
location(object(nani,small), 'washing machine').
location(object(broccoli,small), kitchen).
location(object(crackers,small), kitchen).
location(object(computer,big), office).
door(office,hall).
door(kitchen,office).
door(hall,'dining room').
door(kitchen,cellar).
door('dining room',kitchen).
%%Fact for Items that are edible.
edible(apple).
edible(crackers).
tastes_yucky(broccoli).
turned_off(flashlight).
here(kitchen).
where_food(X,Y) :-
location(object(X,small),Y),
edible(X).
where_food(X,Y) :-
location(object(X,small),Y),
tastes_yucky(X).
%%%where_food(_).
connect(X,Y) :- door(X,Y).
connect(X,Y) :- door(Y,X).
look_in(Area):- location(object(X,_),Area),is_contained_in(X,Area),write(X),nl,fail.
look_in(_).%%This will unify with anything and will always return true.
list_things(Place) :-
location(object(X,_), Place),
tab(2),
write(X),nl,
fail.
list_things(_).%%This clause will match with anything and it will return true
%%List connection between two places
list_connections(Place) :-
connect(Place, X),
tab(2),
write(X),
nl,
fail.
list_connections(_).
look :-
here(Place),
write('You are in the '), write(Place), nl,
write('You can see:'), nl,
list_things(Place),
write('You can go to:'), nl,
list_connections(Place).
move(Place):- retract(here(X)),asserta(here(Place)).
%%Move the player to the desired location
goto(Place):-
puzzle(goto(Place)),
can_go(Place),
move(Place),
look.
can_go(Place):-
here(X),
connect(X, Place).
can_go(Place):- write('You can''t get to the '),write(Place),write(' from here.'), nl,fail.
can_take(X) :- here(Place),location(object(X,small),_),is_contained_in(X,Place).
can_take(X) :- here(Place),location(object(X,big),Place),write('The '),write(X),write(' is too big'),nl,fail.
can_take(X) :- here(Place),not(location(object(X,_),Place)),write('There is no '),write(X),write(' here'),nl,fail.
take_object(X):- retract(location(object(X,_),_)),asserta(have(X)),write('taken'), nl,!.
take(X):- can_take(X),take_object(X).
eat(X) :- have(X),edible(X),retract(have(X)),write('You have eaten the '),write(X),!.
eat(X) :- have(X),tastes_yucky(X),retract(have(X)),write('Ehhhh, tastes yucky'),!.
eat(X) :- not(edible(X)),write('You cannot eat that'),nl,!.
eat(X) :- not(have(X)),write('You do not have the '),write(X),write(' to eat'),nl,fail.
drop(X) :- here(Place),retract(have(X)),asserta(location(object(X,_,_,_),Place)),write('Dropped').
items_I_have :- have(X),tab(2),write(X),nl,fail.
items_I_have.
inventory :- have(X),write('You have'),nl,items_I_have.
inventory :- not(have(_)), write('There is nothing here'),nl.
%%Check for items hiden within other items.
is_contained_in(T1,T2) :- location(object(T1,_),T2).
is_contained_in(T1,T2) :- location(object(X,_),T2),is_contained_in(T1,X).
turn_on(flashlight) :- have(flashlight),retract(turned_off(flashlight)),asserta(turned_on(flashlight)),write('Flashlight is on').
turn_on(flashlight) :- not(have(flashlight)),write('You do not have a flashlight'),nl,fail.
turn_off(flashlight) :- have(flashlight),retract(turned_on(flashlight)),asserta(turned_off(flashlight)),write('Flashlight is off').
puzzle(goto(cellar)):- have(flashlight),turned_on(flashlight),!.
puzzle(goto(cellar)):-
write('It\'s too dark, you can\'t go in there'),nl,!, fail.
puzzle(_).
command_loop:-
write('Welcome to Nani Search'), nl,
repeat,
write('>nani> '),
read(X),get_command(X),
do(X), nl,
end_condition(X).
end_condition(end).
end_condition(_) :-
have(nani),
write('Congratulations, you have found nani and now you can rest safe and easy').
do(goto(X)):-goto(X),!.
do(go(X)):-goto(X),!.
do(inventory):-inventory,!.
do(look):-look,!.
do(look_in(X)) :- look_in(X),!.
do(take(X)) :- take(X),!.
do(drop(X)) :- drop(X),!.
do(eat(X)) :- eat(X),!.
do(turn_on(flashlight)) :- turn_on(flashlight),!.
do(turn_off(flashlight)) :- turn_off(flashlight),!.
do(items_I_have) :- items_I_have,!.
do(end).
do(_) :- write('Invalid Command'),!.
get_command(C) :-
read_list(L),
command(CL,L),
C =.. CL, !.
get_command(_) :-
write('I don''t understand'), nl, fail.
command([V])--> verb(V).
command([goto, Place]) --> noun(place, Place).
command([V,O]) -->
verb(Object_Type,V),
object(Object_Type, O).
verb(place, goto) --> [go,to].
verb(place, goto) --> [go].
verb(place, goto) --> [move,to].
verb(place, goto) --> [X],{room(X)}.
verb(place, goto) --> [dining,room].
verb(thing, take) --> [take].
verb(thing, drop) --> [drop].
verb(thing, drop) --> [put].
verb(thing, turn_on) --> [turn,on].
verb(look) --> [look].
verb(look) --> [look,around].
verb(inventroy) --> [bag].
verb(inventory) --> [inventory].
verb(end) --> [end].
verb(end) --> [quit].
verb(end) --> [good,bye].
det --> [the].
det --> [a].
det --> [an].
object(Type, N) -->
det,
noun(Type, N).
object(Type, N) -->
noun(Type, N).
noun(place, R) --> [R],{room(R)}.
noun(place, 'dining room') --> [dining,room].
noun(thing, T) --> [T],{location(object(T,_),_)}.
noun(thing, T) --> [T],{have(T)}.
noun(thing, 'washing machine') --> [washing,machine].
noun(thing, flashlight) --> [light], {have(flashlight)}.
%read a line of words from the user
read_list(L) :-
write('> '),
read_line(CL),
wordlist(L,CL,[]), !.
read_line(L) :-
get0(C),
buildlist(C,L).
buildlist(13,[]) :- !.
buildlist(C,[C|X]) :-
get0(C2),
buildlist(C2,X).
wordlist([X|Y]) --> word(X), whitespace, wordlist(Y).
wordlist([X]) --> whitespace, wordlist(X).
wordlist([X]) --> word(X).
wordlist([X]) --> word(X), whitespace.
word(W) --> charlist(X), {name(W,X)}.
charlist([X|Y]) --> chr(X), charlist(Y).
charlist([X]) --> chr(X).
chr(X) --> [X],{X>=48}.
whitespace --> whsp, whitespace.
whitespace --> whsp.
whsp --> [X], {X<48}.