Skip to main content

Chapter2 Guessing Game

This chapter introduces you to a few common Rust concepts by showing you how to use them in real program.

We'll implement a classic beginner programming problem. Here's how it works:

  1. The program will generate a random number between 1 to 100
  2. It will prompt the player to enter a guess
  3. The program will indicate whether the guess is too low or too high
  4. If the guess is correct, the game will print a congratulatory message and exit

Steps to Build This Guessing Game

Setting Up a new Project

To set up a new project, first make a new project using Cargo:

cargo new guessing_game
cd guessing_game

The created folder contains a Cargo.toml file:

[package]
name = "guessing_game"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]

And the main.rs file:

fn main() {
println!("Hello, world!");
}

Processing a Guess

To start, we'll allow the player to input a guess:

use std::io;

fn main() {
println!("Guess the number!");
println!("Please input your guess.");

let mut guess = String::new();

io::stdin().read_line(&mut guess).expect("Failed to read line");

println!("You guessed: {}", guess);
}

Generating a Secret Number

Next, we need to generate a secret number that the user will try to guess.

  1. Add rand to dependency list in the Cargo.toml file:

    [dependencies]
    rand = "0.8.5"
  2. Trigger a dependency update: cargo build

  3. If you want to update dependency version, just execute: cargo update

Generating a Random Number

use std::io;

use rand::Rng;

fn main() {
println!("Guess the number!");

let secret_number = rand::thread_rng().gen_range(1..101);

println!("The secret number is: {}", secret_number);

println!("Please input your guess.");

let mut guess = String::new();

io::stdin()
.read_line(&mut guess)
.expect("Failed to read line");

println!("You guessed: {}", guess);
}

You can run the cargo doc --open command to generate docs for all the dependencies that the project relies on.

Comparing the Guess to the Secret Number

use std::io;

use rand::Rng;

fn main() {

// ...

let guess = guess.trim().parse::<u32>();
match guess {
Ok(guess) => match guess.cmp(&secret_number) {
std::cmp::Ordering::Less => println!("Too small!"),
std::cmp::Ordering::Equal => println!("You win!"),
std::cmp::Ordering::Greater => println!("Too big!"),
},
Err(e) => println!("{}", e),
}
}

Allowing Multiple Guesses with Looping


// ...

loop {
let mut guess = String::new();
println!("Please input your guess.");
io::stdin()
.read_line(&mut guess)
.expect("Failed to read line");
println!("You guessed: {}", guess);
let guess = guess.trim().parse::<u32>();
match guess {
Ok(guess) => match guess.cmp(&secret_number) {
std::cmp::Ordering::Less => println!("Too small!"),
std::cmp::Ordering::Equal => println!("You win!"),
std::cmp::Ordering::Greater => println!("Too big!"),
},
Err(e) => println!("{}", e),
}
}

// ...

Quitting After a Correct Guess

// ...

match guess {
Ok(guess) => match guess.cmp(&secret_number) {
std::cmp::Ordering::Less => println!("Too small!"),
std::cmp::Ordering::Equal => {
println!("You win!");
break;
}
std::cmp::Ordering::Greater => println!("Too big!"),
},
Err(e) => println!("{}", e),
}

// ...

Handling Invalid Input

let guess: u32 = match guess.trim().parse() {
Ok(num) => num,
Err(_) => continue,
};

Final Code

use std::io;

use rand::Rng;

fn main() {
println!("Guess the number!");
let secret_number = rand::thread_rng().gen_range(1..101);
loop {
let mut guess = String::new();
println!("Please input your guess.");
io::stdin()
.read_line(&mut guess)
.expect("Failed to read line");

println!("You guessed: {}", guess);

let guess: u32 = match guess.trim().parse() {
Ok(num) => num,
Err(_) => continue,
};

match guess.cmp(&secret_number) {
std::cmp::Ordering::Less => println!("Too small!"),
std::cmp::Ordering::Equal => {
println!("You win!");
break;
}
std::cmp::Ordering::Greater => println!("Too big!"),
}
}
}