我在PROLOG开发棋盘游戏,为了让用户更喜欢界面,我决定添加一个坐标为(0-> 4)的网格,如下所示:
0 1 2 3 4
---------
0 | x x x x x
1 | x o x o o
2 | o x o x x
3 | x x o o o
4 | o x x x o
在开发了一些代码之后,我遇到了关于垂直坐标计数器的问题。在我实现计数器Index is Index + 1
后,谓词就会停止,如下所示:
printGrid :- %Only prints the horizontal grid
write('\t'), write(0), write(' '), write(1), write(' '), write(2), write(' '), write(3), write(' '), write(4), nl,
write('\t'), write('------------------'), nl.
printBoard([Head|Tail]) :-
Index = 0,
Index is Index + 1,
% STOPS HERE ------------
write(' '), write(Index), write(' |'), write(' '),
printRow(Head),
printBoard(Tail).
printBoard([]).
printRow([Head|Tail]) :-
write(Head),
write(' '),
printRow(Tail).
printRow([]) :- nl.
我知道每次调用递归时计数器都会重置为0,因此我真的不知道如何将索引设置为0一次并从那里开始。关于如何解决这两个问题的任何提示?
答案 0 :(得分:2)
您无法更改已绑定的变量的值。您需要使用新变量,例如I1 is I + 1
或succ(I, I1)
。
如果您想要使用副作用(在您的情况下打印),您可以做的另一件事是将between
置于forall
循环中:
?- forall(between(0, 4, X), format('~d~n', [X])).
0
1
2
3
4
true.
您当然可以嵌套forall
s:
?- forall(between(0, 5, X),
( forall(between(0, 4, Y),
format('~d-~d ', [X,Y])),
format('~n')
)).
0-0 0-1 0-2 0-3 0-4
1-0 1-1 1-2 1-3 1-4
2-0 2-1 2-2 2-3 2-4
3-0 3-1 3-2 3-3 3-4
4-0 4-1 4-2 4-3 4-4
5-0 5-1 5-2 5-3 5-4
true.
然后,枚举列表成员的方法是使用nth0
,例如,
?- forall(nth0(N, [a,b,c,d], E), format('~d-~a~n', [N,E])).
0-a
1-b
2-c
3-d
true.
或者,如果您不需要该元素(当您只是标记列时:
?- length([a,b,c,d], Len),
Last is Len - 1,
forall(between(0, Last, X), format('~d~n', [X])).
0
1
2
3
Len = 4,
Last = 3.
或者在使用nth0
时忽略该元素:
?- forall(nth0(N, [a,b,c,d], _), format('~d~n', [N])).
0
1
2
3
true.
还有其他谓词可以提供类似的功能,具体取决于您的目标是什么。例如,请参阅findall
和maplist
。
但是如果你记得做I1 is I + 1
,你当然可以自己做递归。
答案 1 :(得分:1)
我检查了@Otrebor提供的链接,我想出了一个很好的解决方案。我忘记了"小"细节,当绑定时,变量无法更改,因此我添加了一个额外的变量。这是它的外观:
printBoard([], _).
printBoard([Head|Tail], Counter) :-
Index is Counter + 1,
write(' '), write(Index), write(' |'), write(' '),
printRow(Head),
printBoard(Tail, Index).
main :- printBoard(Board, 0).