summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorToby Vincent <tobyv@tobyvin.dev>2023-11-27 11:50:44 -0600
committerToby Vincent <tobyv@tobyvin.dev>2023-11-27 11:50:44 -0600
commit815c70bf9d904b435c4df6b78dbe06578ab61c39 (patch)
tree76d2d7c86ed098160f15162aa682e7c54eb66afe
parent5f7db64aa6767f142ca5b3272195b881eda10492 (diff)
feat(wip): improve formatting
-rw-r--r--src/main.rs135
1 files changed, 77 insertions, 58 deletions
diff --git a/src/main.rs b/src/main.rs
index 7af07bf..d1014f9 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -2,32 +2,48 @@ use std::{collections::HashMap, fmt::Display};
use rand::{seq::SliceRandom, thread_rng};
-const MIN_CARD: u8 = 0;
+const MIN_CARD: u8 = 1;
const MAX_CARD: u8 = 104;
fn main() {
let mut players = Vec::from([
Player {
+ name: String::from("Curie"),
value_function: |card, line| line.push_cost(card).unwrap_or_default(),
hand: Default::default(),
score: 0,
},
Player {
+ name: String::from("Joe"),
value_function: |card, line| line.push_cost(card).unwrap_or_default(),
hand: Default::default(),
score: 0,
},
Player {
+ name: String::from("Jim"),
+ value_function: |card, line| line.push_cost(card).unwrap_or_default(),
+ hand: Default::default(),
+ score: 0,
+ },
+ Player {
+ name: String::from("Jill"),
value_function: |card, line| line.push_cost(card).unwrap_or_default(),
hand: Default::default(),
score: 0,
},
]);
- round(&mut players);
- round(&mut players);
- round(&mut players);
- round(&mut players);
+ let mut n = 0;
+ while players.iter().all(|p| p.score < 66) {
+ n += 1;
+ round(&mut players);
+
+ println!("Round {n}");
+ println!("Name Score");
+ for player in &mut *players {
+ println!("{:<6} {:02}", player.name, player.score);
+ }
+ }
}
fn round(players: &mut [Player]) {
@@ -35,51 +51,72 @@ fn round(players: &mut [Player]) {
cards.shuffle(&mut thread_rng());
let deck = &mut cards.iter();
- let mut state = deck.take(5).copied().map(Line::from).collect::<Vec<Line>>();
+ let mut state = deck
+ .take(5)
+ .copied()
+ .enumerate()
+ .map(Line::from)
+ .collect::<Vec<Line>>();
for player in &mut *players {
player.set_hand(deck.take(10).copied().collect());
- println!("Player: {player}");
+ println!("{}: {:?}", player.name, player.hand);
}
for (i, line) in state.iter().enumerate() {
println!("Line {i}: {line}");
}
- while !players.iter().any(|p| p.hand.is_empty() || p.score > 66) {
+ while !players.iter().any(|p| p.hand.is_empty()) {
let cards: Vec<u8> = players.iter_mut().map(|p| p.evaluate(&state)).collect();
+ let mut played: Vec<(&mut Player, u8)> = players.iter_mut().zip(cards).collect();
+
+ played.sort_by_key(|p| p.1);
+
+ let mut actions = vec![HashMap::new(); state.len()];
+ let mut player_names = Vec::new();
+ print!("{:37}", "Table");
+
+ for (player, card) in played {
+ print!("{:>10}", player.name);
+ player_names.push(&player.name);
- for (player, card) in players.iter_mut().zip(cards) {
let line = state
.iter_mut()
.min_by_key(|line| (player.value_function)(card, line))
.unwrap();
+ actions[line.id].insert(&player.name, card);
+
if let Some(score) = line.push(card) {
player.score += score;
}
}
- for (i, line) in state.iter().enumerate() {
- println!("Line {i}: {line}");
- }
- }
+ println!();
+ for (line, actions) in state.iter().zip(actions) {
+ let cards: String = line
+ .cards
+ .iter()
+ .fold(String::new(), |buf, c| format!("{buf}[{c:>3}]"));
+
+ print!("Line {cards:<32}");
+ for name in &player_names {
+ let card = actions
+ .get(name)
+ .map(|c| format!("[{c:>3}]"))
+ .unwrap_or("".to_string());
+ print!("{:>10}", card);
+ }
- for player in &mut *players {
- println!("Player: {player}");
+ println!();
+ }
}
}
-fn display_cards(cards: &[u8]) -> String {
- cards
- .iter()
- .map(|c| format!("{c}"))
- .collect::<Vec<_>>()
- .join("][")
-}
-
#[derive(Debug, Default)]
struct Line {
+ id: usize,
cards: Vec<u8>,
}
@@ -110,38 +147,24 @@ impl Line {
impl Display for Line {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- let cards = self
- .cards
+ write!(f, "{}: ", self.id)?;
+ self.cards
.iter()
- .map(|c| format!("{c}"))
- .collect::<Vec<_>>()
- .join("][");
- write!(f, "[{cards}]")
+ .try_for_each(|card| write!(f, "[{card:03}]"))
}
}
-impl From<u8> for Line {
- fn from(value: u8) -> Self {
+impl From<(usize, u8)> for Line {
+ fn from((id, value): (usize, u8)) -> Self {
Self {
+ id,
cards: Vec::from([value]),
}
}
}
-#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default)]
-struct Move {
- value: u8,
- line: usize,
- card: u8,
-}
-
-impl Display for Move {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- write!(f, "[{}] to line {}", self.card, self.line)
- }
-}
-
struct Player {
+ name: String,
value_function: fn(card: u8, line: &Line) -> u8,
hand: Vec<u8>,
score: u8,
@@ -157,8 +180,15 @@ impl Player {
let value_function = self.value_function;
let mut cards = HashMap::new();
- for line in state {
- for card in &self.hand {
+ for card in &self.hand {
+ let mut valid_play_found = false;
+ for line in state {
+ if line.head() < card {
+ valid_play_found = true
+ } else if valid_play_found {
+ continue;
+ }
+
let value = value_function(*card, line);
cards
.entry(card)
@@ -172,19 +202,8 @@ impl Player {
cards
.iter()
.max_by_key(|e| e.1)
- .and_then(|e| self.hand.iter().position(|c| c == e.1))
+ .and_then(|e| self.hand.iter().position(|c| c == *e.0))
.map(|index| self.hand.remove(index))
.unwrap()
}
}
-
-impl Display for Player {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- write!(
- f,
- "Score: {}, Hand: {}",
- self.score,
- display_cards(&self.hand)
- )
- }
-}