Prolog101(09)

现在我们使用列表,重写一下room.pl文件。

%swipl -s roomlist.pl
%Hansen

%动态函数声明
:-dynamic here/1.
:-dynamic location_list/2.
:-dynamic bag_list/1.
:-dynamic take_thing/2.
:-dynamic put_thing/2.

%房间定义
room(X):- room_list(List),member(X,List).
room_list([kitchen,office,hall,diningroom,cellar]). 

%门定义
door(X,Y):- door_list(List),member([X,Y],List).
door_list([[office, hall],[kitchen, office],[hall, diningroom],[kitchen, cellar],[diningroom, kitchen]]).

%规则:有门的两个房间是相通的
connect(X,Y):- door(X,Y).
connect(X,Y):- door(Y,X).

%物品在哪个房间
location(X,Y):- location_list(List, Y), member(X, List).
location_list([apple, broccoli, crackers], kitchen). 
location_list([desk, computer], office).
location_list([flashlight, envelope], desk).
location_list([stamp, key], envelope).
location_list([], hall).
location_list([], diningroom).
location_list([washingmachine], cellar). 
location_list([nani], washingmachine).

%房间减少物品
take_thing(Thing, Place):- 
retract(location_list(List, Place)),
delete(List,Thing,ThingsLeft),
asserta(location_list(ThingsLeft,Place)). 

%房间增加物品
put_thing(Thing, Place):-  
retract(location_list(List, Place)),
asserta(location_list([Thing|List],Place)).

%背包有哪些物品
bag(X):-bag_list(List), member(X, List).
bag_list([tourch]).

%背包增加物品
bag_in(Thing):- 
retract(bag_list(List)),
asserta(bag_list([Thing|List])).

%背包减少物品
bag_out(Thing):-
retract(bag_list(List)),
delete(List,Thing,ThingsLeft),
asserta(bag_list(ThingsLeft)). 

%哪些物品可以吃
edible(X):- 
member(X,[apple,crackers,broccoli]).

%当前位置
here(hall).

%房间之间移动
move(Place):- can_go(Place),retract(here(X)), asserta(here(Place)).
can_go(Place):- here(X), connect(X, Place).
can_go(Place):- write('You can''t go to '),write(Place),write(' from here.'), nl, fail.

%拿起物品
take(X):- can_take(X), here(Place), take_thing(X,Place), bag_in(X), write(X), write(' taken.'), nl.
can_take(Thing):- here(Place), location(Thing, Place).
can_take(Thing):- write('There is no '), write(Thing), write(' here.'), nl, fail.

%放下物品
put(X):- can_put(X), here(Place), bag_out(X), put_thing(X,Place), write(X), write(' put.'), nl.
can_put(Thing):- bag(Thing). 
can_put(Thing):- write('There is no '), write(Thing), write(' in your bag.'), nl, fail. 

%房间物品列表
list_things(Place):- location(X, Place),tab(2),write(X),nl,fail.
list_things(_).

%与Place相连的房间
list_connections(Place):- connect(Place, X),tab(2),write(X),nl,fail.
list_connections(_).

%持有物品列表
list_bag(Thing):- bag(X),tab(2),write(X),nl,fail.
list_bag(_).

%吃东西
eat(Thing):- can_eat(Thing), bag_out(Thing), write(Thing), write(' eaten. Yummy!').
can_eat(Thing):- bag(Thing), edible(Thing).
can_eat(Thing):- not(bag(Thing)), write('There is no '), write(Thing), write(' in your bag.'), nl, fail. 
can_eat(Thing):- bag(Thing), write('You can''t eat the '), write(Thing), write('.'), nl, fail. 

%查看房间情况
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),
write('You have:'),nl,list_bag(Thing).

%帮助
game :-
write('Look around: look/0'),nl,
write('Move around: move/1'),nl,
write('Take something: take/1'),nl,
write('Eat something: eat/1').

进行查询

%查找与kitchen相连的房间
1 ?- findall(X, connect(kitchen, X), List).
List = [office, cellar, diningroom].

%查找全部食物与位置
2 ?- findall(foodat(X,Y), (location(X,Y) , edible(X)), L).
L = [foodat(broccoli, kitchen), foodat(crackers, kitchen)].

Leave a Reply

Your email address will not be published. Required fields are marked *

*