使用Prolog解决《耻辱2》Jindosh谜题时遇目标指令失败问题
解决《耻辱2》Jindosh谜题的Prolog代码排查问题
问题背景
我正在游玩《耻辱2》,想用Prolog解决游戏中的Jindosh谜题。编写了对应代码,但加载时出现「Warning: Goal (directive) failed」警告,仅返回true却无其他输出。之前用类似结构解决过斑马谜题,也参考过资料、咨询过相关工具,仍不清楚问题所在,需要排查帮助。使用的是SWIPL,定义的5元组格式为**(姓名、颜色、饮品、地点、传家宝)**。
编写的Prolog代码
% dishonered 2 jindosh riddle exists(A,(A,_,_,_,_)). exists(A,(_,A,_,_,_)). exists(A,(_,_,A,_,_)). exists(A,(_,_,_,A,_)). exists(A,(_,_,_,_,A)). rightOf(A, B, (B,A,_,_,_)). rightOf(A, B, (_,B,A,_,_)). rightOf(A, B, (_,_,B,A,_)). rightOf(A, B, (_,_,_,B,A)). middlePerson(A,(_,_,A,_,_)). firstPerson(A, (A,_,_,_,_)). second(A,(_,A,_,_,_)). third(A,(_,_,A,_,_)). fourth(A,(_,_,_,A,_)). lastPerson(A,(_,_,_,_,A)). nextTo(A,B,H) :- rightOf(A,B,H). nextTo(A,B,H) :- rightOf(B,A,H). :- exists(person(winslow,green,_,_,_), People), firstPerson(person(contee,_,_,_,_), People), nextTo(person(contee,_,_,_,_),person(_,white,_,_,_,_), People), rightOf(person(_,blue,_,_,_,_),person(_,purple,_,_,_,_), People), exists(person(_,purple,absinthe,_,_), People), exists(person(_,red,_,dabokva,_), People), nextTo(person(_,_,_,_,_,snufftin),person(_,_,_,_,dabokva,_), People), exists(person(finch,_,_,_,ring), People), exists(person(_,_,_,karnaca,bird), People), nextTo(person(_,_,_,_,diamond),person(_,_,_,dunwall,_), People), nextTo(person(_,_,_,dunwall,_),person(_,_,wine,_,_), People), exists(person(marcolla,_,whiskey,_,_), People), exists(person(_,_,rum,fraeport,_), People), middlePerson(person(_,_,beer,_,_), People), exists(person(natsiou,_,_,baleton,_), People), exists(person(_,_,_,_,warmedal), People), firstPerson(person(Aperson,Acolour,Adrink,Aloc,Aheir), People), second(person(Bperson,Bcolour,Bdrink,Bloc,Bheir), People), third(person(Cperson,Ccolour,Cdrink,Cloc,Cheir), People), fourth(person(Dperson,Dcolour,Ddrink,Dloc,Dheir), People), lastPerson(person(Eperson,Ecolour,Edrink,Eloc,Eheir), People), format('The first person is the ~w person~n', (Aperson,Acolour,Adrink,Aloc,Aheir)), format('The second person is the ~w person~n', (Bperson,Bcolour,Bdrink,Bloc,Bheir)), format('The third person is the ~w person~n', (Cperson,Ccolour,Cdrink,Cloc,Cheir)), format('The fourth person is the ~w person~n', (Dperson,Dcolour,Ddrink,Dloc,Dheir)), format('The last person is the ~w person~n', (Eperson,Ecolour,Edrink,Eloc,Eheir)).
执行命令与输出
?- [dishonored]. Warning: c:/users/<USERNAME>/documents/prolog/dishonored.pl:25: Warning: Goal (directive) failed: user:(exists(person(winslow,green,_7036,_7058,_7080),_7102),firstPerson(person(contee,_7198,_7220,_7242,_7264),_7102),nextTo(person(contee,_7392,_7414,_7436,_7458),person(_7480,white,_7502,_7524,_7546,_7568),_7102),rightOf(person(_7702,blue,_7724,_7746,_7768,_7790),person(_7812,purple,_7834,_7856,_7878,_7900),_7102),exists(person(_7992,purple,absinthe,_8014,_8036),_7102),exists(person(_8128,red,_8150,dabokva,_8172),_7102),nextTo(person(_8306,_8328,_8350,_8372,_8394,snufftin),person(_8416,_8438,_8460,_8482,dabokva,_8504),_7102),exists(person(finch,_8596,_8618,_8640,ring),_7102),exists(person(_8732,_8754,_8776,karnaca,bird),_7102),nextTo(person(_8898,_8920,_8942,_8964,diamond),person(_8986,_9008,_9030,dunwall,_9052),_7102),nextTo(person(_9174,_9196,_9218,dunwall,_9240),person(_9262,_9284,wine,_9306,_9328),_7102),exists(person(marcolla,_9420,whiskey,_9442,_9464),_7102),exists(person(_9556,_9578,rum,fraeport,_9600),_7102),middlePerson(person(_9698,_9720,beer,_9742,_9764),_7102),exists(person(natsiou,_9856,_9878,baleton,_9900),_7102),exists(person(_9998,_10020,_10042,_10064,warmedal),_7102),firstPerson(person(_10168,_10190,_10212,_10234,_10256),_7102),second(person(_10360,_10382,_10404,_10426,_10448),_7102),third(person(_10552,_10574,_10596,_10618,_10640),_7102),fourth(person(_10744,_10766,_10788,_10810,_10832),_7102),lastPerson(person(_10936,_10958,_10980,_11002,_11024),_7102),format('The first person is the ~w person~n',(_10168,_10190,_10212,_10234,_10256)),format('The second person is the ~w person~n',(_10360,_10382,_10404,_10426,_10448)),format('The third person is the ~w person~n',(_10552,_10574,_10596,_10618,_10640)),format('The fourth person is the ~w person~n',(_10744,_10766,_10788,_10810,_10832)),format('The last person is the ~w person~n',(_10936,_10958,_10980,_11002,_11024))) **true.**
问题排查与修复
1. 核心错误:元组参数数量不匹配
代码中多处出现6元组的person结构(比如person(_,white,_,_,_,_)),但你定义的是5元组(姓名、颜色、饮品、地点、传家宝),这会导致所有涉及错误元组的匹配逻辑直接失败,进而触发指令执行失败的警告。
例如:
nextTo(person(contee,_,_,_,_),person(_,white,_,_,_,_), People)中的第二个person多了一个参数rightOf(person(_,blue,_,_,_,_),person(_,purple,_,_,_,_), People)中的两个person都是6元组nextTo(person(_,_,_,_,_,snufftin),person(_,_,_,_,dabokva,_), People)中的第一个person多了一个参数
2. 修复步骤
把所有错误的6元组person修正为5元组,确保每个person结构的参数数量统一为5个。
3. 优化执行逻辑
将顶层指令封装为独立谓词,便于调试和重复执行,同时优化输出格式:
solve_jindosh(People) :- exists(person(winslow,green,_,_,_), People), firstPerson(person(contee,_,_,_,_), People), nextTo(person(contee,_,_,_,_),person(_,white,_,_,_), People), rightOf(person(_,blue,_,_,_),person(_,purple,_,_,_), People), exists(person(_,purple,absinthe,_,_), People), exists(person(_,red,_,dabokva,_), People), nextTo(person(_,_,_,_,snufftin),person(_,_,_,dabokva,_), People), exists(person(finch,_,_,_,ring), People), exists(person(_,_,_,karnaca,bird), People), nextTo(person(_,_,_,_,diamond),person(_,_,_,dunwall,_), People), nextTo(person(_,_,_,dunwall,_),person(_,_,wine,_,_), People), exists(person(marcolla,_,whiskey,_,_), People), exists(person(_,_,rum,fraeport,_), People), middlePerson(person(_,_,beer,_,_), People), exists(person(natsiou,_,_,baleton,_), People), exists(person(_,_,_,_,warmedal), People), firstPerson(person(Aperson,Acolour,Adrink,Aloc,Aheir), People), second(person(Bperson,Bcolour,Bdrink,Bloc,Bheir), People), third(person(Cperson,Ccolour,Cdrink,Cloc,Cheir), People), fourth(person(Dperson,Dcolour,Ddrink,Dloc,Dheir), People), lastPerson(person(Eperson,Ecolour,Edrink,Eloc,Eheir), People), format('The first person is: ~w, ~w, ~w, ~w, ~w~n', [Aperson,Acolour,Adrink,Aloc,Aheir]), format('The second person is: ~w, ~w, ~w, ~w, ~w~n', [Bperson,Bcolour,Bdrink,Bloc,Bheir]), format('The third person is: ~w, ~w, ~w, ~w, ~w~n', [Cperson,Ccolour,Cdrink,Cloc,Cheir]), format('The fourth person is: ~w, ~w, ~w, ~w, ~w~n', [Dperson,Dcolour,Ddrink,Dloc,Dheir]), format('The last person is: ~w, ~w, ~w, ~w, ~w~n', [Eperson,Ecolour,Edrink,Eloc,Eheir]).
在SWIPL中执行:
?- solve_jindosh(People).
修正后即可正常求解并输出谜题答案。
内容的提问来源于stack exchange,提问作者CricGuru
相关产品推荐
相关产品推荐

