zaffaroby
Published © CC BY

Mastermind - Arduino guess secret code

Project to enable Arduino to play Mastermind and guess the secret code

IntermediateProtip1,203
Mastermind - Arduino guess secret code

Things used in this project

Hardware components

Arduino UNO
Arduino UNO
×1
Perma-Proto Breadboard Half Size
Perma-Proto Breadboard Half Size
×1
Buzzer, Piezo
Buzzer, Piezo
×1
Jumper wires (generic)
Jumper wires (generic)
×17
Resistor 10k ohm
Resistor 10k ohm
×3
Resistor 221 ohm
Resistor 221 ohm
×1
Alphanumeric LCD, 16 x 2
Alphanumeric LCD, 16 x 2
×1
Tactile Switch, Top Actuated
Tactile Switch, Top Actuated
×3

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Schematics

Circuit Diagram

Circuit Image

Code

Code

C/C++
// C++ code
//

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

const int BTN_1 = 8;
const int BTN_2 = 9;
const int BTN_3 = 10;
const int buzzerPin = 7;
int key = 0;   //which button is pressed?
int Li = 17;   //variable for lcd left row scrolling
int Lii = 1;   //variable for lcd left row scrolling
int Ri = -1;   //variable for lcd right row scrolling
int Rii = -1;  //variable for lcd right row scrolling
int numTones = 10;
int tones[] = { 261, 277, 294, 311, 330, 349, 370, 392, 415, 440 };
//            mid C  C#   D    D#   E    F    F#   G    G#   A

//arrays for custom chars. Black and white key code pegs
byte black_peg[8] = {
  B00000,
  B01110,
  B11111,
  B11111,
  B11111,
  B01110,
  B00000,
};
byte white_peg[8] = {
  B00000,
  B01110,
  B10001,
  B10001,
  B10001,
  B01110,
  B00000,
};

void setup() {
  pinMode(BTN_1, INPUT);         //key code black pegs
  pinMode(BTN_2, INPUT);         //key code white pegs
  pinMode(BTN_3, INPUT);         //enter to confirm key code or start the game
  pinMode(buzzerPin, OUTPUT);    //to manage the sound effects
  Serial.begin(9600);            // use monitor for troubleshooting
  lcd.createChar(1, black_peg);  //create custom char for black pegs
  lcd.createChar(2, white_peg);  //create custom char for white pegs
  lcd.begin(16, 2);              //inizialize the LCD


  for (int i = 0; i <= 16; i++) {
    lcd.setCursor(0, 0);
    lcd.print(Scroll_LCD_Right("MASTER MIND GAME"));
    delay(200);
  }
  for (int i = 0; i <= 36; i++) {
    lcd.setCursor(0, 1);
    lcd.print(Scroll_LCD_Left(" Arduino will guess your secret code."));
    if (i == 0) {
      delay(1100);
    } else {
      delay(300);
    }
  }
  Clear_Scroll_LCD_Left();
  for (int i = 0; i <= 31; i++) {
    lcd.setCursor(0, 1);
    lcd.print(Scroll_LCD_Left("Write it down and press key 3"));
    delay(300);
  }
}

void loop() {
  //wait until key 3 is pressed
  key = 0;
  while (key != 3) {
    key = read_buttons();
    lcd.clear();
    if (key == 1) { lcd.noDisplay(); }
  }
  lcd.display();
  int lc = 0;
  byte db_lc[252][4];
  byte game_board[10][4];
  byte game_board_k[10][2];
  byte code_played[4] = {};
  byte whites = 0;
  byte blacks = 0;
  for (int row = 0; row < 11; row++) {
    lcd.clear();
    int digit;
    // the first code played is "1234" type and it is generated by random function
    if (row == 0) {
      byte code_pattern[6] = { 1, 2, 3, 4, 5, 6 };
      randomSeed(analogRead(0));
      for (int i = 0; i < 4; i++) {
        digit = random(6 - i);
        code_played[i] = code_pattern[digit];
        for (int j = digit; j < 5; j++) {
          code_pattern[j] = code_pattern[j + 1];
        }
      }
      //set fixed 1234 as code_played for debugging
      //code_played[0]=1; code_played[1]=2; code_played[2]=3; code_played[3]=4;
    } else {
      int rndCode = random(lc);
      for (int k = 0; k < 4; ++k) { code_played[k] = db_lc[rndCode][k]; }
    }
    // print row number + code played - example:" 1) 2453 "
    lcd.print(row + 1);
    lcd.print(") ");
    for (int i = 0; i < 4; i++) {
      lcd.print(code_played[i]);
    }
    Clear_Scroll_LCD_Left();
    for (int i = 0; i <= 26; i++) {
      lcd.setCursor(0, 1);
      lcd.print(Scroll_LCD_Left("1)blacks 2)whites 3)enter"));
      if (i == 0 && row == 0) {
        delay(1100);
      } else {
        delay(300);
      }
    }
    if (lc == 1) {
      whites = 0;
      blacks = 4;
    } else {
      // input blacks and whites key code with buttons 1 and 2
      lcd.setCursor(8, 0);
      lcd.blink();
      whites = 0;
      blacks = 0;
      key = 0;
      while (key != 3) {
        key = read_buttons();
        if (key == 1) { blacks++; }
        if (key == 2) { whites++; }
        if (blacks + whites > 4) {
          lcd.setCursor(8, 0);
          lcd.print("    ");
          lcd.setCursor(8, 0);
          blacks = 0;
          whites = 0;
        } else {
          lcd.write(byte(key));
        }
      }
    }
    lcd.noBlink();
    //append code played to game board
    for (int k = 0; k < 4; ++k) { game_board[row][k] = code_played[k]; }
    //append blacks and whites to game_board_k
    game_board_k[row][0] = blacks;
    game_board_k[row][1] = whites;
    if (blacks == 4) {
      lcd.setCursor(12, 0);
      lcd.print(" ");
      lcd.setCursor(0, 1);
      lcd.print("SecrCode Guessed");
      for (int i = 0; i < numTones; i++) {
        tone(buzzerPin, tones[i], 100);
        delay(300);
      }
      for (int i = numTones; i > 0; i--) {
        tone(buzzerPin, tones[i], 100);
        delay(300);
      }
      noTone(buzzerPin);
      break;
    }
    lc = left_codes(game_board, game_board_k, row + 1, db_lc);
    if (lc == 0) {
      Clear_Scroll_LCD_Left();
      for (int i = 0; i <= 27; i++) {
        lcd.setCursor(0, 1);
        lcd.print(Scroll_LCD_Left("Almost a Key Code is wrong"));
        if (i == 0) {
          delay(1100);
        } else {
          delay(150);
        }
      }
      break;
    }
  }
}

//----------------------------------
int read_buttons() {
  while (true) {
    int key1 = digitalRead(BTN_1);
    int key2 = digitalRead(BTN_2);
    int key3 = digitalRead(BTN_3);
    if (key1 == HIGH) {
      tone(buzzerPin, 100, 100);
      delay(400);
      return (1);
    }
    if (key2 == HIGH) {
      tone(buzzerPin, 200, 100);
      delay(400);
      return (2);
    }
    if (key3 == HIGH) {
      tone(buzzerPin, 300, 100);
      delay(400);
      return (3);
    }
  }
}
//----------------------------------
String Scroll_LCD_Left(String StrDisplay) {
  String result;
  String StrProcess = "                " + StrDisplay + "                ";
  result = StrProcess.substring(Li, Lii);
  //Serial.print ("\n");
  //Serial.print (StrProcess);
  Li++;
  Lii++;
  if (Li > StrProcess.length()) {
    Li = 16;
    Lii = 0;
  }
  return result;
}
void Clear_Scroll_LCD_Left() {
  Li = 16;
  Lii = 0;
}
//----------------------------------
String Scroll_LCD_Right(String StrDisplay) {
  String result;
  String StrProcess = "                " + StrDisplay + "                ";
  if (Rii < 1) {
    Ri = StrProcess.length();
    Rii = Ri - 16;
  }
  result = StrProcess.substring(Rii, Ri);
  Ri--;
  Rii--;
  return result;
}
void Clear_Scroll_LCD_Right() {
  Ri = -1;
  Rii = -1;
}
//-------------------------------------
int left_codes(byte game_board[][4], byte game_borad_k[][2], byte len_board, byte db_lc[][4]) {
  int colors = 6;
  byte t[4] = { 0, 0, 0, 0 };
  byte board_row[4] = {};
  int j = 0;  // used for db_lc code append
  for (int a = 1; a < colors + 1; a++) {
    for (int b = 1; b < colors + 1; b++) {
      for (int c = 1; c < colors + 1; c++) {
        for (int d = 1; d < colors + 1; d++) {
          t[0] = a, t[1] = b, t[2] = c, t[3] = d;
          for (int i = 0; i < len_board; i++) {
            byte key_code[2] = {};
            // board_row = game_board[i]
            for (int k = 0; k < 4; k++) { board_row[k] = game_board[i][k]; }
            // key_code is found_keycode
            find_keycode(t, board_row, key_code);
            if (key_code[0] != game_borad_k[i][0] || key_code[1] != game_borad_k[i][1]) {
              break;
            } else {
              if (i == len_board - 1) {
                //db_lc.append(t)
                for (int k = 0; k < 4; k++) {
                  db_lc[j][k] = t[k];
                }
                j++;
                // memory room limits the left code to 252
                if (j == 252) {
                  int lc = j;
                  return (lc);
                }
              }
            }
          }
        }
      }
    }
  }
  int lc = j;
  return (lc);
}

//---------------------------------------------------------------
void find_keycode(byte code_a[4], byte code_b[4], byte key_code[2]) {
  byte whites = 0;
  byte blacks = 0;
  byte sa[4] = { 1, 1, 1, 1 };
  byte sb[4] = { 1, 1, 1, 1 };
  for (int i = 0; i < 4; i++) {
    if (code_a[i] == code_b[i]) {
      sa[i] = 0;
      sb[i] = 0;
      blacks += 1;
    }
  }
  for (int i = 0; i < 4; i++) {
    for (int j = 0; j < 4; j++) {
      if (sa[i] == 1 && sb[j] == 1 && code_a[i] == code_b[j]) {
        sa[i] = 0;
        sb[j] = 0;
        whites += 1;
      }
    }
  }
  key_code[0] = blacks;
  key_code[1] = whites;
}

Credits

zaffaroby

zaffaroby

1 project • 0 followers

Comments