use std::io;
use rand::Rng;
struct Hangman {
word: String,
guessed: Vec<char>,
attempts: usize,
}
impl Hangman {
fn new(word: String) -> Self {
Self {
word: word.to_lowercase(),
guessed: Vec::new(),
attempts: 6,
}
}
fn display(&self) -> String {
let mut result = String::new();
for c in self.word.chars() {
if self.guessed.contains(&c) {
result.push(c);
} else {
result.push('_');
}
result.push(' ');
}
result
}
fn guess(&mut self, letter: char) -> bool {
let letter = letter.to_lowercase().next().unwrap();
if self.guessed.contains(&letter) {
return false;
}
self.guessed.push(letter);
if !self.word.contains(letter) {
self.attempts -= 1;
return false;
}
true
}
fn won(&self) -> bool {
for c in self.word.chars() {
if !self.guessed.contains(&c) {
return false;
}
}
true
}
fn lost(&self) -> bool {
self.attempts == 0
}
}
pub fn play() {
let words = vec!["rust", "programming", "computer", "function", "variable"];
let word = words[rand::thread_rng().gen_range(0..words.len())].to_string();
let mut game = Hangman::new(word);
println!("\nHangman - Guess the word!");
loop {
println!("\n{}", game.display());
println!("Attempts left: {}", game.attempts);
println!("Enter a letter:");
let mut input = String::new();
io::stdin().read_line(&mut input).unwrap();
let letter = match input.trim().chars().next() {
Some(c) if c.is_alphabetic() => c,
_ => continue,
};
if game.guess(letter) {
println!("Correct!");
} else {
println!("Wrong!");
}
if game.won() {
println!("\nYou won! Word: {}", game.word);
break;
}
if game.lost() {
println!("\nYou lost! Word: {}", game.word);
break;
}
}
}