实施反击序言

时间:2014-11-04 10:39:30

标签: prolog

我在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一次并从那里开始。关于如何解决这两个问题的任何提示?

2 个答案:

答案 0 :(得分:2)

您无法更改已绑定的变量的值。您需要使用新变量,例如I1 is I + 1succ(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.

还有其他谓词可以提供类似的功能,具体取决于您的目标是什么。例如,请参阅findallmaplist

但是如果你记得做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).