Thirty Days of Rust: Day Four
Tags: 30days, rust, programming, challenge
Published: 2022-01-15 23:18:46

Today was more of a relaxed day for me, instead of putting together a whole new project I just added the ability to lose into my hangman game. This was way simpler than I thought it would be (I'm not really sure why, but I expected this to take a while), so I don't really have that much to share, but I will share it.
## Final Code
```rust
// /src/main.rs

use rand::seq::SliceRandom;
use rand::thread_rng;
use std::io;

fn main() {
    let mut rng = thread_rng();

    let possible_words = [
        "Hangman",
        "Challenge",
        "Hello, World!",
        "Programming",
        "Rust",
        "Thirty Days",
        "Day Three",
    ];
    let word_to_guess = possible_words.choose(&mut rng).unwrap().to_string();

    let mut guessed_letters: Vec<char> = vec![];

    let mut current_guess = String::new();
    for i in 0..word_to_guess.chars().count() {
        if &word_to_guess.chars().nth(i).unwrap() == &' ' {
            current_guess.push_str(" ");
        } else {
            current_guess.push_str("_");
        }
    }

    let mut guesses_left: i32 = 8;

    while current_guess != word_to_guess && guesses_left > 0 {
        println!("{}", &current_guess);
        println!("Make a guess");
        println!("Guessed Letters: {:?}", guessed_letters);
        let mut guess = String::new();

        io::stdin().read_line(&mut guess).unwrap();

        if !guessed_letters.contains(&guess.chars().nth(0).unwrap()) {
            guessed_letters.push(guess.chars().nth(0).unwrap());

            let mut new_guess = current_guess.chars().collect::<Vec<_>>();

            for i in 0..word_to_guess.len() {
                if word_to_guess.chars().collect::<Vec<_>>()[i]
                    .eq_ignore_ascii_case(&guess.chars().nth(0).unwrap())
                {
                    new_guess[i] = word_to_guess.chars().collect::<Vec<_>>()[i];
                } else {
                    continue;
                }
            }
            
            if new_guess.iter().collect::<String>() == current_guess {
                guesses_left -= 1;
            }

            current_guess = new_guess.iter().collect::<String>();

            println!("Guesses left: {:?}", guesses_left);
        } else {
            println!("You already guessed that");
            continue;
        }
    }
    if current_guess == word_to_guess {
        println!("You won! Guesses: {:?}", guessed_letters.len());
        println!("{}", current_guess);
    } else {
        println!("You lose! Guesses: {:?}", guessed_letters.len())
    }
}
```
It's basically the same as yesterday, but with a few things added. Notably, a variable to keep track of how many guesses are left, an extra condition for the while loop, and a way to check if the guess was wrong or not:
```rust
...
let mut guesses_left: i32 = 8;
...
while current_guess != word_to_guess && guesses_left > 0
...
if new_guess.iter().collect::<String>() == current_guess {
                guesses_left -= 1;
            }

            current_guess = new_guess.iter().collect::<String>();
...
```
The last part is also a slight change to what I was doing before, which was to immediately assign the `current_guess` to the `new_guess` instead of waiting until I checked the validity of the guess.
### Problem Solving
The first way I went about this was just by getting rid of the `continue;` in that else statement and replacing it with the `guesses_left -= 1;` line. The problem with this is that it runs each for loop iteration, so that was a no go. Not thinking too hard about it, I changed `guesses_left` to be dependant on the length of `word_to_guess`, which sort of solved one issue but raised another one. The line was still being called every iteration, so instead of only using up "one" guess if the guess was wrong, it used up one guess every time a letter wasn't every letter in the string, which was all the time. That's why I had to bring the logic out of the for loop, and instead of relying on that else statement, I just waited to reassign `current_guess` to the value of `new_guess` until after I had made a check to see if anything was correct.
That's about it for me today, and thanks for reading.