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
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
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.
#!/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
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)