【问题标题】:Mastermind in Prolog - backtrackingProlog 中的策划者 - 回溯
【发布时间】:2015-01-25 16:59:18
【问题描述】:

编辑 2:

解决了使用列表中的列表。感谢您的帮助。


我尝试在 Prolog 中制作 Mastermind。我有一个功能

guess(Colors, Size, Possibilities, Answer, Black, White)

计算使用的颜色、游戏区域的大小、颜色列表和用户对答案的评价。它可能看起来像:

guess(4, 6, P, [red, red, blue, green, green, yellow], 2, 3)

这意味着有 4 种颜色,6 个位置用于钉子和猜测

[red, red, blue, green, green, yellow] 得到 2 个黑色钉和 3 个白色钉。


当我像这样直接调用这些函数时

guess(4, 6, O, [red, red, blue, green, green, yellow], 2, 3), 
guess(4, 6, O, [red, yellow, green, blue, red, blue], 0, 4), 
guess(4, 6, O, [green, blue, yellow, red, green, yellow], 4, 2), 
guess(4, 6, O, [yellow, blue, red, yellow, green, yellow], 5, 0).

它给了我正确的答案O = [green, blue, red, yellow, green, yellow]


现在我尝试让它更具交互性,所以我创建了函数

play:-
    write('Size: '), read(Size), nl,
    write('Colors: '), read(Colors), nl,
    createFirstGuess(Size, Colors, [], A), //initial guess
    run(Colors, Size, _, A).

run(Colors, Size, P, A) :- 
    tryGuess(Colors, Size, J, A),   //Possibilities in J
    copy(J, X),   //First possible result J -> X
    J = P,   //Unification of all results
    run(Colors, Size, J, X).   //loop

tryGuess(_, _, _, []) :- !. 
tryGuess(Colors, Size, P, A) :- 
    write('Evaluation of: '), write(A), nl,
    write('Black pegs: '), read(B), nl, 
    write('White pegs: '), read(W), nl,
    guess(Colors, Size, P, A, B, W).

copy([],[]) :- !.    //Copy list T1 to T2
copy([H|T1],[H|T2]) :- !, copy(T1,T2).

createFirstGuess(0, _, L, L) :- !.   //Initial guess (just field of the same colors)    
createFirstGuess(N, Colors, R, L) :-
    N > 0, N1 is N - 1, color(Colors, H), createFirstGuess(N1, Colors, [H|R], L).

我运行“播放”,设置大小和颜色数量开始播放。

Evaluation of: [red, red, red, red, red, red]   //Initial guess
Black pegs: 1.
White pegs: 0.

Evaluation of: [red, green, green, green, green, green]  //OK
Black pegs: 1.
White pegs: 2.

Evaluation of: [red, green, green, green, green, blue]  //Bad, it goes through the list one-by-one
Black pegs: 1.
White pegs: 2.

Evaluation of: [red, green, green, green, green, yellow]   //Bad
Black pegs: 2.
White pegs: 2.

Evaluation of: [red, green, green, green, blue, green]   //Bad
Black pegs: 0.
White pegs: 4.

似乎前两个答案很好(一个是初始的,第二个是计算的),但下一个只是一个接一个地遍历所有可能性。我认为回溯有问题,所以应该有一些削减(),但我无法找到将它们放在哪里。

感谢您的帮助。

编辑:

感谢您的帮助。

我想得到这样的输出:

Evaluation of: [red, red, red, red, red, red]   //Initial guess
Black pegs: 1.
White pegs: 0.

Evaluation of: [red, green, green, green, green, green]
Black pegs: 1.
White pegs: 2.

Evaluation of: [green, red, blue, yellow, green, blue]
Black pegs: 3.
White pegs: 2.

Evaluation of: [green, blue, yellow, yellow, green, red]
Black pegs: 4.
White pegs: 2.

Evaluation of: [green, blue, red, yellow, green, yellow]
Black pegs: 6.
White pegs: 0.

End of Game

但是,就我而言,prolog 会逐一遍历所有可能性的列表,但是当我使用 guess(如上所示)时效果很好。统一和回溯肯定有问题。起初我使用初始列表并获得正确的可能结果。然后我取第一个结果,让玩家评估它。这是我用于下一个guess 的玩家评估的第一个结果,但是有一个问题。如我所见,由于回溯是这个结果(answer)重新统一,所以无论评价如何,玩家都必须一一浏览列表。

我认为,如果玩家评估的答案不会重新统一,它应该可以工作,但我找不到这样做的方法。

【问题讨论】:

  • Prolog 没有函数,它有定义关系的谓词copy(J, X), 只是统一 JX 一次一个元素。它与J = X 做同样的事情。然后将JP 统一起来(如J = P)。所以JXP都统一在那个子句中,代表同一个东西。这就是统一。它不像在其他语言中那样分配一个值给另一个变量位置。如果你这样做了,X = [A,B], copy(X, Y), A = 1, B = 2. 你会得到X = [1,2]Y = [1,2]
  • 您显示了您不喜欢的输出。你能描述一下你喜欢它的输出吗?

标签: prolog backtracking


【解决方案1】:

好的,我终于用列表中的列表解决了它保存答案和评估。然后我只是扩展这些列表并使用它来构建更精确的解决方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-06
    相关资源
    最近更新 更多