Prolog 中的策划者 - 回溯
Mastermind in Prolog - backtracking
编辑 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).
I 运行 'play',设置大小和颜色数量开始播放。
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)重新统一,所以无论评估如何,玩家都必须逐一检查列表。
我觉得应该可以,如果玩家评价的答案不会统一,但我找不到办法。
好的,我终于用列表中的列表解决了这个问题保存答案和评价。然后我只是扩展这些列表并将其用于构建更精确的解决方案。
编辑 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).
I 运行 'play',设置大小和颜色数量开始播放。
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)重新统一,所以无论评估如何,玩家都必须逐一检查列表。
我觉得应该可以,如果玩家评价的答案不会统一,但我找不到办法。
好的,我终于用列表中的列表解决了这个问题保存答案和评价。然后我只是扩展这些列表并将其用于构建更精确的解决方案。