/*
Guess the number game
Anon Engineering July 2021
A simple Hi/Lo game that uses no external hardware
What the F? https://www.baldengineer.com/arduino-f-macro.html
Reading serial input https://forum.arduino.cc/t/serial-input-basics-updated/382007/3
Bump 7/25
*/
const byte numOfGuesses = 6; // 7 is easy...
const byte numChars = 4; // only up to 100 + null
const byte LED = 13; // built-in LED pin on many boards
char rxChars[numChars]; // an array to store the received data
byte guessValue = 0; // holds entered value
byte guessNum = 0; // holds which guess we're at
byte secretNum = 0; // holds the random value
bool isGameWon = false; // has the game been won?
void askPlayAgain() {
Serial.println(F("Play again? (y or n)"));
Serial.println();
while (rxChars[0] == '\0') { // wait for user input
getInput();
}
//Serial.println(rxChars); // for test
if (rxChars[0] != 'y') { // if not yes...
//Serial.println();
Serial.println(F("See ya!"));
Serial.println(F("(Press reset to start over.)"));
Serial.println();
while (1); //loop forever here
}
}
void displayStart() {
//Serial.println();
Serial.println(F("Welcome!"));
Serial.print(F("I've chosen a number between 1 and 100. "));
//Serial.print(secretNum); // uncomment to cheat!
Serial.println();
Serial.print(F("Try to guess it in "));
Serial.print(numOfGuesses);
Serial.println(F(" tries or less!"));
}
void getInput() {
static byte index = 0;
char endMarker = '\n'; // newline character
char rxChar; // received char
while (Serial.available() > 0) {
rxChar = Serial.read(); // read one char
if (rxChar != endMarker) { // if not end marker add char to rx receive buffer
rxChars[index] = rxChar;
index++; // increment the char array index
if (index >= numChars) { // make sure we don't overflow the buffer
index = numChars - 1;
}
}
else { // if it is the end maker null terminate the c string
rxChars[index] = '\0'; // terminate the string
index = 0;
guessValue = atoi(rxChars); // atoi returns the integer the rx buffer chars represent
}
}
}
void showRemainGuesses() {
if (numOfGuesses - guessNum > 1) {
Serial.print(F("You have "));
Serial.print(numOfGuesses - guessNum);
Serial.println(F(" guesses left!"));
} else if (numOfGuesses - guessNum == 1) {
Serial.print(F("You have "));
Serial.print(numOfGuesses - guessNum);
Serial.println(F(" guess left!"));
} else { // no guesses left so print blank line
//Serial.println();
}
}
void youLose() {
Serial.println();
Serial.println(F("You lose!"));
Serial.print(F("The secret number was "));
Serial.print(secretNum);
Serial.println(F("."));
Serial.println();
isGameWon = false;
rxChars[0] = '\0'; // set rx buffer to null
}
void youWin() {
Serial.println();
Serial.println(F("You win!"));
Serial.println();
isGameWon = true;
rxChars[0] = '\0'; // set rx buffer to null
for (int i = 0; i < 6; i++) { // flash onboard LED for a win
digitalWrite(LED, HIGH);
delay(250);
digitalWrite(LED, LOW);
delay(250);
}
}
void setup() {
Serial.begin(9600);
pinMode(LED, OUTPUT);
// seed the random number generator with "noise"
randomSeed(analogRead(0));
}
void loop() {
secretNum = random(1, 101); // set a value between 1 and 100
guessNum = 0; // reset the guess number
isGameWon = false; // reset game won flag
displayStart(); // display welcome message
while (guessNum < numOfGuesses) {
getInput();
if (guessValue != 0) { // if a value was entered compare it to the secret number
guessNum++; // increment the number of guesses made
Serial.print(F("You guessed "));
Serial.println(guessValue);
for (int i = 0; i < 4; i++) { // just for dramatic effect...
Serial.print(F(". "));
delay(200);
}
if (guessValue < secretNum) {
Serial.println(F("Wrong, too low!"));
showRemainGuesses();
} else if (guessValue > secretNum) {
Serial.println(F("Wrong, too high!"));
showRemainGuesses();
} else if (guessValue == secretNum) { // You win
Serial.println();
youWin();
guessNum = numOfGuesses; // set guessNum to max so while loop drops out
}
guessValue = 0; // reset the guessValue until a new one is entered
}
} // end of while
if (!isGameWon) { // once the while loop terminates and if the game isn't won...
youLose();
}
// Now that win or lose has been displayed...
askPlayAgain();
}