Skip to content

Instantly share code, notes, and snippets.

@arsane
Created March 22, 2015 06:08
Show Gist options
  • Save arsane/32ed54e0bf938edc683f to your computer and use it in GitHub Desktop.
Save arsane/32ed54e0bf938edc683f to your computer and use it in GitHub Desktop.
mastermind.cpp in c++11
#include <algorithm>
#include <iostream>
#include <map>
using namespace std;
/**
* @brief repeat helper.
*/
template <typename F>
void repeat(unsigned n, F f)
{
while(n--) f();
}
/**
* @brief generate random sequence from specified list.
*
* @param xs a list of unique elements.
* @param n number of elements exptected.
*
* @return a random list.
*/
template <typename T>
vector<T> generate_random_nseq(const vector<T>& xs, unsigned n)
{
vector<T> vs;
srand(time(NULL));
repeat(n, [&vs, &xs](){
vs.push_back(xs[rand() % xs.size()]);
});
return vs;
}
/**
* helper structure for guess check.
*/
typedef struct {
unsigned pos_matched; /* number of position matched */
unsigned ele_matched; /* number of element matched */
} match_result;
/**
* @brief check matched result.
*
* @param rs real sequence value.
* @param gs guessed sequence value.
*
* @return
*/
template <typename T>
match_result check_guess(const vector<T>& rs, const vector<T>& gs)
{
match_result rst = {0, 0};
// count occurrences of same position
typename vector<T>::const_iterator i1, i2;
for ( i1 = rs.begin(), i2 = gs.begin();
i1 != rs.end() && i2 != gs.end();
++i1, ++i2) {
if ((*i1) == (*i2)) rst.pos_matched += 1;
}
// count occurrences of same values.
map<T, int> rs_m, gs_m;
for(auto const & x : rs) { ++rs_m[x];}
for(auto const & x : gs) { ++gs_m[x];}
for(auto im : rs_m) {
rst.ele_matched += min(im.second, gs_m[im.first]);
}
return rst;
}
const vector<char> COLORS = {'B', 'G', 'R'};
const unsigned NUM_ELEMENTS = 3;
int main()
{
vector<char> vcomb = generate_random_nseq (COLORS, NUM_ELEMENTS);
while(1)
{
// get guess
string guess;
cout << " - your guess --> ";
cin >> guess;
// string -> vector
vector<char> vguess(guess.begin(), guess.end());
if (vguess.size() != NUM_ELEMENTS) {
cout << "Guess must be " << NUM_ELEMENTS << " elements" << endl;
continue;
}
// todo: check if all elements valid.
// check (vector, vector)
match_result rst = check_guess(vcomb, vguess);
cout << "Positon matched: " << rst.pos_matched
<< ", Value matched: " << rst.ele_matched << endl;
if (rst.pos_matched == vcomb.size())
break;
}
cout << " - solved!" << endl;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment