prolog - 如何在 Prolog 中编写特定游戏?
问题描述
我在编写下述程序时遇到问题
考虑下面的游戏。给出了一个带有三颗黑子、三颗白子和一个空白区域的棋盘。游戏的目标是将黑棋子与白棋子交换位置。移动规则定义以下句子: 交替移动白色和黑色块。每个棋子可以垂直或水平移动,占据一个空白空间。每一块都可以垂直或水平地跳过另一块(任何颜色)。在 Prolog 中编写一个程序,找出所有可能的方法来找到一个获胜的序列。例如,如果我们问这个问题:
? - play (w, s (w, w, w, e, b, b, b), s (b, b, b, e, w, w, w), S, R ).
序言应该回答,例如:
S = [s (w, w, w, e, b, b, b), s (w, e, w, w, b, b, b), ..., s (b, b, b, e, w, w, w)] R = [[w, 2,4], [b, 6,2], [w, 4,6], ..., [w, 4,6]]
这里[ w, 2,4]
意味着将白兵从位置 2 移动到位置 4。当然 Prolog 应该完整返回字母 S 和 R(不带“...”)。
棋盘上不同棋子设置的最大数量是多少?检查查询:
? - play (_, s (w, w, w, e, b, b, b), s (b, b, e, w, w, b, w), _, _).
Prolog的答案是什么意思?提示:先解决play/4
没有 R的问题
还有一个看起来像这样的游戏板:
我根本不知道从哪里开始?我怎样才能做到这一点?各位大佬能帮我看看这个吗?
解决方案
这是标准状态空间搜索,至少从 50 年代中期开始就是 GOFAI 的标准范式。
准系统算法:
search(State,Path,Path) :- is_final(State),!. % Done, bounce "Path" term
search(State,PathSoFar,PathOut) :-
generate_applicable_operators(State,Operators),
(is_empty(Operators) -> fail ; true),
select_operator(Operators,Op,PathSoFar),
apply_operator(State,Op,NextState), % depth-first / best first
search(NextState,[[NextState,Op]|PathSoFar],PathOut).
% Called like this, where Path will contain the reverse Path through
% State Space by which one may reach a final state:
search(InitialState,[[InitialState,nop]],Path).
首先,您需要在这种情况下表示给定状态,即棋盘状态(在某个时间 t)。
我们可以列出棋盘位置及其内容(w
白色、黑色、b
空令牌)或列出令牌及其位置。让我们列出董事会职位。e
在 Prolog 中,可以轻松进行模式匹配的术语是合适的。这个问题已经提供了一些东西:(w, w, w, e, b, b, b)
。这似乎受到 LISP 的启发,并不能很好地适应 Prolog。让我们使用一个列表来代替:[w, w, w, e, b, b, b]
董事会职位与列表职位的映射应为:
+---+---+
| 0 | 1 |
+---+---+---+
| 2 | 3 | 4 |
+---+---+---+
| 5 | 6 |
+---+---+
我们已经完成了状态描述的设置!
然后您需要表示/定义可以应用于状态的运算符(操作?):它们将有效状态转换为另一个有效状态。
运算符对应于“移动令牌”,当然并非所有运算符都适用于给定状态(如果那里没有令牌,则不能从字段 1 移动令牌;如果已经有令牌,则不能将令牌移动到字段 1那里)。
因此,您想编写一个谓词,将棋盘状态链接到适用于该状态的运算符:generate_applicable_operators/2
然后您需要选择您要申请的运营商。这可以根据一些启发式(例如A*)随机、详尽地完成,但绝对需要检查到目前为止通过状态空间所采用的路径以避免循环:select_operator/3
。
然后应用运算符生成下一个状态:apply_operator/3
.
最后递归调用search/3
寻找下一步。这一直持续到“最终状态”,在这种情况下[b, b, b, e, w, w, w]
已经达到!
如果要执行“广度优先搜索”,也可以使用迭代深化,但必须修改算法结构。
就是这样。
推荐阅读
- c++ - 如何在虚幻引擎中使用第三方库 Eigen?
- javascript - 在“片段”中键入段落时出错
- javascript - Bootstrap 5:在 Button 中对齐图标和文本
- python - Python Pandas 删除具有数字的行(不是浮点数也不是整数,而是像 1.2.3)
- python - 移植到 Python 3.7,poster3.encode.multipart_encode,TypeError: memoryview: a bytes-like object is required, not 'str'
- angular - 在 Angular 中使用 IconFinderCore 进行图标化返回“not_found”错误
- r - 如何返回列的行值,使得它们在另一列中的对应值是最小的 n 值,在 R
- amazon-web-services - AWS DeviceFarm 忽略 TestNG 注释
- c# - c#位运算符'&'和'Enum.HasFlag'的区别
- html - 在反应中使禁用的按钮触发onClick事件