2017-01-24 1 views
0

Ich versuche, ein Genie Spiel zu implementieren, können die Regeln auf https://en.wikipedia.org/wiki/Mastermind_(board_game) finden.ERROR: Out of global Stapel in Drahtzieher Spiel

Das Programm erzeugt eine Sequenz von vier verschiedenen Farben. Der Spieler hat 10 Runden um den Code zu erraten.

Ich weiß, dass der Code verbessert werden kann, aber jetzt versuche ich einen aus globalen Stack-Fehler zu lösen. Es tritt auf, wenn ich die Anzahl der weißen Pflöcke zähle, aber nicht immer. Wahrscheinlich liegt das Problem im gemeinsamen oder unterschiedlichen Prädikat (oder beiden).

Ich bin ein Anfänger in Prolog und ich freuen uns über jede Hilfe.

finden Sie den Code auf https://github.com/kmdeoliv/mastermind

+0

Es ist ein bisschen unhöflich, auf ein Repo zu zeigen; Es ist besser, ein [minimales Beispiel] (http://stackoverflow.com/help/mcve) einzuschließen.Das Vorbereiten eines minimalen Beispiels würde Ihnen wahrscheinlich helfen, das Problem zu isolieren und wahrscheinlich unser beider Leben einfacher zu machen. –

+0

Nicht eine Antwort genau, aber einige Ihrer Prädikate haben Standardgegenstücke: 'member1/2' ist' memberchk/2', ich würde 'sort/2' anstelle von' distinct/2' verwenden, 'nonmember/2' würde ich ersetzen mit '\ + member (...)'. Du benutzt "!" Genug, um mich nervös zu machen, aber ich habe dort keine offensichtlichen Fehler gesehen. Darüber hinaus sieht es nicht schrecklich aus; Ich würde stärkere Formatierungsprädikate verwenden und die Logik von der Präsentation mehr trennen, aber für einen Anfänger sieht das sehr gut aus. –

Antwort

1

ersetzen member1 mit memberchk und Ihr Code wird viel besser funktionieren. Der Grund, warum Sie überraschen werden! Lassen Sie uns einige "Debuggen printfs" zu Ihrem member1/2 Prädikat hinzu:

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

scheint OK zu arbeiten, nicht wahr?

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

Übrigens tut memberchk/2 das Gleiche:

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

Nun, wir bekommen "true". :) Aber was passiert, wenn ich etwas Seltsames übergebe, wie eine Variable statt einer Liste?

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

Ah, na ja, memberchk/2 wird dies als eine Art Behauptung nehmen, dass es an der Spitze der Liste ist (dies ist, weil es das tut, was member/2 tut, aber mit nur einer Lösung). Was macht 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 

Überraschenderweise tritt Ihr Code tatsächlich in diesen Fall ein! Beachten Sie, dass Sie Bedingungen, die Variablen auf einer Seite definieren, aber nicht die andere:

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

Welche Werte LB1 und LB2 nehmen, wenn B1 zu B2 nicht gleich? Sie bleiben uninstantiiert! Dann ein paar Zeilen später Sie bedingungslos hängen Sie sie:

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

So von diesem Punkt L1 = LA1 + LB1 + LC1 + LD1, aber LB1 ist eine reine Variable! Dies kann passieren einer beliebigen Ihrer LX1/LX2-Variablen, und dann landen Sie member1/2 mit einer Art Loch in Ihrer Liste eingeben! Diese

ist kein Fehler in Prolog, nebenbei bemerkt. Es gibt Zeiten, in denen Sie beispielsweise das Ende einer Liste uninstantiierter Differenzlisten verlassen wollen.

Nun, ich habe Eimer andere Ratschläge für Sie, aber ich denke, die Moral der jetzt Geschichte ist, dass Sie, wann immer möglich Einbau-Prädikate verwenden sollten. :)