Mastermind

Hi guys.
I'm trying to write a code for the Mastermind board game, and I've hit a snag. I've got close, but the problem is when there are more than 1 of a colour of peg, either in the generated code or in the user input. For example:
for a generated code of b p y g, and a user input of r p b b, the correct output would be 1 pegs in the right place, and 1 in the wrong place, but the code outputs 1 peg in the right place, 2 in the wrong place.
I can see why this is the output, but I cannot work out how to fix it. Any help would be greatly appreciated.
Here's my code, sorry it's quite long.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
  //Mastermind
#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <string>
using namespace std;

int main ()
{
int a, b, c, d, maxtries, tries=0, pegs, right, close;	//Define the integers
string colour1, colour2, colour3, colour4, peg1, peg2, peg3, peg4;	//Define the strings

srand (time(NULL));
a=rand() % 6;	//Determine first colour
{
if (a==0) {
	colour1="red";
}
else if (a==1) {
	colour1="blue";
}
else if (a==2) {
	colour1="yellow";
}
else if (a==3) {
	colour1="purple";
}
else if (a==4) {
	colour1="orange";
}
else if (a==5) {
	colour1="green";
}
}
b=rand() % 6;	//Determine second colour
{
if (b==0) {
	colour2="red";
}
else if (b==1) {
	colour2="blue";
}
else if (b==2) {
	colour2="yellow";
}
else if (b==3) {
	colour2="purple";
}
else if (b==4) {
	colour2="orange";
}
else if (b==5) {
	colour2="green";
}
}
c=rand() % 6;	//Determine third colour
{
if (c==0) {
	colour3="red";
}
else if (c==1) {
	colour3="blue";
}
else if (c==2) {
	colour3="yellow";
}
else if (c==3) {
	colour3="purple";
}
else if (c==4) {
	colour3="orange";
}
else if (c==5) {
	colour3="green";
}
}
d=rand() % 6;	//Determine fourth colour
{
if (d==0) {
	colour4="red";
}
else if (d==1) {
	colour4="blue";
}
else if (d==2) {
	colour4="yellow";
}
else if (d==3) {
	colour4="purple";
}
else if (d==4) {
	colour4="orange";
}
else if (d==5) {
	colour4="green";
}
}

cout << "You choice of colours is red, blue, yellow, purple, orange green.";
cout << "\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
while (tries<maxtries) {
	right=0;	//Reset correct colour in correct place
	close=0;	//Reset correct colour in wrong place
	
	cout << "\n\nPlease enter the colour of the first peg: ";
	cin >> peg1;
	cout << "\nPlease enter the colour of the second peg: ";
	cin >> peg2;
	cout << "\nPlease enter the colour of the third peg: ";
	cin >> peg3;
	cout << "\nPlease enter the colour of the fourth peg: ";
	cin >> peg4;
	tries++;
	{
	if (colour1==peg1) {
		right++;
	}
	if (colour2==peg2) {
		right++;
	}
	if (colour3==peg3) {
		right++;
	}
	if (colour4==peg4) {
		right++;
	}	//Determine the number of right colours in the right place
	}
	{
	if (peg1!=colour1) {
		if (peg1==colour2 || peg1==colour3 || peg1==colour4) {
			close++;
		}
	}
	if (peg2!=colour2) {
		if (peg2==colour1 || peg2==colour3 || peg2==colour4) {
			close++;
		}
	}
	if (peg3!=colour3) {
		if (peg3==colour1 || peg3==colour2 || peg3==colour4) {
			close++;
		}
	}
	if (peg4!=colour4) {
		if (peg4==colour1 || peg4==colour2 || peg4==colour3) {
			close++;
		}
	}
	}	//Determine the number of right colours in the wrong place
	
	if ((peg1==colour1) && (peg2==colour2) && (peg3==colour3) && (peg4==colour4)) {
		cout << "\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
		cout << "\n\nCongratulations! You broke the code in " << tries << " tries.";	//Output the number of guesses made
		cout << "\n\nThe code was " << colour1 << ", " << colour2 << ", " << colour3 << ", " << colour4 << ".";	//Output the correct code
		return 0;
	}	//Determine whether the code is the correct one
	cout << "\n\nYou had " << right << " of the right colours in the right place.";		//Output the number of correct pegs in the right place
	cout << "\nYou had " << close << " of the right colours in the wrong place.";		//Output the number of correct pegs in the wrong place
}
}
This sounded fun, so I did it myself!

