use std::collections::HashMap; mod animals; mod slot; struct AnswerMachine<'a> { answer: String, yes_no: HashMap<&'a str, bool>, distinguish: HashMap<&'a str, (&'a str, bool)>, } impl<'a> AnswerMachine<'a> { fn abort(&self, msg: String) -> ! { println!("{}", msg); std::process::exit(1); } } impl<'a> animals::UserAPI for AnswerMachine<'a> { fn notify_new_game(&self) { println!("----- NEW GAME -----"); println!("Secret animal is: {}", self.answer); } fn notify_game_ended(&self) { println!("Game ended.\n"); } fn notify_new_animal(&self, animal: &str) { println!("Learned a new animal: {}", animal); } fn notify_victory(&self) { println!("Yay, found an answer!"); } fn answer_yes_no(&self, question: &str) -> bool { println!("{}", question); let answer = match self.yes_no.get(question) { Some(a) => *a, None => { self.abort(format!("* Missing answer for {}! *", &self.answer)); } }; println!("> {}", match answer { true => "yes", false => "no" }); answer } fn is_it_a(&self, animal: &str) -> bool { println!("Is it a {}?", animal); let answer = animal == &self.answer; println!("> {}", match answer { true => "yes", false => "no" }); answer } fn what_is_it(&self) -> String { println!("What animal is it?"); println!("> {}", self.answer); self.answer.clone() } fn how_to_tell_apart(&self, other: &str) -> (String, bool) { println!("How to tell apart {} and {}?", self.answer, other); let (s, b) = self.distinguish.get(other).unwrap_or_else(|| { self.abort(format!("* I don't know how to tell apart {} and {}! *", self.answer, other)); }); println!("> {}", s); println!("What is the answer for {}?", self.answer); println!( "> {}", match *b { true => "yes", false => "no" } ); (s.to_string(), *b) } } // a little hack for map initializer literals macro_rules! map( { $($key:expr => $value:expr),* } => { { let mut m = std::collections::HashMap::new(); $( m.insert($key, $value); )* m } }; ); fn main() { let mut db = animals::AnimalDB::new(); let duck = AnswerMachine { answer: "duck".to_string(), yes_no: map! { "Does it quack?" => true }, distinguish: map! { "cow" => ("Does it moo?", false) }, }; db.start_game(&duck); let dog = AnswerMachine { answer: "dog".to_string(), yes_no: map! { "Does it quack?" => false, "Does it woof?" => true, "Is it wild?" => false }, distinguish: map! { "duck" => ("Does it quack?", false), "wolf" => ("Is it wild?", false) }, }; db.start_game(&dog); let wolf = AnswerMachine { answer: "wolf".to_string(), yes_no: map! { "Does it quack?" => false, "Is it wild?" => true, "Does it fly?" => false, "Does it eat acorns?" => false }, distinguish: map! { "dog" => ("Is it wild?", true) }, }; db.start_game(&wolf); let cow = AnswerMachine { answer: "cow".to_string(), yes_no: map! { "Does it quack?" => false, "Is it wild?" => false, "Does it woof?" => false, "Does it give milk?" => true, "Is it grown for meat?" => true }, distinguish: map! { "dog" => ("Does it woof?", false) }, }; db.start_game(&cow); let pig = AnswerMachine { answer: "pig".to_string(), yes_no: map! { "Does it quack?" => false, "Is it wild?" => false, "Does it woof?" => false, "Does it give milk?" => false }, distinguish: map! { "cow" => ("Does it give milk?", false) }, }; db.start_game(&pig); let goat = AnswerMachine { answer: "goat".to_string(), yes_no: map! { "Does it quack?" => false, "Is it wild?" => false, "Does it woof?" => false, "Does it give milk?" => true, "Is it grown for meat?" => false }, distinguish: map! { "cow" => ("Is it grown for meat?", false) }, }; db.start_game(&goat); let raven = AnswerMachine { answer: "raven".to_string(), yes_no: map! { "Does it quack?" => false, "Is it wild?" => true, "Does it woof?" => false, "Does it fly?" => true }, distinguish: map! { "wolf" => ("Does it fly?", true) }, }; db.start_game(&raven); let boar = AnswerMachine { answer: "boar".to_string(), yes_no: map! { "Does it quack?" => false, "Is it wild?" => true, "Does it woof?" => false, "Does it fly?" => false }, distinguish: map! { "wolf" => ("Does it eat acorns?", true) }, }; db.start_game(&boar); // try how the DB works with the learned animals println!("===== Testing known animals ====="); db.start_game(&cow); db.start_game(&dog); db.start_game(&wolf); db.start_game(&duck); db.start_game(&pig); db.start_game(&goat); db.start_game(&raven); }