Tracking State
Guess history, attempt limits, and a struct to hold it all.
A bare loop with local variables stops scaling the moment you have more than two pieces of state. Move it into a struct.
struct Game {
secret: u32,
guesses: Vec<u32>,
max_attempts: usize,
}
impl Game {
fn new(max_attempts: usize) -> Self {
Self {
secret: rand::rng().random_range(1..=100),
guesses: Vec::new(),
max_attempts,
}
}
fn guess(&mut self, value: u32) -> Ordering {
self.guesses.push(value);
value.cmp(&self.secret)
}
fn out_of_attempts(&self) -> bool {
self.guesses.len() >= self.max_attempts
}
}
Notice the receiver types: &mut self when the method mutates, &self when it only reads.
The compiler enforces that distinction, which means you can tell what a method does from its
signature alone.