Lecture 6 - Guessing Game Part 2: VSCode & Completing the Game
Learning objectives
By the end of class today you should be able to:
- Use VSCode with rust-analyzer and the integrated terminal for Rust development
- Start using loops and conditional logic in Rust
- Use
matchexpressions andOrderingfor comparisons - Keep your code tidy and readable with
clippy, comments, and doc strings
Why VSCode for Rust?
- Rust Analyzer: Real-time error checking, autocomplete, type hints
- Integrated terminal: No more switching windows
- Git integration: Visual diffs, staging, commits
Setting up VSCode for Rust
You'll need to have
- Installed VSCode
- Installed Rust
- Installed the rust-analyzer extension
Joey covered this in discussions - if you need help with these come talk to us
Opening our project
From the terminal:
cd guessing_game
code .
or use File -> Open Folder from VSCode
VSCode Features Demo
File Explorer & Navigation
- Side panel for project files
- Quick switching with
Cmd+P(Mac) /Ctrl+P(Windows) - Split editor views
Integrated Terminal
View → TerminalorCtrl+`- Multiple terminals
- Same commands as before:
cargo run,cargo check
Rust Analyzer in Action
- Red squiggles - Compiler errors
- Yellow squiggles - Warnings
- Hover tooltips - Type information
- Autocomplete - As you type suggestions
- Format on save - Automatic code formatting
Let's see it in action!
Cargo Clippy
- Run with
cargo clippyin terminal to see suggestions - Suggests stylistic changes that won't change the function of your code (ie refactoring suggestions)
cargo clippy --fixwill automatically accept suggestions
Completing The Guessing Game
Highlights from the compiler errors activity
Let's chat about these together
- Lots of folks hit on something like this - what happened?
"1. error ""error[E0433]: failed to resolve: use of unresolved module or unlinked crate `rand`
--> main.rs:8:25"""
- Then playing around, people found:
- expected `;`, found keyword `let` (deleted a semicolon)
- invalid basic string b/c removed ""
- linking with `link.exe` failed: exit code: 1
- expected function, found macro `println` (got rid of ! in println!)
- cannot borrow `guess` as mutable, as it is not declared as mutable (got rid of mut in declaration)
- this file contains an unclosed delimiter (deleted a curly bracket)
- unresolved import `std::higang`
- failed to resolve: use of unresolved module or unlinked crate `io`
- unreachable expression (placed code after break)
Let's walk through an interesting one
One student used cargo add rand rather than manually adding rand to the dependencies (which is totally valid!), and go this. What's going on?
warning: use of deprecated function `rand::thread_rng`: Renamed to `rng`
--> src\main.rs:8:31
|
8 | let secret_number = rand::thread_rng().gen_range(1..=100);
| ^^^^^^^^^^
|
= note: `#[warn(deprecated)]` on by default
warning: use of deprecated method `rand::Rng::gen_range`: Renamed to `random_range`
--> src\main.rs:8:44
|
8 | let secret_number = rand::thread_rng().gen_range(1..=100);
| ^^^^^^^^^
warning: `scavenger_hunt` (bin ""scavenger_hunt"") generated 2 warnings
Current state (from last class):
use std::io; use rand::Rng; fn main() { println!("Guess the number!"); let secret_number = rand::thread_rng().gen_range(1..=100); 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); }
Making it a real game:
- Remove the secret reveal - no cheating!
- Compare numbers - too high? too low?
- Add a loop - keep playing until correct
- Handle invalid input - what if they type "banana"?
Steps 0+1
Step 0: No cheating
We just need to delete:
#![allow(unused)] fn main() { println!("The secret number is: {secret_number}"); }
Step 1: Comparing Numbers
First, we need to convert the guess to a number and compare:
#![allow(unused)] fn main() { use std::cmp::Ordering; // typically crate :: module :: type or crate :: module :: function // Add this after reading input: let guess: u32 = guess.trim().parse().expect("Please enter a number!"); match guess.cmp(&secret_number) { Ordering::Less => println!("Too small!"), Ordering::Greater => println!("Too big!"), Ordering::Equal => println!("You win!"), } }
Step 2: Adding the Loop
Wrap the input/comparison in a loop:
#![allow(unused)] fn main() { loop { println!("Please input your guess."); // ... input code ... match guess.cmp(&secret_number) { Ordering::Less => println!("Too small!"), Ordering::Greater => println!("Too big!"), Ordering::Equal => { println!("You win!"); break; // Exit the loop } } } }
Step 3: Handling Invalid Input
Replace .expect() with proper error handling:
#![allow(unused)] fn main() { let guess: u32 = match guess.trim().parse() { Ok(num) => num, Err(_) => { println!("Please enter a valid number!"); continue; // Skip to next loop iteration } }; }
Back to VSCode
Completing the game
Let's paste the whole thing in and take a look
Comments & Documentation Best Practices
What would happen if you came back to this program in a month?
Inline Comments (//)
- Explain why, not what the code does
- Bad:
// Create a random number - Good:
// Generate secret between 1-100 for balanced difficulty - If it's not clear what the code does you should edit the code!
Doc Comments (///)
- Document meaningful chunks of code like functions, structs, modules
- Show up in
cargo docand IDE tooltips
#![allow(unused)] fn main() { /// Prompts user for a guess and validates input /// Returns the parsed number or continues loop on invalid input fn get_user_guess() -> u32 { // implementation... } }
The Better Comments extension
- Color-codes different types of comments in VSCode - let's paste it into
main.rsand see
#![allow(unused)] fn main() { // TODO: Add input validation here // ! FIXME: This will panic on negative numbers // ? Why does this work differently on Windows? // * Important: This function assumes sorted input }
Visual Git Features:
- Source Control panel - See changed files
- Diff view - Side-by-side comparisons
- Stage changes - Click the + button
- Commit - Write message and commit
Still use terminal for:
git status- Quick overviewgit log- Commit historygit push/git pull- Syncing
Activity Time (20 minutes)
Wrap-up
What we've accomplished so far:
- Can now use shell, git, and rust all in one place (VSCode)
- We built a complete, functional game from scratch
- Started learning key Rust concepts: loops, matching, error handling
- We've practiced using GitHub Classroom - you'll use it for HW2!
Looking ahead
- HW1 due tonight at midnight
- HW2 released this evening
- Discussions tomorrow will focus on getting started on HW2