我有一项任务,我必须使用Prolog来解决战舰难题。我目前的解决方案遍及整个领域,并将一条船放在它当前所在的坐标上。如果那里没有允许船的任何部分(我只看一下给出的船的总和。)它放了一些水。
example(X) :-
battleship(
[
[n,_,'~',_,_,_,_,n],
[_,_,n,'~',_,o,_,_],
['~','~',_,'~',_,_,_,s],
[_,'~',x,'~',_,_,'~','~'],
[_,_,_,'~',_,_,n,_],
[_,_,_,'~',_,_,_,_],
[_,_,_,x,_,'~',_,_],
[_,_,_,_,_,_,_,_]
],
[5,0,5,1,2,1,2,4],[2,4,2,3,2,1,4,2],[4,3,2,1],X).
上面这句话就是你所说的。第一个参数是水域为~
的字段,_
为未知,其他所有字段均为船只的一部分。第二个参数是每列中船的总和,第三个参数是相同的但是对于行。第四个参数是船的大小,最后的论点是我应该把结果放在哪里。
battleship(Grid, Columns, Rows, Ships, Result) :-
print(Result),
fillField(Grid, Columns, Rows, Ships, Result).
fillField(Grid, Columns, Rows, Ships, Result) :-
fillRows(Grid, Columns, Rows, Ships, Result, 0).
fillRows(Grid, Columns, Rows, Ships, Result, RowIndex) :-
length(Grid, Length),
RowIndex >= Length,
print(Grid), print('\n'),
print('Done\n').
fillRows(Grid, Columns, Rows, Ships, Result, RowIndex) :-
length(Grid, Length),
RowIndex < Length,
fillRow(Grid, Columns, Rows, Ships, Result, RowIndex, 0),
NextRow is RowIndex + 1,
fillRows(Grid, Columns, Rows, Ships, Result, NextRow).
fillRow(Grid, Columns, Rows, Ships, Result, RowIndex, ElemIndex) :-
print(Grid),print('\n'),
length(Grid, Length),
ElemIndex >= Length.
fillRow(Grid, Columns, Rows, Ships, Result, RowIndex, ElemIndex) :-
length(Grid, Length),
ElemIndex < Length,
isLegalShip(Grid, RowIndex, ElemIndex),
nth0(RowIndex, Rows, R1),
R2 is R1 - 1,
R2 >= 0,
replace(Rows, RowIndex, R2, NewRows),
nth0(ElemIndex, Columns, C1),
C2 is C1 - 1,
C2 >= 0,
replace(Columns, ColumnIndex, C2, NewColumns),
NextElem is ElemIndex + 1,
fillRow(Grid, NewColumns, NewRows, Ships, Result, RowIndex, NextElem).
fillRow(Grid, Columns, Rows, Ships, Result, RowIndex, ElemIndex) :-
length(Grid, Length),
ElemIndex < Length,
isSea(Grid, RowIndex, ElemIndex),
NextElem is ElemIndex + 1,
fillRow(Grid, Columns, Rows, Ships, Result, RowIndex, NextElem).
isLegalShip(Grid, RowIndex, ElemIndex) :-
nth0(RowIndex, Grid, Row),
nth0(ElemIndex, Row, Element),
isShip(Element).
replace([_|Tail], 0, Value, [Value|Tail]).
replace([Head|Tail], Index, Value, [Head|R]):-
Index > 0,
NextIndex is Index - 1,
replace(Tail, NextIndex, Value, R).
isSea(Grid, RowIndex, ElemIndex) :-
nth0(RowIndex, Grid, Row),
nth0(ElemIndex, Row, '~').
isShip(x).
isShip(o).
isShip(e).
isShip(s).
isShip(w).
isShip(n).
解决这样的问题将从右上角开始,然后左右移动以填充该字段。然而,当需要回溯因为它被卡住它失败了。使用此示例,x
将放置在位置(0,3)
上,这是错误的。当我们到达行的末尾时,我们找到了另一条船,并发现出了问题。她回到我们放置x
的地方。它现在应该放~
,但它告诉我:
ERROR: >/2: Arguments are not sufficiently instantiated
Exception: (13) fillRow([[n, ~, ~, _G907, _G910, _G913, _G916|...], [_G925, _G928, n, ~, _G937, o|...], [~, ~, _G958, ~, _G964|...], [_G979, ~, x, ~|...], [_G1006, _G1009, _G1012|...], [_G1033, _G1036|...], [_G1060|...], [...|...]], [4, 0, 5, 1, 2, 1, 2, 4], [1, 4, 2, 3, 2, 1, 4, 2], [4, 3, 2, 1], _G828, 0, 3) ? creep
Exception: (10) fillRow([[n, _G901, ~, _G907, _G910, _G913, _G916|...], [_G925, _G928, n, ~, _G937, o|...], [~, ~, _G958, ~, _G964|...], [_G979, ~, x, ~|...], [_G1006, _G1009, _G1012|...], [_G1033, _G1036|...], [_G1060|...], [...|...]], [5, 0, 5, 1, 2, 1, 2, 4], [2, 4, 2, 3, 2, 1, 4, 2], [4, 3, 2, 1], _G828, 0, 0) ? creep
我只有Prolog的一些基本知识,无法弄清楚出了什么问题。
任何帮助都会受到赞赏,我希望这个问题有点清楚。
答案 0 :(得分:3)
在fillRow/2
的第二个条款中,你有这一行:
replace(Columns, ColumnIndex, C2, NewColumns),
ColumnIndex
是一个单身,这意味着代码中没有其他任何地方可以使用它。例如:您没有将其设置为任何值。这就是为什么在replace/4
的第2条中你在这一行中有错误的原因:
Index > 0,
由于Index
等同于ColumnIndex
,因此未设置Index
(未充分实例化)并且无法进行比较。因此,一个错误。