1
2/*
3 *	MASTERMIND GAME
4 */
5
6:- module(mastermind).
7
8:- lib(master_tools, master_tools).
9:- lib(master_basic, master_basic).
10
11:- import
12	selects/2,
13	exact_matches/3
14   from master_tools.
15
16:- import
17	length/2
18   from master_basic.
19
20:- dynamic query/3.
21
22
23mastermind :-
24	cleanup,
25	guess(Code),
26	check(Code),
27	announce.
28
29guess([X1, X2, X3, X4]) :-
30	selects([X1, X2, X3, X4], [1,2,3,4,5,6,7,8,9,0]).
31
32
33/*
34 *  verify the proposed guess
35 */
36
37check(Guess) :-
38	~ inconsistent(Guess),
39	ask(Guess).
40
41inconsistent(Guess) :-
42	query(OldGuess, Bulls, Cows),
43	~ bulls_and_cows_match(OldGeuss, Guess, Bulls, Cows).
44
45buls_and_cows_match(OldGuess, Guess, Bulls, Cows) :-
46	exact_matches(Oldguess, Guess, N1),
47	Bulls = N1,			% correct number of bulls
48	common_members(OldGuess, Guess, N2),
49	Cows is N2 - Bulls.		% correct number of cows
50
51
52/*
53 * asking a guess
54 */
55
56ask(Guess) :-
57	repeat,
58		printf("How many bulls and cows in %w ? ", [Guess]),
59		read((Bulls, Cows)),
60		sensible(Bulls, Cows),
61		!,
62		assert(query(Guess, Bulls, Cows)),
63		Bulls == 4.
64
65sensible(Bulls, Cows) :-
66	integer(Bulls),
67	integer(Cows),
68	Bulls + Cows =< 4.
69
70
71/*
72 *  bookkeeping
73 */
74
75cleanup :-
76	retract_all(query(_,_,_)).
77
78announce :-
79	size_of(X, A^(B^(query(X, A, B))), N),
80	printf("Found the answer after %w queries.\n", [N]).
81
82size_of(X, Goal, N) :-
83	setof(X, Goal, Instances),
84	length(Instances, N).
85
86
87
88
89