2016-01-13 67 views
0

網格是7個列表的列表,每個列表是一個最多可包含6個元素的列。爲了勝利檢查,我實施了垂直勝利和橫向勝利,如下所示。但我在對角線檢查方面存在問題。有什麼建議麼?序言:connect4檢查對角線結尾

% Vertical end check 
isEndVert(Grid, J, N) :- 
    getColumn(N, Grid, Column),   
    sublist([J,J,J,J], Column), 
    !. 
isEndVert(Grid, J, N) :- 
    N > 0, 
    N1 is N-1, 
    isEndVert(Grid, J, N1). 

% Horizontal end check 
isEndHor(Grid, J, N) :- 
    getLine(N, Grid, Line), 
    sublist([J,J,J,J], Line), 
    !.          
isEndHor(Grid, J, N) :- 
    N > 0, 
    N1 is N-1, 
    isEndHor(Grid, J, N1). 

回答

1

那麼,你必須getLine/3getColumn/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個」元素從一編號的每個列表這會讓我們基本降對角線。我們需要一個條款,以獲得其他:

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

建成後,您可能可以解決問題的方式爲垂直和水平情況。

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). 

我認爲它應該獨立工作的矩陣表示爲取向的行或列的。評論假設一個面向行的表示。

+0

這對我來說很不透明。我發現它很有用(讚美!),但它是如何成爲頭腦的人。 –

+0

@DanielLyons:是的,雖然 – CapelliC

+0

有點棘手,但效率不高。 :) –