Do you know how to use loops and strings? If so I can help you with some ideas! If you don't, I recommend reading about them before moving on, it will make your code MUCH easier to work with :D

Also have you learned anything about functions yet? Your code could also benefit a ton from functions!
I know nothing about functions. I believe I understand loops and strings, at least to some extent. I've seen a few codes for Mastermind, and they all seemed a lot more streamlined than mine, I just had no idea what the majority of the stuff meant.
@spacehippo

I compressed your code a bit, to get rid of a lot of repetitions, such as in when the computer chooses colors. The program works now. If you have questions on what I did, please ask.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// Master Mind.cpp : main project file.

#include <iostream>
#include <stdlib.h>
#include <ctime>
#include <string>

using namespace std;

int main ()
{
 int a, tries=0, right, close;	//Define the integers
 string peg[4];	// Using array for pegs

 srand((unsigned) time(0));
 string Colors[6] = {"red","blue","yellow","purple","orange","green"}; // The 6 colors
 string Code[4];
 a=rand() % 6;	//Determine first colour
 Code[0]=Colors[a];

 a=rand() % 6;	//Determine second colour
 Code[1]=Colors[a];

 a=rand() % 6;	//Determine third colour
 Code[2]=Colors[a];

 a=rand() % 6;	//Determine fourth colour
 Code[3]=Colors[a];
// Placed all 4 computer color picks into Code array

 while (tries<10)
 {
	cout << endl << "Your choice of colours is red, blue, yellow, purple, orange green.";
	cout << endl << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
	cout << "\n\nThe code was " << Code[0] << ", " << Code[1] << ", " << Code[2] << ", " << Code[3] << ".";	//Output correct code to check response accuracy
// Remove the above line when you're satisfied it works.
	right=0;	//Reset correct colour in correct place
	close=0;	//Reset correct colour in wrong place

	cout << "\n\nPlease enter the colour of the first peg: ";
	cin >> peg[0];
	cout << "\nPlease enter the colour of the second peg: ";
	cin >> peg[1];
	cout << "\nPlease enter the colour of the third peg: ";
	cin >> peg[2];
	cout << "\nPlease enter the colour of the fourth peg: ";
	cin >> peg[3];
	tries++;

	//Determine the number of right colours in the right place
	for(int x=0;x<4;x++)
	{
	 if (Code[x]==peg[x])
	 {
		right++;
		peg[x] = "X"; // Remove peg color so it's not looked at again
	 } 
	}

	//Determine the number of right colours in the wrong place
	for(int x=0;x<4;x++)
	{
	 for( int y=0;y<4;y++)
	 {
		if(Code[x]==peg[y])
		{
		 close++;
		 peg[y] = "X"; // Remove peg color so it's only picked once
		}
	 }
	}

	if (right == 4) // If right is 4, all guesses were correct
	{
	 cout << "\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
	 cout << "\n\nCongratulations! You broke the code in " << tries << " tries.";	//Output the number of guesses made
	 cout << "\n\nThe code was " << Code[0] << ", " << Code[1] << ", " << Code[2] << ", " << Code[3] << ".";	//Output the correct code
	 return 0;
	}	//Determine whether the code is the correct one
	cout << "\n\nYou had " << right << " of the right colours in the right place.";		//Output the number of correct pegs in the right place
	cout << "\nYou had " << close << " of the right colours in the wrong place.";		//Output the number of correct pegs in the wrong place
 }
}

Last edited on
Hey we could have a fun mastermind creation party!

Here's mine!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#include <iostream>
#include <string>
#include <cstdlib>
#include <time.h>

