The Bash logo

Learn Bash by writing a number guessing game

0

Whenever I try to learn a new language, whether it’s a new shell scripting language or a new programming language to write larger programs, I focus on a few things: defining variables, writing statements, and evaluating expressions. Once I understand how to do those concepts, I can usually figure out the rest on my own. Most programming languages share some similarities, so learning the rest is usually a matter of working out the details.

I like to write a few “test” or “scratch” programs to practice a new programming language. One sample program I use frequently as an example is the classic “guess the number” program, where the computer picks a number in a range and prompts me to guess the secret number. This exercises how to assign values, how to write statements, and how to evaluate and compare values.

If you’d like to learn how to write shell scripts in Bash, you can use the “guess the number” program to practice Bash scripting.

A brief introduction to Bash

GNU Bash is the standard shell for most Linux system. Its name comes from the original Unix shell, which was just named sh. Later, Unix added support for other shells, including ksh for the Korn Shell, and bsh for the Bourne Shell. Bash is actually short for the “Bourne Again Shell,” a play on the original “Bourne Shell” name on older “Big Unix” systems.

Bash supports all the features of bsh but adds several other useful features. Its backwards compatibility with classic Unix shells makes it a popular choice on many Linux systems.

Guess the number in Bash

To write a “guess the number” script in Bash, we need to do a few things:

  1. Pick a random number from 1 to 100, and save it to a variable (secret)
  2. Enter a loop where the user enters their guess, and the script says if the guess is too high or too low
  3. Exit the loop when the user guesses the secret number

To select a random value, you can use the $RANDOM internal variable. The name of the variable is actually RANDOM and you can reference the value of the variable with the dollar sign in front: $RANDOM will always generate a random number, usually a large number.

You can use the “modulo” arithmetic operator (%) to divide the random number by another number and get the remainder. For example, 21 % 10 is 1, because 21 divided by 10 is 2, with 1 left over. But 20 % 10 is 0, because 10 goes into 20 exactly twice, with nothing left over. That means $RANDOM % 100 will give values between zero and 99. To make the secret number between 1 and 100, use $RANDOM % 100 + 1.

Bash provides arithmetic expansion using the $(( )) notation, so use this to calculate a random number from 1 to 100 and save it in a new variable called secret:

secret=$(( $RANDOM % 100 + 1 ))

Next, set a variable to store the user’s guess. We can initialize it to zero with:

guess=0

To start a loop that will continue only if the user’s guess is not equal to the secret number, use:

while [ "0$guess" -ne $secret ] ; do
...
done

In this example, I’ve used "0$guess to prepend a zero in front of the user’s guess, in case the user types a non-digit value like m. The -ne comparison test will only work with numbers, so 0m -ne 50 will test what we want: that the number value of 0 is not equal to 50, if the secret number was 50.

Get values from the user with the read statement:

read guess

You can test if one number is less than another using the -lt comparison, and greater than using the -gt test. You can use an if block in Bash to do each test, but a one-line shortcut uses && to basically say “if this test on the left is true then do this task on the right. For example, you could add two tests to print if the user’s guess was too low or too high:

[ "0$guess" -lt $secret ] && echo "Too low"
[ "0$guess" -gt $secret ] && echo "Too high"

Putting it all together

Let’s combine what we’ve learned about Bash scripting in this file, called guess:

#!/bin/bash

secret=$(( $RANDOM % 100 + 1 ))

guess=0
echo "Guess a number between 1 and 100"

while [ "0$guess" -ne $secret ] ; do
    read guess
    [ "0$guess" -lt $secret ] && echo "Too low"
    [ "0$guess" -gt $secret ] && echo "Too high"
done

echo "That's right!"

I’ve added an echo statement at the top to tell the user what the script will do, and another echo statement at the end to let the user know when they’ve guessed the number.

Make this script executable with the chmod command:

$ chmod +x guess

And now you can run your script whenever you want to play the “guess the number” game:

$ ./guess
Guess a number between 1 and 100
50
Too high
25
Too low
33
Too high
30
Too high
28
Too high
27
That's right!

Every time you run the script, the $RANDOM internal variable gives a new number, so you’ll always have a random secret number between 1 and 100:

$ ./guess
Guess a number between 1 and 100
50
Too low
75
Too low
88
Too high
80
Too low
84
That's right!

Learning is fun

This “guess the number” game is a great introductory program when learning a new programming language because it exercises several common programming concepts in a pretty straightforward way. By implementing this simple game in different programming languages, you can demonstrate some core concepts and compare details in each language.