implementing display for everything

This commit is contained in:
Jeff Wu 2016-03-09 10:27:40 -08:00
parent d2928c255d
commit 958c63e7d0
3 changed files with 115 additions and 17 deletions

View file

@ -64,12 +64,12 @@ impl <T> From<Vec<T>> for Pile<T> {
}
impl <T> fmt::Display for Pile<T> where T: fmt::Display {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// surely doing unwraps is improper..
write!(f, "[").unwrap();
try!(f.write_str("["));
for item in &self.0 {
write!(f, "{}, ", item).unwrap();
try!(f.write_str(&format!("{}, ", item)));
}
write!(f, "] ")
try!(f.write_str(""));
Ok(())
}
}
@ -96,12 +96,15 @@ impl Firework {
}
}
fn top_value(&self) -> Value {
self.cards.top().unwrap().value
}
fn desired_value(&self) -> Option<Value> {
let top_value = self.cards.top().unwrap().value;
if top_value == FINAL_VALUE {
if self.complete() {
None
} else {
Some(top_value + 1)
Some(self.top_value() + 1)
}
}
@ -111,7 +114,7 @@ impl Firework {
}
fn complete(&self) -> bool {
self.desired_value() == None
self.top_value() == FINAL_VALUE
}
fn place(&mut self, card: Card) {
@ -129,10 +132,10 @@ impl Firework {
}
impl fmt::Display for Firework {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if let Some(value) = self.desired_value() {
write!(f, "{} firework at {}", self.color, value)
} else {
if self.complete() {
write!(f, "{} firework complete!", self.color)
} else {
write!(f, "{} firework at {}", self.color, self.top_value())
}
}
}
@ -189,6 +192,19 @@ pub struct PlayerState {
// represents what is common knowledge about the player's hand
info: CardsInfo,
}
impl fmt::Display for PlayerState {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
try!(f.write_str("hand: "));
let mut i = 0;
for card in &self.hand.0 {
let info : &CardInfo = &self.info.0[i];
try!(f.write_str(&format!("{} =? {: <15} ", card, info)));
i += 1;
}
Ok(())
}
}
impl PlayerState {
pub fn new(hand: Cards) -> PlayerState {
let infos = (0..hand.size()).map(|_| {
@ -275,7 +291,7 @@ pub struct BoardState {
// TODO:
// pub turn_history: Vec<TurnChoice>,
// only relevant when deck runs out
deckless_turns_remaining: u32,
pub deckless_turns_remaining: u32,
}
impl BoardState {
pub fn new(opts: &GameOptions) -> BoardState {
@ -324,6 +340,10 @@ impl BoardState {
score as u32
}
pub fn deck_size(&self) -> usize {
self.deck.size()
}
pub fn player_to_left(&self, player: &Player) -> Player {
(player + 1) % self.num_players
}
@ -331,6 +351,35 @@ impl BoardState {
(player - 1) % self.num_players
}
}
impl fmt::Display for BoardState {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
try!(f.write_str(&format!(
"Turn {} (Player {}'s turn):\n", self.turn, self.player
)));
let deck_size = self.deck_size();
try!(f.write_str(&format!(
"{} cards remaining in deck\n", deck_size
)));
if deck_size == 0 {
try!(f.write_str(&format!(
"Deck is empty. {} turns remaining in game\n", self.deckless_turns_remaining
)));
}
try!(f.write_str(&format!(
"{}/{} hints remaining\n", self.hints_remaining, self.hints_total
)));
try!(f.write_str(&format!(
"{}/{} lives remaining\n", self.lives_remaining, self.lives_total
)));
try!(f.write_str("Fireworks:\n"));
for (_, firework) in &self.fireworks {
try!(f.write_str(&format!(" {}\n", firework)));
}
// discard: Cards::new(),
Ok(())
}
}
// complete game view of a given player
// state will be borrowed GameState
@ -352,6 +401,22 @@ pub struct GameState {
pub player_states: HashMap<Player, PlayerState>,
pub board: BoardState,
}
impl fmt::Display for GameState {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
try!(f.write_str("==========================\n"));
try!(f.write_str("Hands:\n"));
try!(f.write_str("==========================\n"));
for player in 0..self.board.num_players {
let state = &self.player_states.get(&player).unwrap();
try!(f.write_str(&format!("player {} {}\n", player, state)));
}
try!(f.write_str("==========================\n"));
try!(f.write_str("Board:\n"));
try!(f.write_str("==========================\n"));
try!(f.write_str(&format!("{}", self.board)));
Ok(())
}
}
pub type Score = u32;

View file

@ -1,22 +1,39 @@
use std::collections::HashMap;
use std::cmp::Eq;
use std::hash::Hash;
use std::fmt;
use game::*;
// Represents a bit of information about T
pub trait Info<T> where T: Hash + Eq + Clone {
// get all a-priori possibilities
fn get_possibilities() -> Vec<T>;
fn get_all_possibilities() -> Vec<T>;
// get map from values to whether it's possible
// true means maybe, false means no
fn get_possibility_map(&self) -> &HashMap<T, bool>;
fn get_mut_possibility_map(&mut self) -> &mut HashMap<T, bool>;
// get what is now possible
fn get_possibilities(&self) -> Vec<&T> {
let mut v = Vec::new();
let map = self.get_possibility_map();
for (value, is_possible) in map {
if *is_possible {
v.push(value);
}
}
v
}
fn is_possible(&self, value: &T) -> bool {
self.get_possibility_map().contains_key(value)
}
fn initialize() -> HashMap<T, bool> {
let mut possible_map : HashMap<T, bool> = HashMap::new();
for value in Self::get_possibilities().iter() {
for value in Self::get_all_possibilities().iter() {
possible_map.insert(value.clone(), true);
}
possible_map
@ -60,7 +77,7 @@ impl ColorInfo {
}
}
impl Info<Color> for ColorInfo {
fn get_possibilities() -> Vec<Color> {
fn get_all_possibilities() -> Vec<Color> {
let mut possible : Vec<Color> = Vec::new();
for color in COLORS.iter() {
possible.push(*color);
@ -83,7 +100,7 @@ impl ValueInfo {
}
}
impl Info<Value> for ValueInfo {
fn get_possibilities() -> Vec<Value> {
fn get_all_possibilities() -> Vec<Value> {
let mut possible : Vec<Value> = Vec::new();
for value in VALUES.iter() {
possible.push(*value);
@ -111,3 +128,19 @@ impl CardInfo {
}
}
}
impl fmt::Display for CardInfo {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut string = String::new();
for color in &self.color_info.get_possibilities() {
let colorchar = color.chars().next().unwrap();
string.push(colorchar);
}
// while string.len() < COLORS.len() + 1 {
string.push(' ');
//}
for value in &self.value_info.get_possibilities() {
string.push_str(&format!("{}", value));
}
f.pad(&string)
}
}

View file

@ -44,7 +44,7 @@ pub fn simulate_once<S: Strategy>(opts: &GameOptions, _: &S) -> Score {
}
// TODO: do some stuff
debug!("State: {:?}", game);
debug!("State:\n{}", game);
}
game.score()
}