2017-01-24 7 views
0

Я пытаюсь реализовать игру-вдохновителя, правила можно найти на https://en.wikipedia.org/wiki/Mastermind_(board_game).ОШИБКА: Из глобального стека в игре вдохновителя

Программа генерирует последовательность из четырех различных цветов. У игрока 10 поворотов, чтобы угадать код.

Я знаю, что код может быть улучшен, но на данный момент я пытаюсь решить ошибку глобального стека. Это происходит, когда я подсчитываю количество белых колышек, но не всегда. Вероятно, проблема заключается в общем или отдельном предикате (или и том и другом).

Я новичок в Прологе, и я ценю любую помощь.

Пожалуйста найти код на https://github.com/kmdeoliv/mastermind

+0

Немного невежливо указать на репо; лучше включить [минимальный пример] (http://stackoverflow.com/help/mcve).Подготовка минимального примера, вероятно, поможет вам изолировать проблему и, возможно, облегчит обе наши жизни. –

+0

Не ответ, но некоторые из ваших предикатов имеют стандартные копии: 'member1/2' is' memberchk/2', я бы использовал 'sort/2' вместо' distinct/2', 'nonmember/2' Я бы заменил с '\ + member (...)'. Вы используете '!' Достаточно, чтобы меня нервничать, но я не видел там очевидных ошибок. Помимо этого, это не выглядит ужасно; Я бы использовал более мощные предикаты форматирования и больше отделял логику от презентации, но для новичков это выглядит очень хорошо. –

ответ

1

Заменить member1 с memberchk и ваш код будет работать намного лучше. Причина удивит вас! Давайте добавим некоторые «отладочные printfs» к вашему member1/2 предиката:

member1(X,[H|_]) :- format('testing ~w == ~w?~n', [X,H]), X==H,!. 
member1(X,[_|T]) :- format('looking in tail ~w for ~w~n', [T,X]), member1(X,T). 

Кажется, работает хорошо, не так ли?

?- member1(bar, [foo,bar,baz]). 
testing bar == foo? 
looking in tail [bar,baz] for bar 
testing bar == bar? 
true. 

Кстати, memberchk/2 делает то же самое:

?- memberchk(bar, [foo,bar,baz]). 
true. 

Ну, мы получаем "истинный". :) Но что произойдет, если я передам ему что-то странное, как переменную вместо списка?

?- memberchk(bar, V). 
V = [bar|_G483709]. 

Ах, ну, memberchk/2 принимает это как своего рода утверждение, что это в верхней части списка (это потому, что он делает то, что member/2 делает, но только один раствор). Что делает member1/2?

?- member1(bar, V). 
looking in tail _G478121 for bar 
testing bar == _G478129? 
looking in tail _G478130 for bar 
testing bar == _G478138? 
looking in tail _G478139 for bar 
testing bar == _G478147? 
looking in tail _G478148 for bar 
testing bar == _G478156? 
looking in tail _G478157 for bar 
testing bar == _G478165? 
looking in tail _G478166 for bar 
testing bar == _G478174? 
looking in tail _G478175 for bar 
testing bar == _G478183? 
... 
eventually, boom, stack depth exceeded 

Удивительно, но ваш код действительно входит в этот случай! Обратите внимание на то, что у вас есть условия, определяющие переменные с одной стороны, а не другой:

(B1==B2 -> K is J + 1; K is J + 0, LB1=[B1],LB2=[B2]), 

Какие ценности LB1 и LB2 считать, если B1 не равен B2? Они остаются неподготовленными! Затем несколько строк позже вы безоговорочно добавить их:

append(LA1,LB1,AB1), 
append(LC1,LD1,CD1), 
append(AB1,CD1,L1), 

Так к этому моменту, L1 = LA1 + LB1 + LC1 + LD1, но LB1 это чистая переменная! Это может произойти с любыми ваших переменных LX1/LX2, а затем вы завершаете ввод member1/2 с каким-то отверстием в вашем списке!

Это не ошибка в Прологе, между прочим. Например, если вы хотите, например, оставить хвост списка списков неинтересных различий.

Теперь у меня есть ведра другого совета для вас, но я думаю, что мораль этой истории прямо сейчас заключается в том, что вы должны использовать встроенные предикаты, когда это возможно. :)

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

  • Нет связанных вопросов^_^