Created
March 22, 2015 06:08
-
-
Save arsane/32ed54e0bf938edc683f to your computer and use it in GitHub Desktop.
mastermind.cpp in c++11
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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