2023-10-07 20:46:24 +02:00
|
|
|
use crate::Error;
|
|
|
|
|
use rand::distributions::{Distribution, Uniform};
|
2024-03-11 20:45:36 +01:00
|
|
|
use rand::{rngs::StdRng, SeedableRng};
|
2023-10-07 20:46:24 +02:00
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
|
|
2024-03-11 20:45:36 +01:00
|
|
|
#[derive(Debug)]
|
|
|
|
|
pub struct DiceRoller {
|
|
|
|
|
rng: StdRng,
|
2023-10-07 20:46:24 +02:00
|
|
|
}
|
2024-03-11 20:45:36 +01:00
|
|
|
|
|
|
|
|
impl Default for DiceRoller {
|
|
|
|
|
fn default() -> Self {
|
|
|
|
|
Self::new(None)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl DiceRoller {
|
|
|
|
|
pub fn new(opt_seed: Option<u64>) -> Self {
|
|
|
|
|
Self {
|
|
|
|
|
rng: match opt_seed {
|
|
|
|
|
None => StdRng::from_rng(rand::thread_rng()).unwrap(),
|
|
|
|
|
Some(seed) => SeedableRng::seed_from_u64(seed),
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-07 20:46:24 +02:00
|
|
|
/// Roll the dices which generates two random numbers between 1 and 6, replicating a perfect
|
|
|
|
|
/// dice. We use the operating system's random number generator.
|
2024-03-11 20:45:36 +01:00
|
|
|
pub fn roll(&mut self) -> Dice {
|
2023-10-07 20:46:24 +02:00
|
|
|
let between = Uniform::new_inclusive(1, 6);
|
|
|
|
|
|
2024-03-11 20:45:36 +01:00
|
|
|
let v = (between.sample(&mut self.rng), between.sample(&mut self.rng));
|
2023-10-07 20:46:24 +02:00
|
|
|
|
2024-03-11 20:45:36 +01:00
|
|
|
Dice { values: (v.0, v.1) }
|
2023-10-07 20:46:24 +02:00
|
|
|
}
|
2024-01-20 21:40:06 +01:00
|
|
|
|
2024-03-11 20:45:36 +01:00
|
|
|
// Heads or tails
|
|
|
|
|
// pub fn coin(self) -> bool {
|
|
|
|
|
// let between = Uniform::new_inclusive(1, 2);
|
|
|
|
|
// let mut rng = rand::thread_rng();
|
|
|
|
|
// between.sample(&mut rng) == 1
|
|
|
|
|
// }
|
|
|
|
|
}
|
2024-01-27 19:11:23 +01:00
|
|
|
|
2024-03-11 20:45:36 +01:00
|
|
|
/// Represents the two dice
|
|
|
|
|
///
|
|
|
|
|
/// Trictrac is always played with two dice.
|
|
|
|
|
#[derive(Debug, Clone, Copy, Serialize, PartialEq, Deserialize, Default)]
|
|
|
|
|
pub struct Dice {
|
|
|
|
|
/// The two dice values
|
|
|
|
|
pub values: (u8, u8),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Dice {
|
2024-01-20 21:40:06 +01:00
|
|
|
pub fn to_bits_string(self) -> String {
|
|
|
|
|
format!("{:0>3b}{:0>3b}", self.values.0, self.values.1)
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-10 11:49:23 +01:00
|
|
|
pub fn to_display_string(self) -> String {
|
|
|
|
|
format!("{} & {}", self.values.0, self.values.1)
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-20 21:40:06 +01:00
|
|
|
// pub fn to_bits(self) -> [bool;6] {
|
|
|
|
|
// self.to_bits_string().into_bytes().iter().map(|strbit| *strbit == '1' as u8).collect()
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// pub from_bits_string(String bits) -> Self {
|
|
|
|
|
//
|
|
|
|
|
// Dices {
|
|
|
|
|
// values: ()
|
|
|
|
|
// }
|
|
|
|
|
// }
|
2023-10-07 20:46:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Trait to roll the dices
|
|
|
|
|
pub trait Roll {
|
|
|
|
|
/// Roll the dices
|
2024-02-03 22:16:14 +01:00
|
|
|
fn roll(&mut self) -> &mut Self;
|
2023-10-07 20:46:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
|
mod tests {
|
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_roll() {
|
2024-03-11 20:45:36 +01:00
|
|
|
let dice = DiceRoller::default().roll();
|
|
|
|
|
assert!(dice.values.0 >= 1 && dice.values.0 <= 6);
|
|
|
|
|
assert!(dice.values.1 >= 1 && dice.values.1 <= 6);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_seed() {
|
2024-03-14 15:28:15 +01:00
|
|
|
let seed = Some(123);
|
|
|
|
|
let dice1 = DiceRoller::new(seed).roll();
|
|
|
|
|
let dice2 = DiceRoller::new(seed).roll();
|
|
|
|
|
let dice3 = DiceRoller::new(seed).roll();
|
|
|
|
|
assert!(dice1.values.0 == dice2.values.0);
|
|
|
|
|
assert!(dice1.values.0 == dice3.values.0);
|
|
|
|
|
assert!(dice1.values.1 == dice2.values.1);
|
|
|
|
|
assert!(dice1.values.1 == dice3.values.1);
|
2023-10-07 20:46:24 +02:00
|
|
|
}
|
|
|
|
|
|
2024-01-20 21:40:06 +01:00
|
|
|
#[test]
|
|
|
|
|
fn test_to_bits_string() {
|
2024-03-11 20:45:36 +01:00
|
|
|
let dice = Dice { values: (4, 2) };
|
|
|
|
|
assert!(dice.to_bits_string() == "100010");
|
2024-01-20 21:40:06 +01:00
|
|
|
}
|
2023-10-07 20:46:24 +02:00
|
|
|
}
|