Click here to Skip to main content
Click here to Skip to main content

Mastermind Human&Computer Player Implementation in C++

By , 22 Sep 2010
Rate this:
Please Sign up or sign in to vote.

Introduction

Have you played chess or card games with computers and be suprised how smart they are?

Elements of artificial intelligence used in computer games have come a long way. In the beginning, the developed systems were based on sets of rules written directly in the code of the game or on the behaviour scripts interpreted by the code, with the whole thing based most commonly on the appropriate selection of importance of the random factor in the process of choosing the appropriate behaviour. That time witnessed the birth of such memorable games as the immortal River-Raid, Donkey-Kong, Boulder-Dash, and many other objects of fascination for users of eight-bit machines, back in the 1970s.

For many years I wondered how computers could think. This mastermind game is one of my first game projects. It can be useful if you are also interested in artificial intelligence in computers.

In fact computers can't think at all, They just decide on results of some probability calculations. Mastermind is a board game which is played with 2 players in different roles. Two sample applications are provided to show how to implement thinking on each side.

Points of Interest

Note that most of the functions are same and the decision is made on probability calculations. And another important point, computer never makes a mistake...

So if you want an easier opponent, you need to include procedures like makemistake(); !!

The code (Computer Player)

#include "stdafx.h"
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>

/*
MasterMind Computer Player, By Aytek Ustundag (holyone@tahribat.com)
*/

using namespace std;

int probabilitycount=0;
string probabilities[120];


inline bool hasduplicate(string s)
{
int k;
int j;
for (j=0;j<4;j++)
for (k=0;k<4;k++)
{
	if (k!=j)
	if (s[k]==s[j]) { return true;}
}
return false;
}



inline bool checkstring(string s)
{
if (s.length()!=4) return false;
if (s[0]== 0x30) return false;
if (hasduplicate(s)) return false;
return true;
}




int HowManyAreCorrect(string a,string b)
{
int t=0;
for(int i=0;i<4;i++)
{		
if (a[i]==b[i])	t++;
}
return t;
}





int HowManyAreMisplaced(string a, string b)
{
int l=0;
for(int i=0;i<4;i++)
{
	for(int j=0;j<4;j++)
		if((a[i]==b[j])&&(i!=j))
		{
		l++;
		}
}
	return l;
}




 string generatestringfromnumbers(int i,int j,int k,int l)
 {
 string result="";
 result+= char(0x30+i);
 result+= char(0x30+j);
 result+= char(0x30+k);
 result+= char(0x30+l);
 return result;
 }


 void eliminateprobability(int i)
 {
 int x;
 for (x=i;x<probabilitycount;x++)
 {
 probabilities[x]=probabilities[x+1];
 }
 probabilitycount=probabilitycount-1;
 }



int main()
{

srand(time(0));
cout<<endl;
cout<<"                     Wellcome to Mastermind - Computer Player\n";
cout<<"--------------------------------------------------------------------------------\n";
cout<<" hold a random 4 digit number with diffrent digits\n";
cout<<" I will tell you the number, just give me the information about \n";
cout<<" how many of the digits that i guessed right, and how many in wrong places \n";
cout<<" DONT TRY TO FOOL ME HUMAN!, BECAUSE I CAN FIND IT OUT!\n";
cout<<" Lets start the game if you are ready.\n\n";

short int correct,wrongplace,i,j,k,l;
string lastguess;

string Temp[120];

//Generating probability List
for (i=0;i<5;i++) 
for (j=0;j<5;j++) 
for (k=0;k<5;k++) 
for (l=0;l<5;l++) 
{
if (checkstring( generatestringfromnumbers(i,j,k,l) )==true)
{
probabilities[probabilitycount]= generatestringfromnumbers(i,j,k,l);
probabilitycount+=1;
}
}
//Done Generating probability List

int GuessCnt=0;
do {
lastguess=probabilities[rand()%probabilitycount];

if (probabilitycount==1)
cout<<endl<<" There is only one probability left. And it Has to be be Right!\n"<<endl;
else cout<<endl<<" There is "<<probabilitycount<<" probabilities.\n";
cout<<" My guess: "<<lastguess<<endl<<endl;
cout<<" Input number of correct digits and input number of misplaced digits:\n";
cout<<endl;
cout<<"How many are correct?\t:";
cin>>correct;
cout<<"How many are misplaced?\t:";
cin>>wrongplace;
GuessCnt++;
i=0;
do
{
if ((HowManyAreCorrect(probabilities[i],lastguess)!=correct) || (HowManyAreMisplaced(probabilities[i],lastguess)!=wrongplace))
eliminateprobability(i); else
i++;
} while ((i<probabilitycount) && (probabilitycount>=0));



//delete slashes to see the probabilities left at your each guess
//for (j=0;j<probabilitycount+1;j++) cout<<probabilities[j]<<endl; cout<<"probabilitycount:"<<probabilitycount<<endl;


} while (((correct!=4) || (wrongplace!=0) )&& (probabilitycount>0));

//do {cout<<"Guess again:\n"; cin>>b;} while(checkstring(b)==false);

if (probabilitycount<=0)
{ 
cout<<" You Can't Fool me human, The datas you have provided are invalid.\n";
cout<<" Dont Try it again... I can sense you cheating.\n";
return -1;
}
cout<<"\n I found it in "<<GuessCnt<<" Guesses Human."<<endl;
cout<<" See ya later..."<<endl;

return 0;
}


The code (Human Player)

#include "stdafx.h"
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>
/*
MasterMind Human Player, By Aytek Ustundag (holyone@tahribat.com)
*/
using namespace std;

const bool showhint=false; 
//This is a cheat code to test the program.
//If set to true, you can see the number that computer thinks of.

short int numbercount=0; // if set to 5 then 0,1,2,3,4 will be available for each digit.
//has to be any number from 1 to 9

int digitcount=0; //determines how many digits the numbers should have.

//The variables have 1 and 0 values for the while loop in the main functions.


inline bool hasduplicate(string s) //function that returns false if any duplicate numbers are found in a string
{
int k;
int j;
for (j=0;j<digitcount;j++)
for (k=0;k<digitcount;k++)
{
	if (k!=j)
	if (s[k]==s[j]) { return true;}
}
return false;
}

 

inline bool checkstring(string s) //Checks if...
{

//...The recieved string is 4 characters long ,
if (s.length()!=digitcount) { cout<<"Numeric Error: Your input is out of range\n";
return false;
}

//...The recieved string is not starting with 0,
if (s[0]== 48) {  cout<<"Numeric Error: Your input is out of range\nStarting with 0 is not allowed\n"; return false;}

//...The recieved string has duplicate characters,
if (hasduplicate(s))
{ cout<<"Error: Your number contains duplicate numbers\n" ;return false;}

//if any of those conditions is not present then the function returns true which means
//the recived string contains no errors.
return true;

}




int HowManyAreRight(string a,string b)
//Function that returns How many correct digits does our string have
{
	int t=0;
for(int i=0;i<digitcount;i++)
{
		
if (a[i]==b[i])	t++;
	
}
return t;
}



//Function that returns How many misplaced digits does our string have
int HowManyAreMisplaced(string a, string b)
{int l=0;
for(int i=0;i<digitcount;i++)
{
	for(int j=0;j<digitcount;j++)
		if((a[i]==b[j])&&(i!=j))
		{
		l++;
		}
}
return l;
}



//This function is to make computer chose a random number
//which applies to game rules (4 digit, not starting with 0,
// not having any numbers greater than numbercount constant in any digit)
string randomnumber(int digit)
{
string result;
int k,rnd;

do{	result="";
for (k=0;k<digit;k++)
{

if ( result.length()==0 )
rnd = rand() % numbercount +1; else rnd=rand() %numbercount;
result=result + char( 48 +rnd);
}
}
while (hasduplicate(result)==true);
return result;
}



//Main Function...
int main()
{
srand(time(0));
cout<<endl;
cout<<"                         Wellcome to Mastermind - Human Player\n";
cout<<"--------------------------------------------------------------------------------\n";
cout<<" I will chose a random number, Try to find if you can\n";
cout<<" I will tell you how many of the digits you have guessed right,\n";
cout<<" and how many of the digits you have guessed right, but in the wrong place.\n\n";


//while loop is to prevent variable input errors
while((numbercount<digitcount)|| (digitcount<=1)|| (digitcount>9) ||  (numbercount<=1) ||  (numbercount>9))
{
cout<<"How many digits do you want me to chose? :";
cin>>digitcount;
cout<<"How many numbers do you want me to chose for any digit of my number? :";
cin>>numbercount;

if (numbercount<digitcount) cout<<"\nNumber of digits should be equal or smaller than number of options for any digit Please Re-Input:\n";
if((digitcount>9)||(numbercount>9)) cout<<"Digitcount or Numbercount cannot be greater than 9"<<endl;
}

string a=randomnumber(digitcount);string b;

//set showhint constant to true to see the random number at startup
if (showhint) cout<<"Hint: The number is "<<a<<endl<<endl;

do {cout<<"Input Your Guess:"; cin>>b;} while(checkstring(b)==false);

int guesscnt=1;

while (b!=a)  //while guess is wrong
{
	cout<<"Correct:"<<HowManyAreRight(a,b) <<endl; //show number of correct digits
	cout<<"Misplaced:"<<HowManyAreMisplaced(a,b) <<endl<<endl;//show number of misplaced digits
	guesscnt++; do {cout<<"Guess Again:"; cin>>b;} while(checkstring(b)==false);
}
cout<<"\n You found it in "<<guesscnt<<" Guesses."<<endl;
//finally display how many times the user tried...
return 0;
}
 

Code by: Y. Aytek Üstündağ

Homepage: http://www.tahribat.com

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Aytek Ustundag
Engineer
Turkey Turkey
15+ years of “hard core” development experience
Worked with leading companies.
Early .NET user and developer
I often win “Mine’s older than yours”

Comments and Discussions

 
GeneralMy vote of 1 Pinmemberauge__28-Jun-09 22:16 
Generalsure wish you'd finish this PinmemberJim Crafton13-Oct-07 17:50 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140415.2 | Last Updated 22 Sep 2010
Article Copyright 2007 by Aytek Ustundag
Everything else Copyright © CodeProject, 1999-2014
Terms of Use
Layout: fixed | fluid