【发布时间】:2013-11-07 09:57:08
【问题描述】:
我在 SWI-Prolog 中为文本冒险游戏创建了两个不同的 .pl 文件。他们是两个不同的任务。
有什么办法在第一个任务结束时打开第二个任务(第二个.pl文件)并关闭第一个?
另外,还有什么更好的方法:为我的 N 个任务创建 N 个 .pl 文件还是一个大的 .pl 文件?
【问题讨论】:
标签: prolog swi-prolog
我在 SWI-Prolog 中为文本冒险游戏创建了两个不同的 .pl 文件。他们是两个不同的任务。
有什么办法在第一个任务结束时打开第二个任务(第二个.pl文件)并关闭第一个?
另外,还有什么更好的方法:为我的 N 个任务创建 N 个 .pl 文件还是一个大的 .pl 文件?
【问题讨论】:
标签: prolog swi-prolog
我同意您最初的想法,即最好使用多个模块文件。我想使用不同文件的一个原因是为事实和规则提供不同的名称空间,这些事实和规则最好使用相同的谓词来表达。例如,Description 在任务 1 中的 room(1, Description) 与在任务 2 中的不同。
实现这一点的一种方法是在每个不同的任务模块中访问私有的、非导出的谓词。 (旁白:我在某处读到 Jan Wielemaker 对这种做法的警告,但我不知道为什么,也不确定我确实读过这篇文章。)
这是我总结的一个可能的模式:
给定一个主文件“game.pl”,包含以下程序,
:- use_module([mission1, mission2]).
start :-
playing(mission1).
playing(CurrentMission) :-
read(Command),
command(CurrentMission, Command),
playing(CurrentMission).
command(_, quit) :- write('Good bye.'), halt.
command(CurrentMission, Command) :-
( current_predicate(CurrentMission:Command/_) % Makes sure Command is defined in the module.
-> CurrentMission:Command % Call Command in the current mission-module
; write('You can\'t do that.'), % In case Command isn't defined in the mission.
).
还有这些任务模块,
在文件“mission1.pl”中:
:- module(mission1, []).
turn_left :-
write('You see a left-over turnip').
eat_turnip :-
write('You are transported to mission2'),
playing(mission2). % Return to the prompt in `game` module, but with the next module.
在文件“mission2.pl”中:
:- module(mission2, []).
turn_left :-
write('You see a left-leaning turncoat.').
那我们就可以玩这个烂游戏了:
?- start.
|: turn_left.
You see a left-over turnip
|: eat_turnip.
You are transported to mission2
|: turn_left.
You see a left-leaning turncoat.
|: quit
|: .
Good bye.
由于多种原因,该计划的细节存在问题。例如,我希望我们可能宁愿有一个单一的谓词来处理通过地点导航,并且我们宁愿描述对我们任务中的不同命令做出反应的地点和对象,而不是考虑每个可能的命令。但是使用不同文件的一般原则仍然有效。
另一种方法是使用consult/1 和unload_file/1 加载和卸载模块,在这种情况下,您应该能够使用它们的公共导出谓词,而不是按模块调用它们。这些和相关谓词的文档可以在"Loading Prolog Source Files"部分的手册中找到。
【讨论】:
module 是做什么的?
module/2 将当前文件声明为一个模块!第二个参数(在这种情况下为空列表)是您放置导出谓词的位置。例如,如果您使用我提到的其他方法(conulst/1 和 unload_file/1),那么您可能想要导出,例如,每个任务中的地点::- module(mission1, [place/3])(假设每个地点由一个 3 元谓词,例如,可能是 place(mission1:assertz(completed) 来断言在一个任务中为真但在另一个任务中为假的事实。那么mission1:completed 为真,但mission2:completed 仍可能为假。