Advertisement
puppet106

cmind.cc

Apr 6th, 2020
567
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.24 KB | None | 0 0
  1. // colormind - mastermind clone
  2. #include <unistd.h>
  3. #include <string.h>
  4. #include <iostream>
  5. #include <vector>
  6.  
  7. #define MAXCOLORS 8
  8. #define MINCOLORS 2
  9. #define STANDARDCOLORSNO 4
  10. #define MAXTRIES 16
  11. #define MINTRIES 2
  12. #define STANDARDTRIESNO 8
  13. #define MAXLINE 80
  14. #define VERSION 1.0
  15. #define WHITE 0
  16. #define BLACK 1
  17.  
  18. using namespace std;
  19.  
  20. // variables, classes
  21. class PEGS {
  22.  public:
  23.   int white;
  24.   int black;
  25.   PEGS(int i1, int i2) { white=i1; black=i2; };
  26.   PEGS() { };
  27. ~PEGS() { }; };
  28. vector<PEGS> pegshistory;
  29. struct Word { char formulaWord[MAXLINE]; };
  30. vector<Word> words;
  31. const char *COLORNAMES[]={ "red", "green", "blue", "black", "cyan", "magenta", "brown", "white" }, *PEGNAMES[]={ "white", "black" }, *PASSWORD="reveal";
  32. char *myname;
  33. bool reveal=false;
  34. int colorcode[2][MAXCOLORS], guessedcolors[MAXTRIES][MAXCOLORS], guessedsumcolors[2][MAXCOLORS], whitepegs, blackpegs, tries=0, maxtries=STANDARDTRIESNO, nocolors=STANDARDCOLORSNO;
  35.  
  36. // functions declaration
  37. void separatewords(char formula[]);
  38. int readline(char line[]);
  39. void showpegshistory();
  40. void revealcolorcode();
  41. void showusage();
  42.  
  43. int main(int argc, char *argv[])
  44. {
  45.   int i, i1, c, correctline, victory=0;
  46.   char guessline[MAXLINE];
  47.   myname=argv[0];
  48.   // randomize
  49.   srand(time(NULL));
  50.  
  51.   // parse command line options
  52.   while ((c = getopt(argc, argv, ":c:t:r")) != -1)
  53.    switch (c) {
  54.     case 'c':
  55.      if ((i=atoi(optarg))<=MAXCOLORS && i>=MINCOLORS)
  56.       nocolors=atoi(optarg);
  57.      else
  58.       showusage();
  59.     break;
  60.     case 't':
  61.      if ((i=atoi(optarg))<=MAXTRIES && i>=MINTRIES)
  62.       maxtries=atoi(optarg);
  63.      else
  64.       showusage();
  65.     break;
  66.     case 'r':
  67.      reveal=true;
  68.     break;
  69.     case '?':
  70.      showusage();
  71.     break;
  72.     default:
  73.      abort();
  74.   break; }
  75.  
  76.   // show information
  77.   cout << "ColorMind version " << VERSION << endl << "colors: <";
  78.   for (i=0;i<nocolors;i++)
  79.    cout << COLORNAMES[i] << " ";
  80.   cout << "\b> extra: <history>";
  81.   if (reveal)
  82.    cout << " <reveal>";
  83.   cout << endl;
  84.   // generate color code
  85.   for (i=0;i<nocolors;i++) // colorcode[2] contains generated code and sum of colors
  86.    colorcode[1][i]=0;
  87.   for (i=0;i<nocolors;i++) {
  88.    colorcode[0][i]=rand() % nocolors;
  89.   ++colorcode[1][colorcode[0][i]]; }
  90.    // loop
  91.    while (tries<maxtries) {
  92.     for (i=0;i<nocolors;i++) { // guessedcolors contains currently given code
  93.      guessedcolors[tries][i]=-1;
  94.      guessedsumcolors[0][i]=0; // guessedsumcolors[2] contains given pegs from guessed colors and sum of given guessed colors
  95.     guessedsumcolors[1][i]=0; }
  96.     correctline=0;
  97.     while (!correctline) {
  98.      correctline=1;
  99.      cout << "try number: " << tries+1 << endl;
  100.      while (!(i=readline(guessline)));
  101.      separatewords(guessline);
  102.      if (words.size()!=nocolors)
  103.       correctline=0;
  104.      // extra commands
  105.      if (!strcmp(guessline, "history"))
  106.       showpegshistory();
  107.      if (!strcmp(guessline, PASSWORD) && reveal)
  108.       revealcolorcode();
  109.      // parse words vector
  110.      for (i=0;i<nocolors;i++)
  111.       for (i1=0;i1<nocolors;i1++)
  112.        if (!strcmp(words[i].formulaWord, COLORNAMES[i1]))
  113.         guessedcolors[tries][i]=i1;
  114.      for (i=0;i<nocolors;i++)
  115.       ++guessedsumcolors[1][guessedcolors[tries][i]];
  116.      for (i=0;i<nocolors;i++)
  117.       if (guessedcolors[tries][i]==-1)
  118.     correctline=0; }
  119.     // award pegs
  120.     whitepegs=0; blackpegs=0;
  121.     // black pegs
  122.     for (i=0;i<nocolors;i++) {
  123.      if (guessedcolors[tries][i]==colorcode[0][i]) {
  124.       ++guessedsumcolors[0][guessedcolors[tries][i]];
  125.      ++blackpegs; } }
  126.      // white pegs
  127.      for (i=0;i<nocolors;i++) {
  128.       for (i1=0;i1<nocolors;i1++) {
  129.         if (guessedcolors[tries][i]==colorcode[0][i1] && guessedcolors[tries][i]!=colorcode[0][i] && guessedsumcolors[0][guessedcolors[tries][i]]<colorcode[1][guessedcolors[tries][i]] && guessedsumcolors[0][guessedcolors[tries][i]]<guessedsumcolors[1][guessedcolors[tries][i]]) {
  130.         ++guessedsumcolors[0][guessedcolors[tries][i]];
  131.     ++whitepegs; } } }
  132.     for (i=0;i<whitepegs;i++)
  133.      cout << PEGNAMES[WHITE] << " ";
  134.     for (i=0;i<blackpegs;i++)
  135.      cout << PEGNAMES[BLACK] << " ";
  136.     if (!whitepegs && !blackpegs)
  137.      cout << "zero pegs";
  138.     cout << endl;
  139.     // record peg history
  140.     PEGS tpegs(whitepegs, blackpegs);
  141.     pegshistory.push_back(tpegs);
  142.     ++tries;
  143.     if (blackpegs==nocolors) {
  144.      victory=1;
  145.    break; } }
  146.    // result
  147.    switch (victory) {
  148.     case 0:
  149.      cout << "color code: ";
  150.      for (i=0;i<nocolors;i++)
  151.       cout << COLORNAMES[colorcode[0][i]] << " ";
  152.      cout << endl;
  153.     break;
  154.     case 1:
  155.      cout << "Victory!" << endl;
  156.    break; }
  157.  
  158.  return 0;
  159. }
  160.  
  161. // separate words in string and store in vector inside structure
  162. void separatewords(char formula[])
  163. {
  164.   int i, n;
  165.   char tformula[MAXLINE];
  166.   Word tword;
  167.   vector<Word>::iterator p=words.begin();
  168.   while (p<words.end()) // because words.clear() only moves pointer, words are kept
  169.    words.erase(p++);
  170.   words.clear();
  171.    
  172.    for (i=0;i<strlen(formula);i++) {
  173.     n=0;
  174.     while (isspace(formula[i]))
  175.      ++i;
  176.     while (!isspace(formula[i]) && i<strlen(formula))
  177.      tformula[n++]=tolower(formula[i++]);
  178.     tformula[n]='\0';
  179.     strcpy(tword.formulaWord, tformula);
  180.    words.push_back(tword); }
  181. }
  182.  
  183. // read line
  184. int readline(char line[])
  185. {
  186.   int i=0;
  187.   char c;
  188.  
  189.    while ((c=getchar())!='\n')
  190.     line[i++]=c;
  191.    line[i]='\0';
  192.    
  193.  return strlen(line);
  194. }
  195.  
  196. // show pegs history
  197. void showpegshistory()
  198. {
  199.   int i, i1, i2;
  200.  
  201.    for (i=0;i<tries;i++) {
  202.     cout << i+1 << ":";
  203.     for (i1=0;i1<nocolors;i1++)
  204.      cout << COLORNAMES[guessedcolors[i][i1]] << " ";
  205.     cout << "-> ";
  206.     for (i1=0;i1<pegshistory[i].white;i1++)
  207.      cout << PEGNAMES[WHITE][0] << " ";
  208.     for (i2=0;i2<pegshistory[i].black;i2++)
  209.      cout << PEGNAMES[BLACK][0] << " ";
  210.     if (!i1 && !i2)
  211.      cout << "zero";
  212.    cout << endl; }
  213. }
  214.        
  215. // reveal code
  216. void revealcolorcode()
  217. {
  218.   int i;
  219.  
  220.   cout << "color code: ";
  221.   for (i=0;i<nocolors;i++)
  222.    cout << COLORNAMES[colorcode[0][i]] << " ";
  223.   cout << endl;
  224. }
  225.  
  226. // show usage
  227. void showusage()
  228. {
  229.   cout << myname << " [-c <colors&rows, 2..8>] [-t <tries 2..16>] [-r <reveal code>]" << endl;
  230.    
  231.  exit(EXIT_FAILURE);  
  232. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement