2

我正在开发一个解谜器(nonograms、griddler、picross...),只是为了好玩和学习更多的 ASP。(您可以在维基百科https://en.wikipedia.org/wiki/Nonogram中阅读有关这些谜题的更多信息)

我想检查是否有一组水平连续的黑色单元格 ( cell(I,J,o)) 被两个白色单元格 ( ) 包围cell(I,J,x),一个在左侧,一个在右侧。

#const rows = 3.
#const cols = 3.

symbol(x;o).

row(0..rows+1).
col(0..cols+1).

% Padding surrounding the puzzle so we can check every group's surroundings
cell(I,0,x) :- row(I).
cell(I,cols+1,x) :- row(I).  
cell(0,J,x) :- col(J).
cell(cols+1,J,x) :- col(J).

% Assign symbols to every cell available
1 { cell(I, J, S) : symbol(S) } 1 :- row(I), col(J).

% Horizontal block (row,starting col,length)
hblock(I,J1,L) :- row(I), col(J1), col(J2), J1 <= J2, L = J2-J1+1, 
                    col(J1-1), col(J2+1), cell(I,J1..J2,o),
                    cell(I,J1-1,x), cell(I,J2+1,x).

% Output only cells that are not padding
out_cell(I,J,S) :- cell(I,J,S), I > 0, J > 0, I <= rows, J <= cols.

#hide.
#show hblock/3.
#show out_cell/3.

如您所见,我cell(I,J1..J2,o)hblock/3定义中使用来检查col(J1)和之间的每个单元格col(J2)是否为黑色(标有 o 符号),但是当给出以下输入时:

cell(1,1,x). cell(1,2,x). cell(1,3,x).
cell(2,1,o). cell(2,2,x). cell(2,3,o).
cell(3,1,x). cell(3,2,x). cell(3,3,x).

它输出hblock(2,3,1) hblock(2,1,3) hblock(2,1,1),这意味着它正在检测单个黑色单元格的两个块(In(2,1)和(2,3))以及(2,1)和(2,3)之间的三个黑色单元格的更大块,但它不应该被检测到,因为它在中间有一个标有 x 的单元格......

我究竟做错了什么?

4

1 回答 1

1

如果我没记错的话,cell(I,J1..J2,o)将为 J1 和 J2 之间的每个数字生成单独的规则。它不会将它们扩展在同一行,即在一条规则中。所以

hblock(I,J1,L) :- row(I), col(J1), col(J2), J1 <= J2, L = J2-J1+1, 
                col(J1-1), col(J2+1), cell(I,J1..J2,o),
                cell(I,J1-1,x), cell(I,J2+1,x).

扩展到

...
hblock(1,1,1) :- cell(1,1,o).
hblock(1,2,1) :- cell(1,2,o).
hblock(1,3,1) :- cell(1,3,o).
hblock(1,1,2) :- cell(1,1,o).
hblock(1,1,2) :- cell(1,2,o).
hblock(1,2,2) :- cell(1,2,o).
hblock(1,2,2) :- cell(1,3,o).
hblock(1,1,3) :- cell(1,1,o).
hblock(1,1,3) :- cell(1,2,o).
hblock(1,1,3) :- cell(1,3,o).
...

我没有弄清楚为什么hblock(2,1,2)hblock(2,2,2)失踪,但这可能不是很相关。

于 2015-12-15T16:57:48.150 回答