Can't pass Number Guessing Game tests

Hi, I can’t get these two Number Guessing Game tests to pass. Everything looks OK to me with my output. Can you help please?

If that username has been used before, it should print Welcome back, <username>! You have played <games_played> games, and your best game took <best_game> guesses. , with <username> being a users name from the database, <games_played> being the total number of games that user has played, and <best_game> being the fewest number of guesses it took that user to win the game

and

When the secret number is guessed, your script should print You guessed it in <number_of_guesses> tries. The secret number was <secret_number>. Nice job! and finish running

I’d upload the files but don’t see a way to do it.

You can just copy the code here.

Have you reviewed other posts about this topic? The most common mistake is miscounting the guesses and not recording all the games in the table so that you can pick the best one each time.

Thanks. As far as I can tell, I am counting the guesses correctly and recording the games. Here is the code:

#!/bin/bash
#pg_dump -cC --inserts -U freecodecamp number_guess > number_guess.sql 
#psql -U postgres < number_guess.sql

PSQL="psql --username=freecodecamp --dbname=number_guess_game -t --no-align -c"

echo "Enter your username:"
read USERNAME

SECRET_NUMBER=SECRET_NUMBER=$((1+ RANDOM % 1001 ))
NUMBER_OF_GUESSES=0
#echo $SECRET_NUMBER

USER_ID=$($PSQL "SELECT user_id FROM users WHERE name='$USERNAME';")

if [[ -z $USER_ID ]]
then
	echo "Welcome, $USERNAME! It looks like this is your first time here."
	INSERT_RESULT=$($PSQL "INSERT INTO users(name) VALUES('$USERNAME');")
    USER_ID=$($PSQL "SELECT user_id FROM users WHERE name='$USERNAME';")

else
	NUM_GAMES=$($PSQL "SELECT COUNT(*) from games WHERE user_id=$USER_ID;")
	BEST_GAME=$($PSQL "SELECT MIN(number_of_guesses) from games WHERE user_id=$USER_ID;")
	echo "Welcome back, $USERNAME! You have played $NUM_GAMES games, and your best game took $BEST_GAME guesses."
fi

function MAKE_A_GUESS() {
	NUMBER_OF_GUESSES=$((NUMBER_OF_GUESSES+1))
	echo "Guess the secret number between 1 and 1000:"
	read USER_GUESS
	if [[ ! $USER_GUESS  =~ ^[0-9]+$ ]]
	  then
		echo "That is not an integer, guess again:"
		MAKE_A_GUESS
	fi
	TEST_GUESS
}
function TEST_GUESS(){
 if [[ $USER_GUESS  -eq $SECRET_NUMBER ]]
    then
      echo "You guessed it in $NUMBER_OF_GUESSES tries. The secret number was $SECRET_NUMBER. Nice job!"
      INSERT_RESULT=$($PSQL "INSERT INTO games(user_id,number_of_guesses,secret_number) VALUES($USER_ID,$NUMBER_OF_GUESSES,$SECRET_NUMBER);")
    elif [[ "$USER_GUESS" -gt "$SECRET_NUMBER" ]]  #lower
    then
      echo "It's lower than that, guess again:"
      MAKE_A_GUESS
    elif [[ "$USER_GUESS" -lt "$SECRET_NUMBER" ]]  #higher
    then
      echo "It's higher than that, guess again:"
      MAKE_A_GUESS
    fi
}

MAKE_A_GUESS

shouldn’t this be mod 1000 + 1? (not mod 1001 + 1 as that will give numbers up to 1001?)
Ref: Bash: Random numbers for fun and profit – /techblog.

i think you should insert before you echo because the test expects you to exit immediately after displaying the message.

I think you are right about mod 1000 + 1 and I changed it. I moved the INSERT before the echo and still have problems with the two tasks asking me to print to the screen. Here is screen output,

It’s lower than that, guess again:
Guess the secret number between 1 and 1000:
417
It’s lower than that, guess again:
Guess the secret number between 1 and 1000:
416
You guessed it in 11 tries. The secret number was 416. Nice job!

Okay trying to look for other things that may be a problem:

You do not need to store the secret number in the table. (But I don’t know if the test cares or not)

