2014-11-04 2 views
0

Я развивающийся настольную игру в 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

http://www.cs.bham.ac.uk/~pjh/prolog_course/md5/md5_accumulators.html посмотреть на первом примере. Вам нужно что-то подобное? – Otrebor

+0

Ну, это решило, ты! :) – Khabz

+0

Вопрос по-прежнему остается тем, почему вычисление остановилось после этой строки кода? (См. Выше) – Khabz

ответ

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). 
+0

Исправлено, спасибо! – Khabz

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.

+0

Я ценю и понимаю ваш ответ, но я искал более простое решение, похожее на c/C++ как мог. – Khabz

+0

@Khabz :) добро пожаловать. Это вопрос вкуса, и ваше решение на самом деле намного ближе к Prolog, в то время как то, что я показываю здесь, просто эмулирует цикл for в стиле C/C++.Вы никогда не напишете рекурсивную функцию, чтобы просто перечислять элементы массива в C, не так ли?) –

+1

Hell no! Я думал, что я избавлюсь от такого рода языков после обучения Scheme, но я думаю, что мой колледж действительно любит преподавать эти неинтуитивные прог-языки :( – Khabz

Смежные вопросы