using namespace std;

//Repeat a character a number of times, for decoration
void rept(char c, int repnum){
    for (int a = 0; a < repnum; a++){
        cout.put(c);
    }
}
//Generate a new random code. Level = number of unique characters (eg. 3=abc)
string genrand(int level){
    string ret;
    for (int a = 0; a < level; a++){
        ret += ('a'+(rand()%level));
    }
    return ret;
}

//Return a string indicating results of a guess
//rcrp = right character right place (default !)
//rcwp = right character wrong place (default ?)
string check(const string& user, const string& key, char rcrp = '!', char rcwp = '?'){
    //If the guess string is the wrong size, somebody is doing something wrong
    if (user.size()!=key.size()){
        return "FAILURE";
    }
    string ret;
    string tmp=user;
    string tmp2=key;
    //Run through the key backwards, check for equality based on that index,
    //if the code's character matches the user's character, add a rcrp and
    //remove both characters so we don't duplicate a check.
    for (int a = key.size()-1; a >= 0; a--){
        if (user[a]==key[a]){
            ret+=rcrp;
            tmp.erase(tmp.begin()+a);
            tmp2.erase(tmp2.begin()+a);
        }
    }
    //Same as previous, only this time for every character of the key, run through
    //the entire user's input
    for (int a = 0; a < tmp2.size(); a++){
        for (int b = 0; b < tmp.size(); b++){
              if (tmp[b]==tmp2[a]){
                    ret+=rcwp;
                    tmp.erase(tmp.begin()+b);
                    tmp2.erase(tmp2.begin()+a);
                    a--; //This is necessary because we're deleting chars at a
                    break;
              }
        }
    }
    return ret;
}
//Make a box around a string, make stuff look pretty :D
void outtitle(string title, char decorate, int borderwidth, int borderheight){

    for (int a=0;a<borderheight;a++){
        rept(decorate,title.size()+borderwidth*2);
        cout << '\n';
    }

    rept(decorate,borderwidth);
    cout << title;
    rept(decorate,borderwidth);
    cout << '\n';

    for (int a=0;a<borderheight;a++){
        rept(decorate,title.size()+borderwidth*2);
        cout << '\n';
    }
}

int main(){
    //So we generate different keys with genrand(blah)
    srand(time(0));

    bool quit = false;
    while(!quit){

        string winstr="HOLY COW YOU WINNNNNNN!!!";

        outtitle(" Welcome To Mastermind ",32+rand()%32,28,2);

        int level=5; //number of colors
        int rows=12; //number of guesses allowed

        string code = genrand(level);
        string input;

        cout << "\n\n";

        outtitle("Gameplay Specifics",'-',4,1);

        cout <<  "\n\nGuess by inputting a string " << level << " characters long.";
        cout <<  "\n(example " << genrand(level) << ")";
        cout <<  "\n\nAvailable characters : ";

        //output all available characters for guessing
        for (int b = 0; b < level; b++){
            cout << " [" << char('a'+b) << "]";
        }

        cout << "\n\nX = right letter right spot\n- = right letter wrong spot";


        cout << "\n\n";

        //loop through user guesses
        for (int a = 0; a < rows && input!=code; a++){

            cout << "\n";

            getline(cin,input);

            //don't allow incorrect input VERY remote chance FAILURE could be the key
            //but the likelyhood is astronomical
            if (input.size() != level || input == "FAILURE"){
                a--;
                cout << "\t\tTry : miss";
            }
            else{
                cout << check(input,code,'X','-') << "\t\tTry : " << a << "/" << rows;

            }
        }

        cout << "\n\n";

        if (input==code){
                outtitle("  You WWWWIIIIINNNNNNNNN!!!  ",'%',10,2);
        }
        else{
            outtitle("Sorry, the code was " + code,'-',10,2);
        }

        cout << "\nPush Enter To Play Again!";
        cin.get();
        cin.clear();
    }

}
Last edited on
Topic archived. No new replies allowed.