Created
November 3, 2018 22:11
-
-
Save macabeus/c67ad63c8738a14119e989c96d3a4005 to your computer and use it in GitHub Desktop.
A simple hangman game written in Rust
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// cargo-deps: rand="0.5.5" | |
extern crate rand; | |
use std::io; | |
use std::collections::HashSet; | |
use rand::Rng; | |
use std::iter::FromIterator; | |
struct State { | |
life: i8, | |
word: String, | |
characters: Vec<char>, | |
missing_characters: usize, | |
} | |
enum Phase { | |
Running, | |
Won, | |
GameOver, | |
} | |
enum InsertCharacterResult { | |
Correct, | |
Wrong, | |
Repeated, | |
} | |
impl State { | |
fn get_phase(&self) -> Phase { | |
if self.life == 0 { | |
Phase::GameOver | |
} else if self.missing_characters == 0 { | |
Phase::Won | |
} else { | |
Phase::Running | |
} | |
} | |
fn insert_character(&mut self, new_char: char) -> InsertCharacterResult { | |
if self.characters.contains(&new_char) { | |
return InsertCharacterResult::Repeated | |
} | |
self.characters.push(new_char); | |
if self.word.contains(new_char) { | |
self.missing_characters -= 1; | |
InsertCharacterResult::Correct | |
} else { | |
self.life -= 1; | |
InsertCharacterResult::Wrong | |
} | |
} | |
fn get_hidden_word_game(&self) -> String { | |
self.word | |
.chars() | |
.map(|c| if self.characters.contains(&c) { c } else { '_' }) | |
.collect::<String>() | |
} | |
fn display_state(&self) { | |
print!("-------------------------\n"); | |
print!("Word: {}\n", self.get_hidden_word_game()); | |
print!("Life: {}\n", self.life); | |
print!("Characters typed: {}\n", String::from_iter(&self.characters)); | |
print!("-------------------------\n"); | |
} | |
} | |
fn user_input() -> char { | |
let mut new_char = String::new(); | |
io::stdin().read_line(&mut new_char) | |
.expect("Failed to read the input"); | |
new_char.chars().next().unwrap() | |
} | |
fn game_loop(state: &mut State) { | |
state.display_state(); | |
let new_char = user_input(); | |
match state.insert_character(new_char) { | |
InsertCharacterResult::Correct => print!("Yes!\n"), | |
InsertCharacterResult::Wrong => print!("No...\n"), | |
InsertCharacterResult::Repeated => print!("Character alread typed\n"), | |
} | |
match state.get_phase() { | |
Phase::Running => game_loop(state), | |
Phase::Won => { | |
print!("Finish!\n"); | |
print!("Secret Word: {}\n", state.get_hidden_word_game()); | |
}, | |
Phase::GameOver => print!("Game Over!"), | |
} | |
} | |
fn main() { | |
let words = ["banana", "apple", "watermelon", "melon", "pineapples", "cherry"]; | |
let game_word = rand::thread_rng().choose(&words).unwrap(); | |
let mut game_word_chars = HashSet::new(); | |
for c in game_word.chars() { | |
game_word_chars.insert(c); | |
} | |
let mut initial_state = State { | |
life: 5, | |
word: game_word.to_string(), | |
characters: Vec::new(), | |
missing_characters: game_word_chars.len(), | |
}; | |
game_loop(&mut initial_state); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment