Number Guessing Game TEST 8
I don’t understand why it does’t work
My code
#!/bin/bash
PSQL="psql --username=freecodecamp --dbname=number_guess -t --no-align -c"
echo "Enter your username:"
read USERNAME
# trim input
USERNAME=$(echo $USERNAME | tr -d '[:space:]')
# get user_id
USER_ID=$($PSQL "SELECT user_id FROM users WHERE name='$USERNAME'")
# if don't exist
if [[ -z $USER_ID ]]
then
echo "Welcome, $USERNAME! It looks like this is your first time here."
# add user
INSERT=$($PSQL "INSERT INTO users(name) VALUES('$USERNAME')")
# get new user_id
USER_ID=$($PSQL "SELECT user_id FROM users WHERE name='$USERNAME'")
else
#USERNAME=$($PSQL "SELECT name FROM users WHERE name='$USERNAME'")
GAMES_PLAYED=$($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")
GAMES_PLAYED=$(echo $GAMES_PLAYED | xargs)
BEST_GAME=$(echo $BEST_GAME | xargs)
if [[ -z "$BEST_GAME" ]]
then
BEST_GAME=0
fi
echo "Welcome back, $USERNAME! You have played $GAMES_PLAYED games, and your best game took $BEST_GAME guesses."
fi
RANDOM_NUMBER=$((1 + RANDOM % 1000))
TRIES=0
echo "Guess the secret number between 1 and 1000:"
# game loop
while true
do
read GUESS
if echo "$GUESS" | grep -qE '^[0-9]+$'
then
((TRIES++))
if [[ $GUESS -eq $RANDOM_NUMBER ]]
then
break
elif [[ $GUESS -lt $RANDOM_NUMBER ]]
then
echo "It's higher than that, guess again:"
else
echo "It's lower than that, guess again:"
fi
else
echo "That is not an integer, guess again:"
fi
done
INSERT_GAME_RESULT=$($PSQL "INSERT INTO games(number_of_guesses,user_id) VALUES($TRIES, $USER_ID)")
echo "You guessed it in $TRIES tries. The secret number was $RANDOM_NUMBER. Nice job!"
I’m also change user name to VARCHAR(25)(it was in someone’s solution to the problem)
Challenge Information:
Number Guessing Game - Build a Number Guessing Game
All my tests pass except “If that username has been used before, it should print Welcome back, ! You have played <games_played> games, and your best game took <best_game> guesses., with 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”
I tried to substitute ‘’-e \n", I checked the entries for extra spaces, all the texts are written exactly as given in the task. But it simply does not protect. All the data in the table is, in theory, correct
if echo "$GUESS" | grep -qE '^[0-9]+$'
then
((TRIES++))
if [[ $GUESS -eq $RANDOM_NUMBER ]]
then
break
elif [[ $GUESS -lt $RANDOM_NUMBER ]]
then
echo "It's higher than that, guess again:"
else
echo "It's lower than that, guess again:"
fi
else
echo "That is not an integer, guess again:"
((TRIES++))
fi
The suggestion to count every guess, even the non-integer ones, was the key.
My original code only incremented the TRIES counter after checking if the input was an integer:
# Old code snippet
if echo "$GUESS" | grep -qE '^[0-9]+$'
then
((TRIES++)) # Only incremented if it was a number
# ... comparison logic ...
else
echo "That is not an integer, guess again:"
fi
The problem was that non-integer inputs weren’t being counted towards the number_of_guesses stored in the database. This meant that when the script later fetched the BEST_GAME using MIN(number_of_guesses), it could get an incorrect value if the best game involved non-integer guesses.
I changed the loop to increment TRIES immediately after read GUESS, before checking if the input is an integer:
Corrected code snippet
read GUESS
((TRIES++)) # Increment on every input
if [[ ! $GUESS =~ ^[0-9]+$ ]] # Check if it's NOT an integer
then
echo "That is not an integer, guess again:"
else
# ... comparison logic ...
fi
This ensures that number_of_guesses saved in the database reflects the total number of attempts, leading to the correct BEST_GAME calculation and allowing the “Welcome back…” message test to pass.
Thanks again for pointing me in the right direction!