文档库 最新最全的文档下载
当前位置:文档库 › 寻找nani

寻找nani

room(kitchen).
room(office).
room(hall).
room('dining room').
room(cellar).
%第一个参数代表物体的名称,第二个参数表示物体的位置
%location/2的意思是“第一个参数所代表的物体位于第二个参数所代表的物体中
%Prolog能够区别location(sink, kitchen)和location(kitchen, sink)。
%因此,参数的顺序是我们定义事实时需要考虑的一个重要问题。
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).
location(envelope, desk).
location(stamp, envelope).
location(key, envelope).

loc_list([apple, broccoli, crackers], kitchen).
loc_list([desk, computer], office).
loc_list([flashlight, envelope], desk).
loc_list([stamp, key], envelope).
loc_list(['washing machine'], cellar).
loc_list([nani], 'washing machine').
%[]表示空表
loc_list([], hall).
%只定义单向的门,以后会很好地解决此问题的。
door(office, hall).
door(kitchen, office).
door(hall, 'dining room').
door(kitchen, cellar).
door('dining room', kitchen).
%下面定义某些物体的属性,

edible(apple).
edible(crackers).
%不好吃
tastes_yucky(broccoli).

%最后,定义手电筒(由于是晚上,玩家必须想找到手电筒,并打开它
%才能到那些关了灯的房间)的状态和玩家的初始位置。
turned_off(flashlight).
%现在所在的地方
here(kitchen).

where_food(X,Y) :- location(X,Y), edible(X).

where_food(X,Y) :- location(X,Y), tastes_yucky(X).
%解决单向门问题
connect(X,Y) :- door(X,Y).
connect(X,Y) :- door(Y,X).
%列出某个房间中的物品
list_things(Place) :-
location(X, Place),
nl,
write(X),
nl,
fail.

%这个子句永远是成功的
%AnyPlace变量的值我们并不关心
%所以我们可以使用无名变量‘_’来代替它。
list_things(_).
%能够列出与某个房间相连的所有房间。
list_connections(Place)
:- connect(Place, X),
nl,
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).

%,nl,write(Place).
can_go(Place):- here(X), connect(X, Place).
%在失败时能够给出一条消息
can_go(Place):- write('You can''t get there from here.'), nl, fail.

%它必须能够动态的修改数据库中的here谓词的子句。
%首先把玩家的旧位置的数据删除,再加上新位置的数据.
move(Place):- retract(here(X)), asserta(here(Place)).
goto(Place):- can_go(Place), move(Place), look.

can_take(Thing) :- here(Place), location(Thing, Place).
can_take(Thing) :-
write('There is no '), write(Thing), write(' here.'), nl, fail.


