How to resolve the algorithm Mastermind step by step in the Prolog programming language

Published on 12 May 2024 09:40 PM

How to resolve the algorithm Mastermind step by step in the Prolog programming language

Table of Contents

Problem Statement

Create a simple version of the board game:   Mastermind. It must be possible to:

The (computer program) game should display all the player guesses and the results of that guess. Display (just an idea):

A text version example:       1.   ADEF   -   XXO- Translates to: the first guess; the four colors (ADEF); result: Happy coding!

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Mastermind step by step in the Prolog programming language

Source code in the prolog programming language

mastermind :- mastermind(7, 4, 8, no_duplicates).

mastermind(Colours, Length, Guesses, Duplicates) :-
	between(2, 20, Colours),
	between(4, 10, Length),
	between(7, 20, Guesses),
	member(Duplicates, [allow_duplicates, no_duplicates]),

	create_board(Colours, Length, Duplicates, Board),
	intro(Colours, Length, Duplicates),
	play(board(Board, Length, Colours, Guesses), [], 0), !.

intro(Colours, Length, Duplicates) :-
	format('Guess the code!~n'),
	format('There are ~p character types, and ~p letters to guess~n',
	    [Colours, Length]),
	Duplicates = allow_duplicates
	-> format('Duplicates are allowed~n~n')
	; format('Duplicates are not allowed~n~n').

/* Create the combination to be guessed */
create_board(Colours, Length, Duplicates, Board) :-
	length(Board, Length),
	valid_char_list(Colours, CharSet),
	repeat,
	maplist(random_alpha(CharSet), Board),
	check_for_duplicates(Board, Duplicates).

check_for_duplicates(_, allow_dupicates).
check_for_duplicates(Board, no_duplicates) :- is_set(Board).

/* Main loop - get the player guess and print out status */
play(board(Board,_,_,MaxGuesses), _, MaxGuesses) :-
	write('Sorry, You failed to guess in time...!\nThe code was : '),
	maplist(write, Board),
	nl.
play(BoardData, PrevGuesses, GuessNum) :-
	BoardData = board(_, Length, Colours, MaxGuesses),
	GuessNum < MaxGuesses,
	ReportedGuess is GuessNum + 1,
	format('Guess #~p of #~p: ', [ReportedGuess, MaxGuesses]),
	get_player_guess(Length, Colours, Guess),
	evaluate_and_print_result(BoardData, PrevGuesses, ReportedGuess, Guess).

evaluate_and_print_result(board(Board,_,_,_), _, _,Board) :-
	format('Well done! You Guessed Correctly.~n').
evaluate_and_print_result(BoardData, PrevGuesses, NextGuessNum, Guess) :-
	BoardData = board(Board, _, _, _),
	dif(Board, Guess),
	match_guess_to_board(Board, Guess, Diffs),
	append(PrevGuesses, [guess(NextGuessNum, Guess, Diffs)], Guesses),
	maplist(print_guess, Guesses),
	play(BoardData, Guesses, NextGuessNum).

/* Get the player guess and validate that it matches the rules */
get_player_guess(Length, Colours, Guess) :-
	repeat,
	read_line_to_string(user_input, Line),
	string_chars(Line, Guess),

	% validate the correct number of items have been entered
	length(Guess, Length),

	% validate that all the characters are valid for the number of colours
	valid_char_list(Colours, ValidCharSet),
	subset(Guess, ValidCharSet).

/* Predicates to figure out how many places are correct */
match_guess_to_board(Board, Guess, Matches) :-
	maplist(guess_differences(Board), Board, Guess, Differences),
	sort(0, @>=, Differences, Matches).

% Same position, same type
guess_differences(_Board, B, B, 'X').
% Same type, different position
guess_differences(Board, B, G, 'O') :- dif(B, G), member(G, Board).
% Type not on board
guess_differences(Board, B, G, '-') :- dif(B, G), \+ member(G, Board).

/* Print out the current progress */
print_guess(guess(NextGuessNumber, Guess, Differences))	:-
	format('~w: ', NextGuessNumber),
	maplist(format('~w '), Guess),
	format(' : '),
	maplist(format('~w '), Differences),
	nl.

/* Utils */
alpha_chars([a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t]).

valid_char_list(Colours, CharSet) :-
	alpha_chars(AllChars),
	truncate_list(AllChars, Colours, CharSet).

random_alpha(AllChars, RandomMember) :- random_member(RandomMember, AllChars).

truncate_list(_, 0, []).
truncate_list([A|T], N, [A|R]) :-
	N > 0,
	N1 is N - 1,
	truncate_list(T, N1, R).


  

You may also check:How to resolve the algorithm The sieve of Sundaram step by step in the Julia programming language
You may also check:How to resolve the algorithm Color quantization step by step in the Raku programming language
You may also check:How to resolve the algorithm Monads/List monad step by step in the Python programming language
You may also check:How to resolve the algorithm Text processing/2 step by step in the Fortran programming language
You may also check:How to resolve the algorithm Ackermann function step by step in the SNUSP programming language