网格中连续的一组单元格

时间:2015-12-12 11:19:23

标签: answer-set-programming

我正在制作一个拼图解算器(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的单元......

我做错了什么?

1 个答案:

答案 0 :(得分: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)缺失,但这可能不太相关。