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