take_object(X):-
retract(location(X,_)), asserta(have(X)), write('

taken'), nl.

take(X):- can_take(X), take_object(X).

%能够在回溯时取消修改的谓词。
backtracking_assert(X):- asserta(X).
backtracking_assert(X):- retract(X),fail.

%递归定义列出某一个东西是否包含在另一个东西中
is_contained_in(T1,T2):-location(T1,T2).
is_contained_in(T1,T2):-location(X,T2),is_contained_in(T1,X).

object(candle, red, small, 1).
object(apple, red, small, 1).
object(apple, green, small, 1).
object(table, blue, big, 50).

location_s(object(candle, red, small, 1), kitchen).
location_s(object(apple, red, small, 1), kitchen).
location_s(object(apple, green, small, 1), kitchen).
location_s(object(table, blue, big, 50), kitchen).

%数据结构的使用
%修改以前所编写的can_take/1谓词,使得只有较轻的物品才能被玩家携带。
can_take_s(Thing) :-
here(Room),
location_s(object(Thing, _, small,_), Room).
can_take_s(Thing) :-
here(Room),
location_s(object(Thing, _, big, _), Room),
write('The '), write(Thing),
write(' is too big to carry.'), nl,
fail.
can_take_s(Thing) :-
here(Room),
%其中变量‘_’是匿名变量.
not (location_s(object(Thing, _, _, _), Room)),
write('There is no '), write(Thing), write(' here.'), nl,
fail.

write_weight(1) :- write('1 pound').
write_weight(W) :- W > 1, write(W), write(' pounds').


%原来的list_things/1谓词也可以加上一些功能,
%下面的list_things_s/1不但可以列出房间中的物品,还可以给出它们的描述。
list_things_s2(Place) :-
location_s(object(Thing, Color, Size, Weight),Place),
%tab(1),
write('A '),write(Size),nl,
%tab(1),
write(Color),nl,
write(Thing), write(', weighing '),
write_weight(Weight), write(' pounds'),nl,fail.
%引起回溯
%为了使结果回答为正确
list_things_s2(_).


%下面使用dimension结构来描述物体的长、宽、高。
object(desk, brown, dimension(6,3,3), 90).
%当然,也可以这样来表达物品的特性
%object(desk, color(brown), size(large), weight(90)).



%member(a, [a, b, c]).
member(H,[H|T]).
member(X,[H|T]):-member(X,T).

%用户使用分号引起回溯???????
%空表能引起失败退出


append([],X,X).
append([H|T1],X,[H|T2]):-append(T1,X,T2).

add_thing(NewThing, Container, NewList):-
loc_list(OldList, Container),
append([NewThing],OldList, NewList).

add_thing2(NewThing, Container, NewList):-
loc_list(OldList, Container),
NewList = [NewThing | OldList].

%不是用显式的联合,而改为在子句头部的隐式联合。
add_thing3(NewTh, Container,[NewTh|OldList]) :-
loc_list(OldList, Container).

%能够直接修改动态数据库,请自己研究一下。
put_thing(Thing,Place) :-
retract(loc_list(List, Place)),
asserta(loc_list([Thing|List],Place)).

%把一个列表转换为多条子句
break_out([]).
break_out([Head | Tail]):-
assertz(stuff(Head)),
break_out(Tail).

%能找出所有能

吃的东西及其位置,并把结果放到了列表中
%?- findall(foodat(X,Y), (location(X,Y) , edible(X)), L).

is_in(apple, room(kitchen)).
%使用op/3谓词把is_in/2定义为操作符,优先权值为35。
op(35,xfx,is_in).

%同样可以使用操作符来定义事实。
banana is_in room(kitchen).

%
op(33,fx,room).
%定义后缀操作
%flashlight turned_on.
op(33,xf,turned_on).

?- X = 3 * 4 + likes(john, 6/2).

%object(apple, size:small, color:red, weight:1).

%object(apple, size,small, color,red, weight,1).

data(one).
data(two).
data(three).

cut_test_a(X) :- data(X).
cut_test_a('last clause').

%使用cut之后
cut_test_b(X) :- data(X), !.
cut_test_b('last clause').

cut_test_c(X,Y) :- data(X), !, data(Y).
cut_test_c('last clause').

%如果存在puzzle,并且约束条件成立,就成功。
%如果存在puzzle,而约束条件不成立,就失败。
%如果没有puzzle,成功。

%puzzle(goto(cellar)):-
%have(flashlight),
%turned_on(flashlight),
%!.
%不使用cut完成同样功能就用not
puzzle(goto(cellar)):-
not(have(flashlight)),
%not(turned_on(flashlight)),
write('Scared of dark message'),
fail.

puzzle(X):-
not(X = goto(cellar)).

not(X) :- call(X), !, fail.
not(X).

%如何在游戏中加入命令循环
goto(Place) :-
puzzle(goto(Place)),
can_go(Place),
move(Place),
look.

command_loop:-
repeat,
write('Enter command (end to exit): '),
read(X),
write(X), nl,
X = end.










相关文档
相关文档 最新文档