Mastermind: Difference between revisions

From Rosetta Code
Content added Content deleted
(→‎{{header|C++}}: added zkl)
(→‎{{header|zkl}}: added code)
Line 217: Line 217:


=={{header|zkl}}==
=={{header|zkl}}==
<lang zkl></lang>
<lang zkl>class MasterMind{
fcn init(code_len,guess_count){
var codeLen =code_len.max(4).min(10);
var guessCnt=guess_count.max(7).min(20);
var colors ="ABCDEFGHIJKLMNOPQRST"[0,codeLen];
}
fcn play{
guesses,win,blackWhite:=List(),False,Void;
code:=codeLen.pump(String,'wrap(_){ colors[(0).random(codeLen)] });
do(guessCnt){
str:=getInput();
win,blackWhite = checkInput(str,code);
guesses.append(T(str,blackWhite));
showBoard(guesses);
if(win) break;
}
if(win) println("--------------------------------\n",
"Very well done!\nYou found the code: ",code);
else println("--------------------------------\n",
"I am sorry, you discover the code!\nThe code was: ",code);
}
fcn [private] showBoard(guesses){
foreach n,gbw in ([1..].zip(guesses)){
guess,blackWhite := gbw;
println("%2d: %s :% s %s".fmt(n,
guess.split("").concat(" "), blackWhite.split("").concat(" "),
"- "*(codeLen - blackWhite.len())));
}
}
fcn [private] getInput{
while(True){
a:=ask("Enter your guess (" + colors + "): ").toUpper()[0,codeLen];
if(not (a-colors) and a.len()>=codeLen) return(a);
}
}
fcn [private] checkInput(guess,code){
// black: guess is correct in both color and position
// white: correct color, wrong position
matched,black := guess.split("").zipWith('==,code), matched.sum(0);
code = matched.zipWith('wrap(m,peg){ m and "-" or peg },code); // remove matched
white:=matched.zipWith('wrap(m,peg){ m and "x" or peg },guess)
.apply(code.holds).sum(0); // not right place in unmatched?
return(black==codeLen,"O"*black + "X"*white)
}
}(4,12).play();</lang>
{{out}}
{{out}}
<pre>
<pre>

Revision as of 04:37, 2 November 2016

Mastermind is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

Create a simple version of the board game: Mastermind.

It must be possible to:

  • choose the number of colors will be used in the game(2 - 20)
  • choose the color code length(4 - 10)
  • choose the maximum number of guesses the player has (7 - 20)
  • choose whether or not will be repeated colors in the code

The game should display all the player guesses and the results of that guess.

Display(just an idea.):

Feature Graphic Version Text Version
Player guess Colored circles Alphabet letters
Correct color & position Black circle X
Correct color White circle O
None Gray circle -

A text version example: 1: ADEF - XXO-
Translates to:
first guess;
the four colors(ADEF);
result: two correct colors and spot, one correct color/wrong spot one color is not in the code.

Happy coding!


C++

<lang cpp>

  1. include <iostream>
  2. include <algorithm>
  3. include <ctime>
  4. include <string>
  5. include <vector>

typedef std::vector<char> vecChar;

class master { public:

   master( size_t code_len, size_t clr_count, size_t guess_count, bool rpt ) {
       std::string color = "ABCDEFGHIJKLMNOPQRST";
       if( code_len < 4 ) code_len = 4; else if( code_len > 10 ) code_len = 10;
       if( !rpt && clr_count < code_len ) clr_count = code_len; 
       if( clr_count < 2 ) clr_count = 2; else if( clr_count > 20 ) clr_count = 20;
       if( guess_count < 7 ) guess_count = 7; else if( guess_count > 20 ) guess_count = 20;
       
       codeLen = code_len; colorsCnt = clr_count; guessCnt = guess_count; repeatClr = rpt;
       for( size_t s = 0; s < colorsCnt; s++ ) {
           colors.append( 1, color.at( s ) );
       }
   }
   void play() {
       bool win = false;
       combo = getCombo();
       while( guessCnt ) {
           showBoard();
           if( checkInput( getInput() ) ) {
               win = true;
               break;
           }
           guessCnt--;
       }
       if( win ) {
           std::cout << "\n\n--------------------------------\n" <<
               "Very well done!\nYou found the code: " << combo <<
               "\n--------------------------------\n\n";
       } else {
           std::cout << "\n\n--------------------------------\n" <<
               "I am sorry, you couldn't make it!\nThe code was: " << combo <<
               "\n--------------------------------\n\n";
       }
   }

private:

   void showBoard() {
       vecChar::iterator y;
       for( int x = 0; x < guesses.size(); x++ ) {
           std::cout << "\n--------------------------------\n";
           std::cout << x + 1 << ": ";
           for( y = guesses[x].begin(); y != guesses[x].end(); y++ ) {
               std::cout << *y << " ";
           }
           std::cout << " :  ";
           for( y = results[x].begin(); y != results[x].end(); y++ ) {
               std::cout << *y << " ";
           }
           int z = codeLen - results[x].size();
           if( z > 0 ) {
               for( int x = 0; x < z; x++ ) std::cout << "- ";
           }
       }
       std::cout << "\n\n";
   }
   std::string getInput() {
       std::string a;
       while( true ) {
           std::cout << "Enter your guess (" << colors << "): ";
           a = ""; std::cin >> a;
           std::transform( a.begin(), a.end(), a.begin(), ::toupper );
           if( a.length() > codeLen ) a.erase( codeLen );
           bool r = true;
           for( std::string::iterator x = a.begin(); x != a.end(); x++ ) {
               if( colors.find( *x ) == std::string.npos ) {
                   r = false;
                   break;
               }
           }
           if( r ) break;
       }
       return a;
   }
   bool checkInput( std::string a ) {
       vecChar g;
       for( std::string::iterator x = a.begin(); x != a.end(); x++ ) {
           g.push_back( *x );
       }
       guesses.push_back( g );
       
       int black = 0, white = 0;
       std::vector<bool> match( codeLen, false );
       for( int b = 0; b < codeLen; b++ ) {
           if( a.at( b ) == combo.at( b ) ) {
               match[b] = true;
               black++;
               continue;
           }
           for( int w = 0; w < codeLen; w++ ) {
               if( !match[b] && w != b && a.at( w ) == combo.at( b ) ) {
                   match[b] = true;
                   white++;
                   continue;
               }
           }
       }
       
       vecChar r;
       for( int b = 0; b < black; b++ ) r.push_back( 'X' );
       for( int w = 0; w < white; w++ ) r.push_back( 'O' );
       results.push_back( r );
       return ( black == codeLen );
   }
   std::string getCombo() {
       std::string c, clr = colors;
       int l, z;
       for( size_t s = 0; s < codeLen; s++ ) {
           z = rand() % ( int )clr.length();
           c.append( 1, clr[z] );
           if( !repeatClr ) clr.erase( z, 1 );
       }
       return c;
   }
   size_t codeLen, colorsCnt, guessCnt;
   bool repeatClr;
   std::vector<vecChar> guesses, results;
   std::string colors, combo;

};

int main( int argc, char* argv[] ) {

   srand( unsigned( time( 0 ) ) );
   master m( 4, 8, 12, false );
   m.play();
   return 0;

} </lang>

Output:
Enter your guess (ABCDEFGH): gbda

--------------------------------
1: A B C D  :  X O O -
--------------------------------
2: A A A E  :  O - - -
--------------------------------
3: E E E E  :  - - - -
--------------------------------
4: B B B C  :  X - - -
--------------------------------
5: D B A F  :  X O O -
--------------------------------
6: G B D A  :  X X X -

Enter your guess (ABCDEFGH): hbda


--------------------------------
Very well done!
You found the code: HBDA
--------------------------------

zkl

<lang zkl>class MasterMind{

  fcn init(code_len,guess_count){
     var codeLen =code_len.max(4).min(10);
     var guessCnt=guess_count.max(7).min(20);
     var colors  ="ABCDEFGHIJKLMNOPQRST"[0,codeLen];
  }
  fcn play{
     guesses,win,blackWhite:=List(),False,Void;
     code:=codeLen.pump(String,'wrap(_){ colors[(0).random(codeLen)] });
     do(guessCnt){

str:=getInput(); win,blackWhite = checkInput(str,code); guesses.append(T(str,blackWhite)); showBoard(guesses); if(win) break;

     }
     if(win) println("--------------------------------\n",

"Very well done!\nYou found the code: ",code);

      else println("--------------------------------\n",

"I am sorry, you discover the code!\nThe code was: ",code);

   }
   fcn [private] showBoard(guesses){
      foreach n,gbw in ([1..].zip(guesses)){
         guess,blackWhite := gbw;
         println("%2d: %s :% s %s".fmt(n,

guess.split("").concat(" "), blackWhite.split("").concat(" "), "- "*(codeLen - blackWhite.len())));

      }
   }
   fcn [private] getInput{
      while(True){

a:=ask("Enter your guess (" + colors + "): ").toUpper()[0,codeLen]; if(not (a-colors) and a.len()>=codeLen) return(a);

      }
   }
   fcn [private] checkInput(guess,code){

// black: guess is correct in both color and position

       // white: correct color, wrong position

matched,black := guess.split("").zipWith('==,code), matched.sum(0); code = matched.zipWith('wrap(m,peg){ m and "-" or peg },code); // remove matched white:=matched.zipWith('wrap(m,peg){ m and "x" or peg },guess) .apply(code.holds).sum(0); // not right place in unmatched? return(black==codeLen,"O"*black + "X"*white)

   }

}(4,12).play();</lang>

Output:
Enter your guess (ABCD): aabb
 1: A A B B : O X - - 
Enter your guess (ABCD): abcc
 1: A A B B : O X - - 
 2: A B C C : O X - - 
Enter your guess (ABCD): abdd
 1: A A B B : O X - - 
 2: A B C C : O X - - 
 3: A B D D : X X X - 
Enter your guess (ABCD): abcd
 1: A A B B : O X - - 
 2: A B C C : O X - - 
 3: A B D D : X X X - 
 4: A B C D : O X X - 
Enter your guess (ABCD): bacb
 1: A A B B : O X - - 
 2: A B C C : O X - - 
 3: A B D D : X X X - 
 4: A B C D : O X X - 
 5: B A C B : O O O - 
Enter your guess (ABCD): bdcb
 1: A A B B : O X - - 
 2: A B C C : O X - - 
 3: A B D D : X X X - 
 4: A B C D : O X X - 
 5: B A C B : O O O - 
 6: B D C B : O O O O 
--------------------------------
Very well done!
You found the code: BDCB