Advertisement

AI strategies for a mastermind codebreaker

Started by August 11, 2003 09:13 AM
13 comments, last by es_quatro 21 years, 2 months ago
quote: Of course, this presumes that you obtain information with your first guess


I don''t quite understand what you are saying. Of course I obtain information with my first guess.

I did run my program for all possible inputs, and that''s how I came to the conclusion that it solves the problem in 6 moves or less. The average was something like 4.3, but I don''t remember (I lost the code, but I can do it again if you are interested).

I also found this link, which proves that you can do a better job than I did:
http://mathworld.wolfram.com/Mastermind.html
quote: Original post by alvaro
Of course I obtain information with my first guess.


Why of course ? While you might find out that you got nothing correct (which does give you some information I suppose), you might not actually find out that you have any colours correct or any positions correct. Does that still mean you can solve it in 6 turns (or less)?

BTW, thanks for taking to time to discuss this. I do appreciate it.

Timkin
Advertisement
quote: Original post by Timkin

Why of course ? While you might find out that you got nothing correct (which does give you some information I suppose), you might not actually find out that you have any colours correct or any positions correct. Does that still mean you can solve it in 6 turns (or less)?


As you said, if I find out that I got nothing correct, that gives me a lot of information. All my program tries to do is reduce the size of the set of configurations that are consistent with the results of the turns played so far. And, yes, 6 turns is the worst case and it''s not very common. If you follow the link to mathworld from my previous post, you''ll see that it can actually be done in 5 turns.

Do you have a C++ compiler? You could try the code I posted and play a little bit with it.

quote:
BTW, thanks for taking to time to discuss this. I do appreciate it.


You are most welcome.

Thanks for wasting an hour of my life, bastards.

#include <iostream>#include <vector>#include <algorithm>using namespace std;const int NUM_COLORS = 4;typedef int Color;struct Arrangement{	Arrangement(Color color0, Color color1, Color color2, Color color3)	{		colors[0] = color0;		colors[1] = color1;		colors[2] = color2;		colors[3] = color3;	}	Color colors[4];};typedef int Result;const int NUM_RESULTS = 25; // actually much lessResult MakeResult(int placed, int misplaced){	return placed*5 + misplaced;}Result MatchUp(const Arrangement &arr1, const Arrangement &arr2){	int placed = 0, misplaced = 0;	bool used1[4] = { false, false, false, false };	bool used2[4] = { false, false, false, false };	// first get placed	for(int i=0; i<4; i++)	{		if(arr1.colors[i] == arr2.colors[i])		{			used1[i] = true;			used2[i] = true;			placed++;		}	}	// now get misplaced	for(int i=0; i<4; i++)	{		if(used1[i]) 		{			continue;		}		for(int j=0; j<4; j++)		{			if(used2[j])			{				continue;			}			if(arr1.colors[i] == arr2.colors[j])			{				used1[i] = true;				used2[j] = true;				misplaced++;			}		}	}	return MakeResult(placed, misplaced);}int _tmain(int argc, _TCHAR* argv[]){	vector<Arrangement> possibilities;	for(int i0=0; i0<NUM_COLORS; i0++)		for(int i1=0; i1<NUM_COLORS; i1++)			for(int i2=0; i2<NUM_COLORS; i2++)				for(int i3=0; i3<NUM_COLORS; i3++)					possibilities.push_back(Arrangement(i0, i1, i2, i3));	vector<Arrangement> guessPossibilities = possibilities;	while(true)	{		int biggestGrouping = INT_MAX;		vector<Arrangement>::const_iterator best = guessPossibilities.end();		for(vector<Arrangement>::const_iterator ig = guessPossibilities.begin();			ig != guessPossibilities.end();			++ig)		{			vector<int> resultCounts(NUM_RESULTS, 0);			for(vector<Arrangement>::const_iterator ip = possibilities.begin();				ip != possibilities.end();				++ip)			{				resultCounts[MatchUp(*ig, *ip)]++;			}			int guessBiggestGrouping = *				max_element(resultCounts.begin(),							resultCounts.end());			if(guessBiggestGrouping < biggestGrouping)			{				biggestGrouping = guessBiggestGrouping;				best = ig;			}		}		cout << "I''m guessing "			 << best->colors[0] << ", "			 << best->colors[1] << ", "			 << best->colors[2] << ", "			 << best->colors[3] << ".\n"			 << "Number placed correctly? ";		int placed, misplaced;		cin >> placed;		cout << "Number placed incorrectly? ";		cin >> misplaced;		Result result = MakeResult(placed, misplaced);		for(vector<Arrangement>::iterator ip = possibilities.begin();			ip != possibilities.end();)		{			if(result != MatchUp(*best, *ip))			{				ip = possibilities.erase(ip);			}			else			{				++ip;			}			}		if(possibilities.size() == 0)		{			cout << "YUO HAVE MESED UP! NO CAEK!\n";			exit(1);		}		if(possibilities.size() == 1)		{			cout << "Ooh! I know! I know!\n"				 << possibilities.begin()->colors[0] << ", "				 << possibilities.begin()->colors[1] << ", "				 << possibilities.begin()->colors[2] << ", "				 << possibilities.begin()->colors[3] << "!\n";			exit(0);		}	}}


How appropriate. You fight like a cow.
quote: Original post by alvaro
Do you have a C++ compiler? You could try the code I posted and play a little bit with it.


I do, although I''m really flat out at the moment. I''ll see if I can find some time later this week to play around with it and get a better feeling for your solution. I''ll let you know if I have any more questions.

Thanks again,

Timkin

This topic is closed to new replies.

Advertisement