use std::collections::HashMap; use std::cmp::Eq; use std::hash::Hash; use game::*; // Represents a bit of information about T pub trait Info where T: Hash + Eq + Clone { // get all a-priori possibilities fn get_possibilities() -> Vec; // get map from values to whether it's possible // true means maybe, false means no fn get_possibility_map(&self) -> &HashMap; fn get_mut_possibility_map(&mut self) -> &mut HashMap; fn initialize() -> HashMap { let mut possible_map : HashMap = HashMap::new(); for value in Self::get_possibilities().iter() { possible_map.insert(value.clone(), true); } possible_map } fn merge(&mut self, other: &Self) { for (value, possible) in self.get_mut_possibility_map().iter_mut() { *possible = *possible && *other.get_possibility_map().get(value).unwrap(); } } fn mark_true(&mut self, value: &T) { // mark everything else as definitively impossible for (other_value, possible) in self.get_mut_possibility_map().iter_mut() { if other_value != value { *possible = false; } else { assert_eq!(*possible, true); } } } fn mark_false(&mut self, value: &T) { self.get_mut_possibility_map().insert(value.clone(), false); } fn mark(&mut self, value: &T, info: bool) { if info { self.mark_true(value); } else { self.mark_false(value); } } } #[derive(Debug)] pub struct ColorInfo(HashMap); impl ColorInfo { pub fn new() -> ColorInfo { ColorInfo(ColorInfo::initialize()) } } impl Info for ColorInfo { fn get_possibilities() -> Vec { let mut possible : Vec = Vec::new(); for color in COLORS.iter() { possible.push(*color); } possible } fn get_possibility_map(&self) -> &HashMap { &self.0 } fn get_mut_possibility_map(&mut self) -> &mut HashMap { &mut self.0 } } #[derive(Debug)] pub struct ValueInfo(HashMap); impl ValueInfo { pub fn new() -> ValueInfo { ValueInfo(ValueInfo::initialize()) } } impl Info for ValueInfo { fn get_possibilities() -> Vec { let mut possible : Vec = Vec::new(); for value in VALUES.iter() { possible.push(*value); } possible } fn get_possibility_map(&self) -> &HashMap { &self.0 } fn get_mut_possibility_map(&mut self) -> &mut HashMap { &mut self.0 } } #[derive(Debug)] pub struct CardInfo { pub color_info: ColorInfo, pub value_info: ValueInfo, } impl CardInfo { pub fn new() -> CardInfo { CardInfo { color_info: ColorInfo::new(), value_info: ValueInfo::new(), } } }