我正在尝试在Prolog中编写一个简单的Noughts-and-Crosses(Tic-tac-Toe)评估器。 我要做的第一件事就是让程序计算所有可能的获胜板。逻辑尚未完成 - 它不会检查可能因实际游戏而产生的有效电路板 - 它只是在寻找任何“3行”。
问题是,程序'stop-short':它正确检测3行,并统一构成3行的变量 - 但不显示其他变量的组合。 (不在胜利线上的细胞)。
这是我的程序和示例输出:
/*
Attempting to create a program that will output 'x' ,'o' or 'none'
given a (filled-in) tic-tac-toe board.
'x' - 'x' has won. (Literally there is a line of x's)
'o' - 'o' as above
'none' : no winners on the given board.
This does NOT check whether the board is in a valid state for tic-tac-toe!
*/
/* Define board states as facts */
cell(none).
cell(x).
cell(o).
/* Define winning line of 3 */
win_line(C1, C2, C3, Winner) :-
cell(C1),
cell(C2),
cell(C3),
C1 \== none,
C1==C2,
C2==C3,
Winner=C1.
/* define the board rule: variables are 'encoded' for each cell by a coordinate (col,row) */
board( C11, C12, C13,
C21, C22, C23,
C31, C32, C34, Winner) :-
win_line(C11, C12, C13, Winner); /* Test the three rows */
win_line(C21, C22, C23, Winner);
win_line(C31, C32, C33, Winner);
win_line(C11, C21, C31, Winner); /* Test the three columns */
win_line(C12, C22, C32, Winner);
win_line(C13, C23, C34, Winner);
win_line(C13, C23, C34, Winner); /* Test the two diaganols */
win_line(C11, C22, C34, Winner);
win_line(C13, C22, C31, Winner).
我的查询,输出如下:
| ?- board(C11,C12,C13, C21,C22,C23, C31,C32,C33, o).
C11 = o
C12 = o
C13 = o ? a
C21 = o
C22 = o
C23 = o
C31 = o
C32 = o
C11 = o
C21 = o
C31 = o
C12 = o
C22 = o
C32 = o
C13 = o
C23 = o
C33 = o
C13 = o
C23 = o
C33 = o
C11 = o
C22 = o
C33 = o
C13 = o
C22 = o
C31 = o
(4 ms) yes
版本信息:
GNU Prolog 1.3.0
By Daniel Diaz
Copyright (C) 1999-2007 Daniel Diaz
| ?-
答案 0 :(得分:1)
我看到你修复了第一个问题。
获取查询所有可能结果的一种方法是使用findall/3
:
?- findall([A,B,C,D,E,F,G,H,I], board(A,B,C,D,E,F,G,H,I,o), Results).
Results = [[o,o,o,_,_,_,_,_,_],
[_,_,_,o,o,o,_,_,_],
[_,_,_,_,_,_,o,o,o],
[o,_,_,o,_,_,o,_,_],
[_,o,_,_,o,_,_,o,_],
[_,_,o,_,_,o,_,_,o],
[_,_,o,_,_,o,_,_,o],
[o,_,_,_,o,_,_,_,o],
[_,_,o,_,o,_,o,_,_]]
请注意,它只考虑了在这种情况下实际上重要的值,只留下其他值。
如果你需要将其他值锁定到实际原子,有很多方法可以做到这一点,虽然它涉及编写另外几个谓词来查找所有可能的值组合以获得结果,对于Results
中的每个结果。
答案 1 :(得分:0)
知道了 - 我想 - 我改变了这样的董事会规则:
/* define the board rule: variables are 'encoded' for each cell by a coordinate (col,row) */
board( C11, C12, C13,
C21, C22, C23,
C31, C32, C34, Winner) :-
cell(C11), cell(C12), cell(C13),
cell(C21), cell(C22), cell(C23),
cell(C31), cell(C32), cell(C33),
win_line(C11, C12, C13, Winner); /* Test the three rows */
[...]as before
因此,在每个变量与细胞事实相结合的进一步条款中添加...不是100%确定为什么我需要这样做......但它似乎有效......