网格是7个列表的列表,每个列表是一个最多可包含6个元素的列。为了胜利检查,我实施了垂直胜利和横向胜利,如下所示。但我对角线检查有问题。有什么建议?
<somevalue/>
答案 0 :(得分:1)
好吧,你有getLine/3
和getColumn/3
,让我们getDiagonal/3
:
getDiagonal(Grid, Diagonal) :-
length(Grid, Columns),
bagof(Cell,
I^Row^(between(1, Columns, I),
(nth1(I, Grid, Row),
nth1(I, Row, Cell))),
Diagonal).
这使我们得到列表中每个列表的“I
th”元素。这使得我们基本上是下降的对角线。我们需要另一个条款来获得另一个:
getDiagonal(Grid, Diagonal) :-
length(Grid, Columns),
bagof(Cell,
OppositeI^I^Row^(between(1, Columns, I),
(OppositeI is Columns + 1 - I,
nth1(I, Grid, Row),
nth1(OppositeI, Row, Cell))),
Diagonal).
这里的^
语法是量词;它基本上告诉bagof/3
我们不认为这些变量的不同实例化需要新的包。 findall/3
更简洁,但我对bagof/3
有一种奇怪的偏好。
构建完成后,您可以按照垂直和水平情况的方式解决问题。
答案 1 :(得分:0)
仅使用列表扫描,一个2胜的例子,匹配前向和后向对角线:
test(J) :- Grid=[
[-,-,-,-,-,-,-],
[-,-,-,-,-,-,-],
[-,-,-,J,-,-,-],
[-,-,J,-,J,-,-],
[-,J,-,-,-,J,-],
[J,-,-,-,-,-,J]
], append(_,[A,B,C,D|_],Grid), % test 4 consecutive rows
( start([A,B,C,D],J) ; start([D,C,B,A],J) ).
% on first row of 4, find first matching column
start([[J|_]|R],J) :- skip1(R,S), diag(S,J). % first found, match diag
start(R,J) :- skip1(R,S), start(S,J).
% each first cell of rows' sequence must match
diag([[J|_]],J). % last row: success
diag([[J|_]|T],J) :- skip1(T,S), diag(S,J).
% discard first column of each row
skip1([],[]).
skip1([[_|R]|T],[R|S]) :- skip1(T,S).
我认为它应该独立于矩阵表示,而不是面向行或列。注释假定面向行的表示。