bug fixes and optimizations for 84

This commit is contained in:
Dr. Matthias Ratajczak
2022-09-27 20:50:52 +02:00
parent 5141f9e06e
commit 1dcc402379
2 changed files with 28 additions and 30 deletions
+27 -29
View File
@@ -1,13 +1,14 @@
use std::collections::{HashMap, VecDeque}; use std::collections::VecDeque;
use std::fmt::Display; use std::fmt::Display;
use std::iter::Cycle; use std::iter::Cycle;
use rand::prelude::*; use rand::prelude::*;
use rand::seq::IteratorRandom;
use strum::IntoEnumIterator; use strum::IntoEnumIterator;
use strum_macros::EnumIter; use strum_macros::EnumIter;
const NUMBER_SQUARES: usize = 40; const NUMBER_SQUARES: usize = 40;
const FOUR: [usize; 4] = [1, 2, 3, 4];
const SIX: [usize; 6] = [1, 2, 3, 4, 5, 6];
#[derive(Debug, EnumIter, PartialEq, Hash, Eq, PartialOrd)] #[derive(Debug, EnumIter, PartialEq, Hash, Eq, PartialOrd)]
pub enum Squares { pub enum Squares {
@@ -53,7 +54,7 @@ pub enum Squares {
H2 = 39, H2 = 39,
} }
#[derive(Debug, EnumIter, Clone)] #[derive(Debug, EnumIter)]
enum CommunityChest { enum CommunityChest {
AdvanceToGo, AdvanceToGo,
GoToJail, GoToJail,
@@ -73,7 +74,7 @@ enum CommunityChest {
DoNothing14, DoNothing14,
} }
#[derive(Debug, EnumIter, Clone)] #[derive(Debug, EnumIter)]
enum Chance { enum Chance {
AdvanceToGo, AdvanceToGo,
GoToJail, GoToJail,
@@ -104,18 +105,17 @@ impl Display for Squares {
} }
} }
#[allow(dead_code)]
#[derive(Debug)] #[derive(Debug)]
pub enum Dice { pub enum Dice {
FourSided = 4, FourSided,
SixSided = 6, SixSided,
} }
impl Dice { impl Dice {
fn throw(&self, rng: &mut ThreadRng) -> usize { fn throw(&self, rng: &mut ThreadRng) -> usize {
match self { match self {
Self::SixSided => (1..=6).choose(rng).unwrap() as usize, Self::SixSided => *SIX.choose(rng).unwrap(),
Self::FourSided => (1..=4).choose(rng).unwrap() as usize, Self::FourSided => *FOUR.choose(rng).unwrap(),
} }
} }
} }
@@ -131,14 +131,12 @@ pub struct Monopoly {
impl Monopoly { impl Monopoly {
fn throw_dice(&mut self) -> (usize, bool) { fn throw_dice(&mut self) -> (usize, bool) {
let mut iter = (0..2).map(|_| self.dice.throw(&mut self.rng)); let t1 = self.dice.throw(&mut self.rng);
let t1 = iter.next().unwrap(); let t2 = self.dice.throw(&mut self.rng);
let t2 = iter.next().unwrap();
let is_double = t1 == t2; let is_double = t1 == t2;
(t1 + t2, is_double) (t1 + t2, is_double)
} }
#[allow(clippy::new_without_default)]
pub fn new(dice: Dice) -> Self { pub fn new(dice: Dice) -> Self {
let mut rng = rand::thread_rng(); let mut rng = rand::thread_rng();
let community_pile = Self::gen_random_community_pile(&mut rng); let community_pile = Self::gen_random_community_pile(&mut rng);
@@ -188,7 +186,7 @@ impl Monopoly {
} }
fn go_to_jail(&mut self) -> Squares { fn go_to_jail(&mut self) -> Squares {
self.go_to_square(Squares::Jail) self.go_to_square(&Squares::Jail)
} }
fn handle_chance(&mut self, square: Squares) -> Squares { fn handle_chance(&mut self, square: Squares) -> Squares {
@@ -196,10 +194,10 @@ impl Monopoly {
match card { match card {
Chance::AdvanceToGo => self.advance_to_go(), Chance::AdvanceToGo => self.advance_to_go(),
Chance::GoToJail => self.go_to_jail(), Chance::GoToJail => self.go_to_jail(),
Chance::GoToC1 => self.go_to_square(Squares::C1), Chance::GoToC1 => self.go_to_square(&Squares::C1),
Chance::GoToE3 => self.go_to_square(Squares::E3), Chance::GoToE3 => self.go_to_square(&Squares::E3),
Chance::GoToH2 => self.go_to_square(Squares::H2), Chance::GoToH2 => self.go_to_square(&Squares::H2),
Chance::GoToR1 => self.go_to_square(Squares::R1), Chance::GoToR1 => self.go_to_square(&Squares::R1),
Chance::GoToNextR | Chance::GoToNextRAgain => self.go_to_railway(), Chance::GoToNextR | Chance::GoToNextRAgain => self.go_to_railway(),
Chance::GoToNextU => self.go_to_utility(), Chance::GoToNextU => self.go_to_utility(),
Chance::GoBack3Squares => self.go_back_3_squares(), Chance::GoBack3Squares => self.go_back_3_squares(),
@@ -207,8 +205,8 @@ impl Monopoly {
} }
} }
fn go_to_square(&mut self, square: Squares) -> Squares { fn go_to_square(&mut self, square: &Squares) -> Squares {
self.board.find(|c| *c == square).unwrap() self.board.find(|c| c == square).unwrap()
} }
fn go_to_squares(&mut self, squares: &[Squares]) -> Squares { fn go_to_squares(&mut self, squares: &[Squares]) -> Squares {
@@ -227,7 +225,7 @@ impl Monopoly {
} }
fn advance_to_go(&mut self) -> Squares { fn advance_to_go(&mut self) -> Squares {
self.go_to_square(Squares::Go) self.go_to_square(&Squares::Go)
} }
fn draw_from_chance_pile_and_put_at_bottom(&mut self) -> &Chance { fn draw_from_chance_pile_and_put_at_bottom(&mut self) -> &Chance {
@@ -257,7 +255,8 @@ impl Monopoly {
fn check_too_many_doubles(&mut self, is_double: bool) -> bool { fn check_too_many_doubles(&mut self, is_double: bool) -> bool {
if is_double { if is_double {
self.number_consecutive_doubles += 1; self.number_consecutive_doubles += 1;
self.number_consecutive_doubles == 3 self.number_consecutive_doubles %= 3;
self.number_consecutive_doubles == 0
} else { } else {
self.number_consecutive_doubles = 0; self.number_consecutive_doubles = 0;
false false
@@ -272,7 +271,7 @@ impl Monopoly {
pub struct Statistics { pub struct Statistics {
monopoly: Monopoly, monopoly: Monopoly,
iterations: usize, iterations: usize,
fields_count: HashMap<Squares, usize>, fields_count: Vec<usize>,
} }
impl Statistics { impl Statistics {
@@ -280,21 +279,20 @@ impl Statistics {
Self { Self {
monopoly, monopoly,
iterations, iterations,
fields_count: Squares::iter().zip([0].into_iter().cycle()).collect(), fields_count: vec![0; 40],
} }
} }
pub fn run(&mut self) { pub fn run(&mut self) {
for _ in 0..self.iterations { for _ in 0..self.iterations {
let square = self.monopoly.make_move(); let square = self.monopoly.make_move();
*self.fields_count.get_mut(&square).unwrap() += 1; self.fields_count[square as isize as usize] += 1;
} }
} }
pub fn show(&self) { pub fn show(&self) {
let mut result: Vec<(&Squares, f64)> = self let mut result: Vec<(Squares, f64)> = Squares::iter()
.fields_count .zip(&self.fields_count)
.iter()
.map(|(k, v)| (k, *v as f64 / self.iterations as f64 * 100.)) .map(|(k, v)| (k, *v as f64 / self.iterations as f64 * 100.))
.collect(); .collect();
result.sort_unstable_by(|(_, v1), (_, v2)| v2.partial_cmp(v1).unwrap()); result.sort_unstable_by(|(_, v1), (_, v2)| v2.partial_cmp(v1).unwrap());
@@ -355,7 +353,7 @@ mod test {
#[test] #[test]
fn custom() { fn custom() {
let mut monopoly = Monopoly::new(Dice::SixSided); let mut monopoly = Monopoly::new(Dice::SixSided);
assert_eq!(monopoly.go_to_square(Squares::E3), Squares::E3); assert_eq!(monopoly.go_to_square(&Squares::E3), Squares::E3);
assert_eq!(monopoly.advance_by(1), Squares::R3); assert_eq!(monopoly.advance_by(1), Squares::R3);
} }
+1 -1
View File
@@ -2,7 +2,7 @@ use euler84::{Dice, Monopoly, Statistics};
fn main() { fn main() {
let monopoly = Monopoly::new(Dice::FourSided); let monopoly = Monopoly::new(Dice::FourSided);
let mut statistics = Statistics::new(monopoly, 500_000_000); let mut statistics = Statistics::new(monopoly, 10_000_000);
statistics.run(); statistics.run();
statistics.show(); statistics.show();
} }