For this call to test guess function, can you make sure it runs in an else block? I am concerned that if the player types a bad guess then the recursive call to make a guess function will eventually end up back here in the call stack and run this test gues function even after the game is done technically (the correct guess is given).

Well either that or make sure to explicitly exit after echoing the last message.

I had the same problem with the second test You guessed it in <number_of_guesses> tries. The secret number was <secret_number>. Nice job!. I made a post about getting it to pass here. It seems that this test wasn’t working properly for me and was checking for the wrong value. If you managed to get it to pass properly please let me know how you did it.

Good catch. The TEST_GUESS does need to be in the else block and was definitely a problem. But I still can’t pass the test for when the correct number is guessed. I tried incrementing the number even when a character (bad guess) was entered and it didn’t make a difference. Wish I could figure this one out.

The “Welcome back” message test passes most of the time. It isn’t consistent though. I added echo -e "\n… " and it passes more consistently.

I saw in other forum posts that adding the secret number to the database helped others pass the tests but it made no difference for me.

can you repost the code now? (including all the changes to the number of guesses and the recursive block/exit after success message change)

#!/bin/bash

PSQL="psql --username=freecodecamp --dbname=number_guess_game -t --no-align -c"

echo "Enter your username:"
read USERNAME
#echo $USERNAME

SECRET_NUMBER=SECRET_NUMBER=$((1+ RANDOM % 1000 ))
NUMBER_OF_GUESSES=0
#echo $SECRET_NUMBER

USER_ID=$($PSQL "SELECT user_id FROM users WHERE name='$USERNAME';")

if [[ -z $USER_ID ]]
then
	echo -e "\nWelcome, $USERNAME! It looks like this is your first time here.\n"
	INSERT_RESULT=$($PSQL "INSERT INTO users(name) VALUES('$USERNAME');")
  USER_ID=$($PSQL "SELECT user_id FROM users WHERE name='$USERNAME';")
	#Insert user into database
else
	NUM_GAMES=$($PSQL "SELECT COUNT(*) from games WHERE user_id=$USER_ID;")
	BEST_GAME=$($PSQL "SELECT MIN(number_of_guesses) from games WHERE user_id=$USER_ID;")
	echo -e "\nWelcome back, $USERNAME! You have played $NUM_GAMES games, and your best game took $BEST_GAME guesses.\n"
fi

function MAKE_A_GUESS() {
echo "Guess the secret number between 1 and 1000:"
read USER_GUESS
if [[ ! $USER_GUESS  =~ ^[0-9]+$ ]]
  then
    echo "That is not an integer, guess again:"
      #NUMBER_OF_GUESSES=$((NUMBER_OF_GUESSES+1))
    MAKE_A_GUESS
else
  NUMBER_OF_GUESSES=$((NUMBER_OF_GUESSES+1))
  TEST_GUESS
fi
}
function TEST_GUESS(){
 if [[ $USER_GUESS  -eq $SECRET_NUMBER ]]
    then
      INSERT_RESULT=$($PSQL "INSERT INTO games(user_id,number_of_guesses,secret_number) VALUES($USER_ID,$NUMBER_OF_GUESSES,$SECRET_NUMBER);")
      echo -e "\nYou guessed it in $NUMBER_OF_GUESSES tries. The secret number was $SECRET_NUMBER. Nice job!\n"
      exit 0
    elif [[ "$USER_GUESS" -gt "$SECRET_NUMBER" ]]  #lower
    then
      echo "It's lower than that, guess again:"
      MAKE_A_GUESS
    elif [[ "$USER_GUESS" -lt "$SECRET_NUMBER" ]]  #higher
    then
      echo "It's higher than that, guess again:"
      MAKE_A_GUESS
  fi
}

MAKE_A_GUESS

i would remove all the newlines here as echo will automatically add a newline anyway at the end of the printed line.
(you can test to confirm)

for this section, why do you need to select after you insert? (the USER_ID should surely be the same as the one typed by the new user already? and therefore no select is needed? It may not harm the game but it may slow down the game and there’s a time limit on the test)

Do you know how to combine these two into one statement? (again my concern is running time)

Also remove the newlines from this line and this following line too:

Then:

Immediately after reading the guess and before executing the next if statement, you need to increment the guess value.
(all guesses should increment the guess value)
Remove the incrementing code from the if/else blocks.

please make the changes and test and confirm the echos work without the newlines.
Let’s see if this helps.

Thanks for all the help. I made all the changes that you suggested but still cannot get the two tests to pass (Welcome message and Success message). I did away with the users table and created only a games table. Thanks for all your help.

#!/bin/bash

PSQL="psql --username=freecodecamp --dbname=number_guess_game -t --no-align -c"

echo "Enter your username:"
read USERNAME

SECRET_NUMBER=SECRET_NUMBER=$((1+ RANDOM % 1000 ))
NUMBER_OF_GUESSES=0
echo $SECRET_NUMBER

USER_COUNT=$($PSQL "SELECT count(name) FROM games WHERE name='$USERNAME';")

if [[ $USER_COUNT -eq 0 ]]
then
	echo -e "Welcome, $USERNAME! It looks like this is your first time here."
 #	INSERT_RESULT=$($PSQL "INSERT INTO users(name) VALUES('$USERNAME');")
else
  STATS=$($PSQL "SELECT COUNT(*),MIN(number_of_guesses) from games WHERE name='$USERNAME';")
  
   IFS="|"
   read -a STATS_ARRAY <<< $STATS
	 echo "Welcome back, $USERNAME! You have played ${STATS_ARRAY[0]} games, and your best game took ${STATS_ARRAY[1]} guesses."
fi

function MAKE_A_GUESS() {
echo "Guess the secret number between 1 and 1000:"
read USER_GUESS
NUMBER_OF_GUESSES=$((NUMBER_OF_GUESSES+1))
if [[ ! $USER_GUESS  =~ ^[0-9]+$ ]]
  then
    echo "That is not an integer, guess again:"
    MAKE_A_GUESS
else
  TEST_GUESS
fi
}
function TEST_GUESS(){
 if [[ $USER_GUESS  -eq $SECRET_NUMBER ]]
    then
      INSERT_RESULT=$($PSQL "INSERT INTO games(name,number_of_guesses,secret_number) VALUES('$USERNAME',$NUMBER_OF_GUESSES,$SECRET_NUMBER);")
      echo -e "You guessed it in $NUMBER_OF_GUESSES tries. The secret number was $SECRET_NUMBER. Nice job!"
      exit 0
    elif [[ "$USER_GUESS" -gt "$SECRET_NUMBER" ]]  #lower
    then
      echo "It's lower than that, guess again:"
      MAKE_A_GUESS
    elif [[ "$USER_GUESS" -lt "$SECRET_NUMBER" ]]  #higher
    then
      echo "It's higher than that, guess again:"
      MAKE_A_GUESS
  fi
}

MAKE_A_GUESS

I’m not sure what the 2 SECRET_NUMBER= are doing here?

Sorry I didn’t notice it before.

also can you check that your username allows a varchar(25) please? Just in case it is too narrowly defined for the test.

Still no luck. I fixed the code, changed username to varchar(25) and stopped inserting the secret number. I attached some screenshots. One with the contents of the table after the test ran.



okay 2 more ideas that I have left.
1- please run a couple of tests yourself (enter in some invalid guesses and some valid guesses) and record that and post it here. Maybe you have some stray output that I didn’t detect in the code. I think the way the test does it is it guesses incrementally and counts as it goes (and throwing in a bad guess once). So 1,2,3,4,5, etc. You could temporarily hardcode the random number to 9 or something just to capture the output.

2- this is a last resort but some people before had luck with it. Instead of relying on recursion, you could rewrite the code to run with loops instead. That way you have a single function that does everything.

Here are some screenshots, with the number hardcoded to 9. Apparently I have a problem with this line when it is a repeat user. You can see the “command not found” error in the screenshot.

INSERT_RESULT=$($PSQL "INSERT INTO games(name, number_of_guesses) VALUES('$USERNAME', $NUMBER_OF_GUESSES);")

It works fine if I replace the variable with the actual command (seen in another screenshot)

INSERT_RESULT=$(psql --username=freecodecamp --dbname=number_guess_game -t --no-align -c "INSERT INTO games(name, number_of_guesses) VALUES('$USERNAME', $NUMBER_OF_GUESSES);")

I don’t understand why it would error in that case.




I could refactor to a loop but I don’t have time to do that today.

did you make these in the sequence you posted? 4 screenshots? because the last one say that A had 1 game so far, when the screenshot is the 3rd.