Fix clippy warnings

This commit is contained in:
timotree3 2023-01-19 20:59:20 -05:00
parent b8a82294d1
commit d65b7616f1
7 changed files with 78 additions and 94 deletions

View file

@ -188,7 +188,7 @@ pub enum Hinted {
} }
impl fmt::Display for Hinted { impl fmt::Display for Hinted {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self { match *self {
Hinted::Color(color) => { Hinted::Color(color) => {
write!(f, "{}", color) write!(f, "{}", color)
} }
@ -355,16 +355,10 @@ impl BoardState {
// can be discarded without necessarily sacrificing score, based on discard + fireworks // can be discarded without necessarily sacrificing score, based on discard + fireworks
pub fn is_dispensable(&self, card: &Card) -> bool { pub fn is_dispensable(&self, card: &Card) -> bool {
let firework = self.fireworks.get(&card.color).unwrap(); let firework = self.fireworks.get(&card.color).unwrap();
if firework.complete() { firework.complete()
true || card.value < firework.needed_value().unwrap()
} else { || card.value > self.highest_attainable(card.color)
let needed = firework.needed_value().unwrap(); || self.discard.remaining(card) != 1
if card.value < needed || card.value > self.highest_attainable(card.color) {
true
} else {
self.discard.remaining(card) != 1
}
}
} }
pub fn get_players(&self) -> Range<Player> { pub fn get_players(&self) -> Range<Player> {
@ -372,10 +366,7 @@ impl BoardState {
} }
pub fn score(&self) -> Score { pub fn score(&self) -> Score {
self.fireworks self.fireworks.values().map(Firework::score).sum()
.iter()
.map(|(_, firework)| firework.score())
.sum()
} }
pub fn discard_size(&self) -> u32 { pub fn discard_size(&self) -> u32 {
@ -449,8 +440,7 @@ pub trait GameView {
fn has_card(&self, player: &Player, card: &Card) -> bool { fn has_card(&self, player: &Player, card: &Card) -> bool {
self.get_hand(player) self.get_hand(player)
.iter() .iter()
.position(|other_card| card == other_card) .any(|other_card| card == other_card)
.is_some()
} }
fn get_other_players(&self) -> Vec<Player> { fn get_other_players(&self) -> Vec<Player> {
@ -624,12 +614,12 @@ impl GameState {
// takes a card from the player's hand, and replaces it if possible // takes a card from the player's hand, and replaces it if possible
fn take_from_hand(&mut self, index: usize) -> Card { fn take_from_hand(&mut self, index: usize) -> Card {
let ref mut hand = self.hands.get_mut(&self.board.player).unwrap(); let hand = &mut self.hands.get_mut(&self.board.player).unwrap();
hand.remove(index) hand.remove(index)
} }
fn replenish_hand(&mut self) { fn replenish_hand(&mut self) {
let ref mut hand = self.hands.get_mut(&self.board.player).unwrap(); let hand = &mut self.hands.get_mut(&self.board.player).unwrap();
if (hand.len() as u32) < self.board.hand_size { if (hand.len() as u32) < self.board.hand_size {
if let Some(new_card) = self.deck.pop() { if let Some(new_card) = self.deck.pop() {
self.board.deck_size -= 1; self.board.deck_size -= 1;
@ -650,8 +640,8 @@ impl GameState {
self.board.hints_remaining -= 1; self.board.hints_remaining -= 1;
debug!("Hint to player {}, about {}", hint.player, hint.hinted); debug!("Hint to player {}, about {}", hint.player, hint.hinted);
assert!( assert_ne!(
self.board.player != hint.player, self.board.player, hint.player,
"Player {} gave a hint to himself", "Player {} gave a hint to himself",
hint.player hint.player
); );

View file

@ -33,7 +33,7 @@ pub trait CardInfo {
// get probability weight for the card // get probability weight for the card
#[allow(unused_variables)] #[allow(unused_variables)]
fn get_weight(&self, card: &Card) -> f32 { fn get_weight(&self, card: &Card) -> f32 {
1. 1.0
} }
fn get_weighted_possibilities(&self) -> Vec<(Card, f32)> { fn get_weighted_possibilities(&self) -> Vec<(Card, f32)> {
@ -135,7 +135,7 @@ pub trait CardInfo {
// Represents hinted information about possible values of type T // Represents hinted information about possible values of type T
pub trait Info<T> pub trait Info<T>
where where
T: Hash + Eq + Clone, T: Hash + Eq + Clone + Copy,
{ {
// get all a-priori possibilities // get all a-priori possibilities
fn get_all_possibilities() -> Vec<T>; fn get_all_possibilities() -> Vec<T>;
@ -149,7 +149,7 @@ where
fn get_possibilities(&self) -> Vec<T> { fn get_possibilities(&self) -> Vec<T> {
self.get_possibility_set() self.get_possibility_set()
.iter() .iter()
.cloned() .copied()
.collect::<Vec<T>>() .collect::<Vec<T>>()
} }
@ -160,7 +160,7 @@ where
fn initialize() -> HashSet<T> { fn initialize() -> HashSet<T> {
Self::get_all_possibilities() Self::get_all_possibilities()
.iter() .iter()
.cloned() .copied()
.collect::<HashSet<_>>() .collect::<HashSet<_>>()
} }
@ -301,10 +301,10 @@ impl CardPossibilityTable {
pub fn decrement_weight(&mut self, card: &Card) { pub fn decrement_weight(&mut self, card: &Card) {
let remove = { let remove = {
let weight = self.possible.get_mut(card).expect(&format!( let weight = self
"Decrementing weight for impossible card: {}", .possible
card .get_mut(card)
)); .unwrap_or_else(|| panic!("Decrementing weight for impossible card: {}", card));
*weight -= 1; *weight -= 1;
*weight == 0 *weight == 0
}; };
@ -425,15 +425,15 @@ where
// update for hint to me // update for hint to me
pub fn update_for_hint(&mut self, hinted: &Hinted, matches: &[bool]) { pub fn update_for_hint(&mut self, hinted: &Hinted, matches: &[bool]) {
match hinted { match *hinted {
Hinted::Color(color) => { Hinted::Color(color) => {
for (card_info, &matched) in self.hand_info.iter_mut().zip(matches.iter()) { for (card_info, &matched) in self.hand_info.iter_mut().zip(matches.iter()) {
card_info.mark_color(*color, matched); card_info.mark_color(color, matched);
} }
} }
Hinted::Value(value) => { Hinted::Value(value) => {
for (card_info, &matched) in self.hand_info.iter_mut().zip(matches.iter()) { for (card_info, &matched) in self.hand_info.iter_mut().zip(matches.iter()) {
card_info.mark_value(*value, matched); card_info.mark_value(value, matched);
} }
} }
} }

View file

@ -105,7 +105,8 @@ fn main() {
return print!("{}", get_results_table()); return print!("{}", get_results_table());
} }
let log_level_str: &str = &matches.opt_str("l").unwrap_or("info".to_string()); let l_opt = matches.opt_str("l");
let log_level_str = l_opt.as_deref().unwrap_or("info");
let log_level = match log_level_str { let log_level = match log_level_str {
"trace" => log::LogLevelFilter::Trace, "trace" => log::LogLevelFilter::Trace,
"debug" => log::LogLevelFilter::Debug, "debug" => log::LogLevelFilter::Debug,
@ -124,16 +125,17 @@ fn main() {
}) })
.unwrap(); .unwrap();
let n_trials = u32::from_str(&matches.opt_str("n").unwrap_or("1".to_string())).unwrap(); let n_trials = u32::from_str(matches.opt_str("n").as_deref().unwrap_or("1")).unwrap();
let seed = matches let seed = matches
.opt_str("s") .opt_str("s")
.map(|seed_str| u32::from_str(&seed_str).unwrap()); .map(|seed_str| u32::from_str(&seed_str).unwrap());
let progress_info = matches let progress_info = matches
.opt_str("o") .opt_str("o")
.map(|freq_str| u32::from_str(&freq_str).unwrap()); .map(|freq_str| u32::from_str(&freq_str).unwrap());
let n_threads = u32::from_str(&matches.opt_str("t").unwrap_or("1".to_string())).unwrap(); let n_threads = u32::from_str(matches.opt_str("t").as_deref().unwrap_or("1")).unwrap();
let n_players = u32::from_str(&matches.opt_str("p").unwrap_or("4".to_string())).unwrap(); let n_players = u32::from_str(matches.opt_str("p").as_deref().unwrap_or("4")).unwrap();
let strategy_str: &str = &matches.opt_str("g").unwrap_or("cheat".to_string()); let g_opt = matches.opt_str("g");
let strategy_str: &str = g_opt.as_deref().unwrap_or("cheat");
sim_games( sim_games(
n_players, n_players,

View file

@ -85,7 +85,7 @@ impl Histogram {
fn insert_many(&mut self, val: Score, count: u32) { fn insert_many(&mut self, val: Score, count: u32) {
let new_count = self.get_count(&val) + count; let new_count = self.get_count(&val) + count;
self.hist.insert(val, new_count); self.hist.insert(val, new_count);
self.sum += val * (count as u32); self.sum += val * count;
self.total_count += count; self.total_count += count;
} }
pub fn insert(&mut self, val: Score) { pub fn insert(&mut self, val: Score) {
@ -195,11 +195,11 @@ where
lives_histogram.merge(thread_lives_histogram); lives_histogram.merge(thread_lives_histogram);
} }
non_perfect_seeds.sort(); non_perfect_seeds.sort_unstable();
SimResult { SimResult {
scores: score_histogram, scores: score_histogram,
lives: lives_histogram, lives: lives_histogram,
non_perfect_seed: non_perfect_seeds.get(0).cloned(), non_perfect_seed: non_perfect_seeds.first().cloned(),
} }
}) })
} }

View file

@ -253,7 +253,7 @@ pub trait PublicInformation: Clone {
fn get_private_info(&self, view: &OwnedGameView) -> HandInfo<CardPossibilityTable> { fn get_private_info(&self, view: &OwnedGameView) -> HandInfo<CardPossibilityTable> {
let mut info = self.get_player_info(&view.player); let mut info = self.get_player_info(&view.player);
for card_table in info.iter_mut() { for card_table in info.iter_mut() {
for (_, hand) in &view.other_hands { for hand in view.other_hands.values() {
for card in hand { for card in hand {
card_table.decrement_weight_if_possible(card); card_table.decrement_weight_if_possible(card);
} }

View file

@ -23,7 +23,7 @@ impl Question for CardHasProperty {
2 2
} }
fn answer(&self, hand: &Cards, board: &BoardState) -> u32 { fn answer(&self, hand: &Cards, board: &BoardState) -> u32 {
let ref card = hand[self.index]; let card = &hand[self.index];
if (self.property)(board, card) { if (self.property)(board, card) {
1 1
} else { } else {
@ -36,20 +36,18 @@ impl Question for CardHasProperty {
hand_info: &mut HandInfo<CardPossibilityTable>, hand_info: &mut HandInfo<CardPossibilityTable>,
board: &BoardState, board: &BoardState,
) { ) {
let ref mut card_table = hand_info[self.index]; let card_table = &mut hand_info[self.index];
let possible = card_table.get_possibilities(); let possible = card_table.get_possibilities();
for card in &possible { for card in &possible {
if (self.property)(board, card) { if (self.property)(board, card) {
if answer == 0 { if answer == 0 {
card_table.mark_false(card); card_table.mark_false(card);
} }
} else { } else if answer == 1 {
if answer == 1 {
card_table.mark_false(card); card_table.mark_false(card);
} }
} }
} }
}
} }
fn q_is_playable(index: usize) -> CardHasProperty { fn q_is_playable(index: usize) -> CardHasProperty {
CardHasProperty { CardHasProperty {
@ -184,7 +182,7 @@ impl Question for CardPossibilityPartition {
self.n_partitions self.n_partitions
} }
fn answer(&self, hand: &Cards, _: &BoardState) -> u32 { fn answer(&self, hand: &Cards, _: &BoardState) -> u32 {
let ref card = hand[self.index]; let card = &hand[self.index];
*self.partition.get(card).unwrap() *self.partition.get(card).unwrap()
} }
fn acknowledge_answer( fn acknowledge_answer(
@ -193,7 +191,7 @@ impl Question for CardPossibilityPartition {
hand_info: &mut HandInfo<CardPossibilityTable>, hand_info: &mut HandInfo<CardPossibilityTable>,
_: &BoardState, _: &BoardState,
) { ) {
let ref mut card_table = hand_info[self.index]; let card_table = &mut hand_info[self.index];
let possible = card_table.get_possibilities(); let possible = card_table.get_possibilities();
for card in &possible { for card in &possible {
if *self.partition.get(card).unwrap() != answer { if *self.partition.get(card).unwrap() != answer {
@ -220,10 +218,7 @@ impl MyPublicInformation {
fn get_other_players_starting_after(&self, player: Player) -> Vec<Player> { fn get_other_players_starting_after(&self, player: Player) -> Vec<Player> {
let n = self.board.num_players; let n = self.board.num_players;
(0..n - 1) (0..n - 1).map(|i| (player + 1 + i) % n).collect()
.into_iter()
.map(|i| (player + 1 + i) % n)
.collect()
} }
// Returns the number of ways to hint the player. // Returns the number of ways to hint the player.
@ -232,7 +227,7 @@ impl MyPublicInformation {
// - it is public that there are at least two colors // - it is public that there are at least two colors
// - it is public that there are at least two numbers // - it is public that there are at least two numbers
let ref info = self.hand_info[&player]; let info = &self.hand_info[&player];
let may_be_all_one_color = COLORS let may_be_all_one_color = COLORS
.iter() .iter()
@ -276,7 +271,7 @@ impl MyPublicInformation {
(-score, i) (-score, i)
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
scores.sort(); scores.sort_unstable();
scores[0].1 scores[0].1
} }
@ -411,10 +406,7 @@ impl MyPublicInformation {
let player_amt = (n + hint.player - hinter - 1) % n; let player_amt = (n + hint.player - hinter - 1) % n;
let amt_from_prev_players = info_per_player let amt_from_prev_players: u32 = info_per_player.iter().take(player_amt as usize).sum();
.iter()
.take(player_amt as usize)
.sum::<u32>();
let hint_info_we_can_give_to_this_player = info_per_player[player_amt as usize]; let hint_info_we_can_give_to_this_player = info_per_player[player_amt as usize];
let card_index = self.get_index_for_hint(&hint.player); let card_index = self.get_index_for_hint(&hint.player);
@ -427,8 +419,7 @@ impl MyPublicInformation {
} else { } else {
2 2
} }
} else { } else if result[card_index] {
if result[card_index] {
match hint.hinted { match hint.hinted {
Hinted::Value(_) => 0, Hinted::Value(_) => 0,
Hinted::Color(_) => 1, Hinted::Color(_) => 1,
@ -438,7 +429,6 @@ impl MyPublicInformation {
Hinted::Value(_) => 2, Hinted::Value(_) => 2,
Hinted::Color(_) => 3, Hinted::Color(_) => 3,
} }
}
}; };
let hint_value = amt_from_prev_players + hint_type; let hint_value = amt_from_prev_players + hint_type;
@ -571,10 +561,10 @@ impl PublicInformation for MyPublicInformation {
.iter() .iter()
.cloned() .cloned()
.enumerate() .enumerate()
.filter_map(|(i, card_table)| { .map(|(i, card_table)| {
let p_play = card_table.probability_is_playable(&self.board); let p_play = card_table.probability_is_playable(&self.board);
let p_dead = card_table.probability_is_dead(&self.board); let p_dead = card_table.probability_is_dead(&self.board);
Some((i, p_play, p_dead)) (i, p_play, p_dead)
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let know_playable_card = augmented_hand_info_raw let know_playable_card = augmented_hand_info_raw
@ -588,10 +578,10 @@ impl PublicInformation for MyPublicInformation {
let augmented_hand_info = augmented_hand_info_raw let augmented_hand_info = augmented_hand_info_raw
.into_iter() .into_iter()
.filter(|&(i, _, p_dead)| { .filter(|&(i, _, p_dead)| {
if p_dead == 1.0 || hand_info[i].is_determined() { if p_dead == 1.0 {
false false
} else { } else {
true !hand_info[i].is_determined()
} }
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
@ -655,14 +645,14 @@ impl PublicInformation for MyPublicInformation {
.cloned() .cloned()
.collect::<Vec<_>>(); .collect::<Vec<_>>();
ask_play.sort_by_key(|&(i, p_play, _)| (ask_play_score(p_play), i)); ask_play.sort_by_key(|&(i, p_play, _)| (ask_play_score(p_play), i));
if let Some(&(i, _, _)) = ask_play.get(0) { if let Some(&(i, _, _)) = ask_play.first() {
return Some(Box::new(q_is_playable(i))); return Some(Box::new(q_is_playable(i)));
} }
let mut ask_partition = augmented_hand_info; let mut ask_partition = augmented_hand_info;
// sort by probability of death (lowest first), then by index // sort by probability of death (lowest first), then by index
ask_partition.sort_by_key(|&(i, _, p_death)| (FloatOrd(p_death), i)); ask_partition.sort_by_key(|&(i, _, p_death)| (FloatOrd(p_death), i));
if let Some(&(i, _, _)) = ask_partition.get(0) { if let Some(&(i, _, _)) = ask_partition.first() {
let question = CardPossibilityPartition::new(i, total_info, &hand_info[i], &self.board); let question = CardPossibilityPartition::new(i, total_info, &hand_info[i], &self.board);
Some(Box::new(question)) Some(Box::new(question))
} else { } else {
@ -739,6 +729,8 @@ impl InformationPlayerStrategy {
board: &BoardState, board: &BoardState,
hand: &HandInfo<CardPossibilityTable>, hand: &HandInfo<CardPossibilityTable>,
) -> Vec<usize> { ) -> Vec<usize> {
use std::collections::hash_map::Entry::{Occupied, Vacant};
let mut useless: FnvHashSet<usize> = FnvHashSet::default(); let mut useless: FnvHashSet<usize> = FnvHashSet::default();
let mut seen: FnvHashMap<Card, usize> = FnvHashMap::default(); let mut seen: FnvHashMap<Card, usize> = FnvHashMap::default();
@ -746,17 +738,20 @@ impl InformationPlayerStrategy {
if card_table.probability_is_dead(board) == 1.0 { if card_table.probability_is_dead(board) == 1.0 {
useless.insert(i); useless.insert(i);
} else if let Some(card) = card_table.get_card() { } else if let Some(card) = card_table.get_card() {
if seen.contains_key(&card) { match seen.entry(card) {
Occupied(e) => {
// found a duplicate card // found a duplicate card
useless.insert(i); useless.insert(i);
useless.insert(*seen.get(&card).unwrap()); useless.insert(*e.get());
} else { }
seen.insert(card, i); Vacant(e) => {
e.insert(i);
}
} }
} }
} }
let mut useless_vec: Vec<usize> = useless.into_iter().collect(); let mut useless_vec: Vec<usize> = useless.into_iter().collect();
useless_vec.sort(); useless_vec.sort_unstable();
useless_vec useless_vec
} }
@ -859,7 +854,7 @@ impl InformationPlayerStrategy {
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
playable_cards.sort_by_key(|&(i, play_score)| (FloatOrd(-play_score), i)); playable_cards.sort_by_key(|&(i, play_score)| (FloatOrd(-play_score), i));
if let Some(&(play_index, _)) = playable_cards.get(0) { if let Some(&(play_index, _)) = playable_cards.first() {
return TurnChoice::Play(play_index); return TurnChoice::Play(play_index);
} }
@ -912,12 +907,9 @@ impl InformationPlayerStrategy {
// (probably because it stalls the deck-drawing). // (probably because it stalls the deck-drawing).
else if view.board.hints_remaining > 0 && view.someone_else_can_play() { else if view.board.hints_remaining > 0 && view.someone_else_can_play() {
true true
} else if view.board.hints_remaining > 4 { } else {
true // this being false is the only case in which we discard a potentially useful card.
} view.board.hints_remaining > 4
// this is the only case in which we discard a potentially useful card.
else {
false
}; };
if will_hint { if will_hint {
@ -1014,7 +1006,7 @@ impl PlayerStrategy for InformationPlayerStrategy {
} }
fn update(&mut self, turn_record: &TurnRecord, view: &BorrowedGameView) { fn update(&mut self, turn_record: &TurnRecord, view: &BorrowedGameView) {
let hint_matches = if let &TurnResult::Hint(ref matches) = &turn_record.result { let hint_matches = if let TurnResult::Hint(matches) = &turn_record.result {
Some(matches) Some(matches)
} else { } else {
None None
@ -1030,7 +1022,7 @@ impl PlayerStrategy for InformationPlayerStrategy {
} }
match turn_record.choice { match turn_record.choice {
TurnChoice::Hint(ref hint) => { TurnChoice::Hint(ref hint) => {
if let &TurnResult::Hint(ref matches) = &turn_record.result { if let TurnResult::Hint(matches) = &turn_record.result {
self.public_info.update_from_hint_matches(hint, matches); self.public_info.update_from_hint_matches(hint, matches);
} else { } else {
panic!( panic!(
@ -1040,7 +1032,7 @@ impl PlayerStrategy for InformationPlayerStrategy {
} }
} }
TurnChoice::Discard(index) => { TurnChoice::Discard(index) => {
if let &TurnResult::Discard(ref card) = &turn_record.result { if let TurnResult::Discard(card) = &turn_record.result {
self.public_info.update_from_discard_or_play_result( self.public_info.update_from_discard_or_play_result(
view, view,
&turn_record.player, &turn_record.player,
@ -1055,7 +1047,7 @@ impl PlayerStrategy for InformationPlayerStrategy {
} }
} }
TurnChoice::Play(index) => { TurnChoice::Play(index) => {
if let &TurnResult::Play(ref card, _) = &turn_record.result { if let TurnResult::Play(card, _) = &turn_record.result {
self.public_info.update_from_discard_or_play_result( self.public_info.update_from_discard_or_play_result(
view, view,
&turn_record.player, &turn_record.player,

View file

@ -15,7 +15,7 @@ pub trait PlayerStrategy {
// Shouldn't do much, except store configuration parameters and // Shouldn't do much, except store configuration parameters and
// possibility initialize some shared randomness between players // possibility initialize some shared randomness between players
pub trait GameStrategy { pub trait GameStrategy {
fn initialize(&self, player: Player, view: &BorrowedGameView) -> Box<dyn PlayerStrategy>; fn initialize(&self, me: Player, view: &BorrowedGameView) -> Box<dyn PlayerStrategy>;
} }
// Represents configuration for a strategy. // Represents configuration for a strategy.