Hello!

I am writing a program that mimics the game Mastermind. However, I am having trouble getting past the first step. We are using letters as the "colors", a string containing "RGBYO". Each time it goes through trying to get the initial "secret code", it needs to get rid of whatever color it randomly picked so that it can not be used again. In other words, each "color" can only be used once. So if the program is generating a secret code to be guessed for this game, it can only come out with RGBY or GYBO, not something like GGYO or RGBB. I can not figure out how to remove the used color from the string. Below is my code:

#include <iostream>
#include <string>
#include <ctime>

void setSecretCode(char[]);
using namespace std;

int main()
{
    char code[4]= {0};
    setSecretCode(code);
    cout << code[0] << code[1] << code[2] << code[3];
    cout << endl;
    system ("pause");
    return 0;
}

void setSecretCode (char code[4])
{
    string colors = "RGBYO";
    int pos;

    srand(time(NULL));
    pos = rand() % 5; 
    code[0] = colors[pos]; 

    srand(time(NULL));
    pos = rand() % 4;
    code[1] = colors[pos];

    srand(time(NULL));
    pos = rand() % 3;
    code[2] = colors[pos];

    srand(time(NULL)); 
    pos = rand() % 2; 
    code[3] = colors[pos]; 

}

I tried colors = colors - colors[pos] as well as colors = colors - code[whateveritis], but the "code" is char and the "pos" is int, so it's telling me I can't convert within it (obviously). Any help would really be appreciated. Thank you!

Use erase: http://www.cplusplus.com/reference/string/string/erase/
string& erase ( size_t pos = 0, size_t n = npos );
"pos: Position within the string of the first character to be erased."
"n: Amount of characters to be removed."

void setSecretCode (char code[4])
{
    string colors = "RGBYO";
    int pos;

    srand(time(NULL));
    pos = rand() % 5; 
    code[0] = colors[pos]; 
    colors.erase(pos,1);

    srand(time(NULL));
    pos = rand() % 4;
    code[1] = colors[pos];
    colors.erase(pos,1);

    srand(time(NULL));
    pos = rand() % 3;
    code[2] = colors[pos];
    colors.erase(pos,1);

    srand(time(NULL)); 
    pos = rand() % 2; 
    code[3] = colors[pos]; 
}

1) Look up how and why to use srand(). You are using it wrong.
2) Using the technique you tried will work -- if you add one more step.
After using colors[pos]; you need to remove it from the list by moving all values after it down.

In other words, it your array starts as ABCDEF and randomly choose C, you need to modify the array into ABDEF before choosing the next value.

Edited 4 Years Ago by WaltP

a more compact example , with some modifications.

#include <iostream>
#include <string>
#include <ctime>

void setSecretCode(char*);
using namespace std;

int main()
{
    char code[5]= {0};
    setSecretCode(code);
    cout << string(code) << endl;
    cout << "press Enter to exit...";
    cin.get();

    return 0;
}

void setSecretCode (char* code)
{
    string colors = "RGBYO";
    int pos;

    srand(static_cast<unsigned int>(time(NULL)));

    for (int i = 0, mod = 5; i < 4; ++i, --mod)
    {
        pos = rand() % mod;
        code[i] = colors[pos];
        colors.erase(pos, 1);
    }

    return;
}

I also forgot to point out, as nullptr has fixed, you only need/want to call srand() once. Because you called srand back to back and over the same second the seed value would be the same which would cause you to get the same "random" number from rand() again and again over the same second.

$ man srand
etc...
The srand() function sets its argument as the seed for a new sequence of pseudo-random integers to be returned by rand(). These sequences are repeatable by calling srand()
with the same seed value.

Sample:

#include <iostream>
#include <cstdlib>
using namespace std;
int main(){
  srand(88);
  cout << "srand(88), rand() = " << rand() << endl;
  srand(88);
  cout << "srand(88), rand() = " << rand() << endl;
  cout << "           rand() = " << rand() << endl;
  srand(89);
  cout << "srand(89), rand() = " << rand() << endl;
  return 0;
}

Output:

$ ./a.out
srand(88), rand() = 38645617
srand(88), rand() = 38645617
           rand() = 708846855
srand(89), rand() = 1888747329
$

**@WaltP, ** I did what you suggested and it worked!

// Set Secret Code Function
void setSecretCode(char code[])
{
    // Declare Variables
    string colors = "RGBYO";
    int pos;
    // Randomly Grab
    srand(time(NULL));
    pos = rand() % 5;
    code[0] = colors[pos]; 
    // Call Remove Color Function
    removeColor(code, colors, pos);

    // Randomly Grab
    srand(time(NULL));
    pos = rand() % 4; 
    code[1] = colors[pos];
    // Call Remove Color Function
    removeColor(code, colors, pos);

    // Randomly Grab
    srand(time(NULL));
    pos = rand() % 3; 
    code[2] = colors[pos]; 
    // Call Remove Color Function
    removeColor(code, colors, pos);

    // Randomly Grab
    srand(time(NULL));
    pos = rand() % 2; 
    code[3] = colors[pos];
    // Call Remove Color Function
    removeColor(code, colors, pos);
}

// Remove Color Function
void removeColor(char code[], string & colors, int pos)
{
    // Declare Variables
    string temp;
    int j = 0;

    // Create New Color String
    while (j<colors.length())
    {
        if (j!=pos)
        {
            temp = temp + colors[j];
        }
        j++;
    }
    colors = temp;
}
This article has been dead for over six months. Start a new discussion instead.