Here is v0.1 for Arduino, the original: Mastermind (board game) - Wikipedia
I use a-f instead of 6 colors and show numbers of full + matches and half - matches.
I also use 6 instead of 4 letters/colors.
The commented-out debug prints can help with understanding the code, feel free to add more.
Just playing this seriously will help strengthen and sharpen most minds.
Any questions?
// codebreak 0.1
char player[ 4 ]; // initials
char secret[ 7 ], guess[ 7 ]; // 6 letters a-f
byte fullMatches, halfMatches, guesses, secretBits, guessBits;
enum gameState { prompt, id, precode, code, entry, clues, interact, win };
byte gamestate;
unsigned long t;
unsigned long seed;
byte i, j; // gp indexes
char chr;
void setup()
{
Serial.begin( 115200 );
for ( i = 0; i < 67; i++) Serial.write( '\n' );
Serial.println( F( "code and guess are 6 letters, may be a to f" ));
Serial.println( F( "clues are 2 numbers, complete and half matches\n" ));
}
void loop()
{
switch ( gamestate )
{
case prompt :
Serial.println( F( "enter your initials" ));
for ( i = 0; i < 3; i++ )
{
player[ i ] = 0; // forced clear
}
i = guesses = 0; // counter in player
gamestate = id;
break;
case id :
if ( Serial.available())
{
chr = Serial.read();
// Serial.write( chr );
// Serial.write( 32 );
// Serial.println( chr, DEC );
if (( chr == ' ' || chr == '\n' || i > 2 ) && i != 0 )
{
Serial.println();
Serial.flush();
seed = micros() >> 2;
randomSeed( seed );
for ( i = 0; i < 6; i++ )
{
secret[ i ] = 0; // forced clear
}
i = 0; // counter in code
gamestate = code;
}
else if (( chr | 0x20 ) >= 'a' && (( chr | 0x20 ) <= 'z' )) // | 0x20 sets lowercase bit
{
player[ i++ ] = chr;
Serial.write( chr );
}
}
break;
case code :
secret[ i++ ] = 'a' + char( random( 0, 6 ));
if ( i > 5 )
{
for ( i = 0; i < 6; i++ )
{
guess[ i ] = 0; // forced clear
}
i = 0; // counter in entry
gamestate = entry;
// Serial.println( secret );
Serial.println(F( "\n****************" ));
}
break;
case entry :
if ( Serial.available())
{
chr = Serial.read();
if (( chr | 0x20 ) >= 'a' && ( chr | 0x20 ) <= 'z' ) // | 0x20 sets lowercase bit
{
guess[ i++ ] = chr;
Serial.write( chr );
}
else if ( chr == 8 && i > 0 ) // iirc 8 is backspace
{
i--;
}
if ( i > 5 )
{
Serial.print( " " );
Serial.flush();
gamestate = clues;
fullMatches = halfMatches = secretBits = guessBits = 0;
}
}
break;
case clues :
guesses++;
for ( i = 0; i < 6; i++ ) // full matches
{
if ( secret[ i ] == guess[ i ] )
{
secretBits += 1 << i;
guessBits += 1 << i;
fullMatches++;
// Serial.print( i, HEX );
// Serial.write( ' ' );
}
}
Serial.print( fullMatches );
Serial.print( "+" );
// Serial.write( ' ' );
// Serial.print( secretBits, HEX );
Serial.print( " | " );
for ( i = 0; i < 6; i++ ) // half matches, only set matchBits for matches secret chars
{
if ( !(( 1 << i ) & secretBits )) // make sure secret char is not already matched
{
for ( j = 0; j < 6; j++ )
{
if ( i != j )
{
if ( !((1 << j ) & guessBits )) // make sure guess char is not already matched
{
if ( secret[ i ] == guess[ j ] )
{
secretBits += 1 << i;
guessBits += 1 << j;
halfMatches++;
// Serial.print( j, HEX );
// Serial.write( ' ' );
break;
}
}
}
}
}
}
Serial.print( halfMatches );
Serial.println( "- " );
// Serial.println( guessBits, HEX );
if ( fullMatches == 6 )
{
Serial.println(F( "\n****************" ));
Serial.print(F( "Solved in " ));
Serial.print( guesses );
Serial.println(F( " guesses\n" ));
gamestate = prompt;
}
else
{
Serial.println(F( "----------------" ));
i = 0; // counter in entry
gamestate = entry;
}
break;
}
}