Skip to content

Instantly share code, notes, and snippets.

@macabeus
Created November 3, 2018 22:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save macabeus/c67ad63c8738a14119e989c96d3a4005 to your computer and use it in GitHub Desktop.
Save macabeus/c67ad63c8738a14119e989c96d3a4005 to your computer and use it in GitHub Desktop.
A simple hangman game written in Rust
// 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