我正在使用Prolog开发Guess Who?游戏。游戏的机制非常简单。玩家(在这种情况下,人类)在许多可能的人中选择一个人,而另一个玩家(计算机)开始询问关于该人的某些属性的是/否问题。最终,根据给定的答案,只有一个可能的人。
到目前为止,我已经能够制定一套规则和谓词,以便计算机可以根据到目前为止提出的问题猜测这个人。我有一组嫌犯 - 那些有可用线索的人可以适应。
suspect('Person 1') :- eyes(blue) , age(old) , gender(male).
定义属性的谓词,以便在尚未询问有关该属性的问题时,或者是否已询问问题且答案与嫌疑人的属性匹配时,它们将为真。
gender(X) :- not(asked_gender) ; value_of(gender, X).
这样,如果两个嫌疑人拥有相同的眼睛,年龄和性别,只要性别保持不变,他们两个都是合理的嫌疑人。
然而,现在困难的部分是自动化提出这些问题的过程。基本上,我期待一个解决方案,Prolog能够从嫌疑人的谓词中获取属性的可能值,而不是在其他地方列出主题。我很确定必须有这样做的方法,因为prolog能够将程序的代码用作数据本身。
我怎么能这样做?
答案 0 :(得分:3)
这适用于SWI-Prolog:
:- dynamic value/1.
suspect('Person 1') :- eyes(blue) , age(old) , gender(male).
suspect('Person 2') :- eyes(green) , age(young) , gender(male).
suspect('Person 3') :- eyes(brown) , age(young) , gender(male).
fetch(Criterion, Value) :-
retractall(value(_)),
assert(value([])),
forall(clause(suspect(_), Body),
check(Body, Criterion)),
retract(value(Value)).
check((F, T), Criterion) :-
F =..[Criterion, V1],
retract(value(V2)),
( member(V1, V2) -> V3 = V2; V3 = [V1 | V2]),
assert(value(V3)).
check(T, Criterion).
check((_F, T), Criterion) :-
check(T, Criterion).
check((F), Criterion) :-
F =..[Criterion, V1],
retract(value(V2)),
( member(V1, V2) -> V3 = V2; V3 = [V1 | V2]),
assert(value(V3)).
check((_F), _Criterion).
例如: ? - 获取(性别,价值)。 价值= [男]。
? - 获取(眼睛,价值)。 值= [棕色,绿色,蓝色]。
答案 1 :(得分:0)
好吧,我想象一下这样的结构:
go :-
findall(People,suspect(People),SuspectList),
length(SuspectList,1),
member(Perb,SuspectList),
write('It is '),write(Perb),write('!!'),nl,!.
go :-
askQuestion,
go.
在askQuestion / 0中你会用read / 1谓词提出问题并断言/ 1答案。 这是您可以尝试使其“智能”的地方,或者您可以迭代不同的问题。