implementing display for everything
This commit is contained in:
parent
d2928c255d
commit
958c63e7d0
3 changed files with 115 additions and 17 deletions
89
src/game.rs
89
src/game.rs
|
@ -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;
|
||||
|
||||
|
|
41
src/info.rs
41
src/info.rs
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue