I'm going through the Adventure in Prolog tutorial and I'm trying to implement an open/close rule for each of the doors I have.
Add an open/closed status for each of the doors. Write open and close predicates that do the obvious
:- dynamic here/1, location/2, have/1, turned_on/1, turned_off/1.
room(kitchen).
room(office).
room(hall).
room('dining room').
room(cellar).
location(desk, office).
location(apple, kitchen).
location(flashlight, desk).
location('washing machine', cellar).
location( nani,'washing machine' ).
location(broccoli, kitchen).
location(crackers, kitchen).
location(computer, office).
door(office, hall).
door(kitchen, office).
door(kitchen, cellar).
door(hall, 'dining room').
door('dining room', kitchen).
edible(apple).
edible(crackers).
tastes_yucky(broccoli).
turned_off(flashlight).
here(kitchen).
connect(X, Y) :- door(X, Y).
connect(X, Y) :- door(Y, X).
list_things(Place) :-
location(X, Place),
tab(2),
write(X), nl,
fail.
list_things(AnyPlace).
list_connections(Conn) :-
connect(Conn, X),
tab(2),
write(X),
nl,
fail.
list_connections(_).
look :-
here(X),
write('you are in the '), write(X), nl,
write('you can see:'), nl,
list_things(X),
write('you can go to:'), nl,
list_connections(X).
goto(Place) :-
can_go(Place),
move(Place),
look.
can_go(Room) :-
here(X),
connect(X, Room).
can_go(Room) :-
write('You can\'t go there from here'),nl,
fail.
move(Place):-
retract(here(X)),
asserta(here(Place)).
take_object(X) :-
retract(location(X, _)),
asserta(have(X)).
write('taken'), nl.
put(X) :-
retract(have(X)),
asserta(location(X,_)).
inventory:-
have(X),
write('you have the following items:'), nl,
write(X).
turn_on(X):-
turned_off(X),
retract(turned_off(X)),
asserta(turned_on(X)),
write('flash light turned on').
turn_on(X):-
write('you can\'t turn that on').
turn_off(X):-
turned_on(X),
retract(turned_on(X)),
asserta(turned_off(X)),
write('flash light is now off').
turn_off(X):-
write('you can\'t turn that off').
Now to actually add the rules:
door(office, hall).
door(kitchen, office).
door(kitchen, cellar).
door(hall, 'dining room').
door('dining room', kitchen).
opened(office, hall).
closed(kitchen, office).
opened(kitchen, cellar).
closed(hall, 'dining room').
opened('dining room', kitchen).
open(X, Y) :-
closed(X, Y),
retract(closed(X, Y)),
asserta(opened(X, Y)),
writeln('door opened').
open(X, Y) :-
closed(Y, X),
retract(closed(Y, X)),
asserta(opened(Y, X)),
writeln('door opened').
close(X, Y) :-
opened(X, Y),
retract(opened(X, Y)),
asserta(closed(X, Y)),
writeln('door closed').
close(X, Y) :-
opened(Y, X),
retract(opened(Y, X)),
asserta(closed(Y, X)),
writeln('door closed').
I'm only concerned that I'm using the open(X,Y)
twice (also the close). Is there a better way?