summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dice.rs135
1 files changed, 91 insertions, 44 deletions
diff --git a/src/dice.rs b/src/dice.rs
index c89c4c9..68b6ecf 100644
--- a/src/dice.rs
+++ b/src/dice.rs
@@ -3,16 +3,26 @@ use std::ops::Add;
use rand::rngs::ThreadRng;
use rand::Rng;
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
-pub struct RiskDie(u8);
pub const NUM_DIE_LEVELS: usize = 6;
-pub const RISK_DIE_VALUES: [u8; NUM_DIE_LEVELS] = [4, 6, 8, 10, 12, 20];
-pub const DELTA_4: RiskDie = RiskDie(0);
-pub const DELTA_6: RiskDie = RiskDie(1);
-pub const DELTA_8: RiskDie = RiskDie(2);
-pub const DELTA_10: RiskDie = RiskDie(3);
-pub const DELTA_12: RiskDie = RiskDie(4);
-pub const DELTA_20: RiskDie = RiskDie(5);
+pub const DIE_VALUES: [u8; NUM_DIE_LEVELS] = [4, 6, 8, 10, 12, 20];
+
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+pub struct Die(u8);
+pub const D_4: Die = Die(0);
+pub const D_6: Die = Die(1);
+pub const D_8: Die = Die(2);
+pub const D_10: Die = Die(3);
+pub const D_12: Die = Die(4);
+pub const D_20: Die = Die(5);
+
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+pub struct RiskDie(Die);
+pub const DELTA_4: RiskDie = RiskDie(Die(0));
+pub const DELTA_6: RiskDie = RiskDie(Die(1));
+pub const DELTA_8: RiskDie = RiskDie(Die(2));
+pub const DELTA_10: RiskDie = RiskDie(Die(3));
+pub const DELTA_12: RiskDie = RiskDie(Die(4));
+pub const DELTA_20: RiskDie = RiskDie(Die(5));
#[derive(Debug, PartialEq, Eq)]
pub enum Error
@@ -21,11 +31,11 @@ pub enum Error
InvalidValue,
}
-impl RiskDie
+impl Die
{
pub fn from_level(level: u8) -> Result<Self, Error>
{
- if (level as usize) < RISK_DIE_VALUES.len() {
+ if (level as usize) < DIE_VALUES.len() {
Ok(Self(level))
}
else {
@@ -35,7 +45,7 @@ impl RiskDie
pub fn from_value(value: u8) -> Result<Self, Error>
{
- for (i, val) in RISK_DIE_VALUES.iter().enumerate() {
+ for (i, val) in DIE_VALUES.iter().enumerate() {
if *val == value {
return Ok(Self(i as u8));
}
@@ -46,27 +56,15 @@ impl RiskDie
pub fn level(&self) -> u8 { self.0 }
- pub fn value(&self) -> u8 { RISK_DIE_VALUES[self.0 as usize] }
+ pub fn value(&self) -> u8 { DIE_VALUES[self.0 as usize] }
- /// Roll the die. If the die shows 3 or less, it returns the next lower die.
- /// If it is more, it returns itself. If it was already the lowest die value
- /// and it would be stepped down it returns `None`.
- pub fn roll(self) -> Option<Self>
+ pub fn roll(&self) -> u8
{
let mut rng = rand::thread_rng();
self.roll_with_rng(&mut rng)
}
- pub fn roll_with_rng(self, rng: &mut ThreadRng) -> Option<Self>
- {
- let rolled = rng.gen_range(1..=self.value());
- if rolled > 3 {
- Some(self)
- }
- else {
- self.level_down()
- }
- }
+ pub fn roll_with_rng(&self, rng: &mut ThreadRng) -> u8 { rng.gen_range(1..=self.value()) }
pub fn can_be_lowered(&self) -> bool { self.0 > 0 }
@@ -94,6 +92,53 @@ impl RiskDie
}
}
+impl RiskDie
+{
+ pub fn from_level(level: u8) -> Result<Self, Error>
+ {
+ Ok(Self {
+ 0: Die::from_level(level)?,
+ })
+ }
+
+ pub fn from_value(value: u8) -> Result<Self, Error>
+ {
+ Ok(Self {
+ 0: Die::from_value(value)?,
+ })
+ }
+
+ pub fn level(&self) -> u8 { self.0.level() }
+
+ pub fn value(&self) -> u8 { self.0.value() }
+
+ /// Roll the die. If the die shows 3 or less, it returns the next lower die.
+ /// If it is more, it returns itself. If it was already the lowest die value
+ /// and it would be stepped down it returns `None`.
+ pub fn roll(self) -> Option<Self>
+ {
+ let mut rng = rand::thread_rng();
+ self.roll_with_rng(&mut rng)
+ }
+
+ pub fn roll_with_rng(self, rng: &mut ThreadRng) -> Option<Self>
+ {
+ let rolled = self.0.roll_with_rng(rng);
+ if rolled > 3 {
+ Some(self)
+ }
+ else {
+ self.level_down()
+ }
+ }
+
+ pub fn can_be_lowered(&self) -> bool { self.0.can_be_lowered() }
+ pub fn level_down(self) -> Option<Self> { self.0.level_down().map(|d| RiskDie(d)) }
+
+ pub fn can_be_upped(&self) -> bool { self.0.can_be_upped() }
+ pub fn level_up(self) -> Self { RiskDie(self.0.level_up()) }
+}
+
#[rustfmt::skip]
const DELTA_ADDITION_TABLE: [[u8; NUM_DIE_LEVELS]; NUM_DIE_LEVELS] = [
/* ------------------- with d4 d6 d8 d10 d12 d20 */
@@ -110,7 +155,9 @@ impl Add for RiskDie
fn add(self, other: Self) -> Self::Output
{
- RiskDie(DELTA_ADDITION_TABLE[self.0 as usize][other.0 as usize])
+ RiskDie(Die(
+ DELTA_ADDITION_TABLE[self.0.level() as usize][other.0.level() as usize]
+ ))
}
}
@@ -120,7 +167,7 @@ mod tests
use super::*;
#[test]
- fn create_die_from_level()
+ fn create_risk_die_from_level()
{
let die = RiskDie::from_level(0).expect("Unable to create die for correct level");
assert_eq!(die.value(), 4);
@@ -137,7 +184,7 @@ mod tests
}
#[test]
- fn create_die_from_invalid_level()
+ fn create_risk_die_from_invalid_level()
{
assert_eq!(
RiskDie::from_level(6).expect_err("Should not be able to create die from level"),
@@ -146,7 +193,7 @@ mod tests
}
#[test]
- fn create_from_value()
+ fn create_risk_die_from_value()
{
let die = RiskDie::from_value(4).expect("Unable to create die from correct value");
assert_eq!(die.level(), 0);
@@ -163,25 +210,25 @@ mod tests
}
#[test]
- fn level_down()
+ fn risk_die_level_down()
{
assert_eq!(DELTA_4.level_down(), None);
- assert_eq!(DELTA_6.level_down(), Some(RiskDie(0)));
- assert_eq!(DELTA_8.level_down(), Some(RiskDie(1)));
- assert_eq!(DELTA_10.level_down(), Some(RiskDie(2)));
- assert_eq!(DELTA_12.level_down(), Some(RiskDie(3)));
- assert_eq!(DELTA_20.level_down(), Some(RiskDie(4)));
+ assert_eq!(DELTA_6.level_down(), Some(DELTA_4));
+ assert_eq!(DELTA_8.level_down(), Some(DELTA_6));
+ assert_eq!(DELTA_10.level_down(), Some(DELTA_8));
+ assert_eq!(DELTA_12.level_down(), Some(DELTA_10));
+ assert_eq!(DELTA_20.level_down(), Some(DELTA_12));
}
#[test]
- fn level_up()
+ fn risk_die_level_up()
{
- assert_eq!(DELTA_4.level_up(), RiskDie(1));
- assert_eq!(DELTA_6.level_up(), RiskDie(2));
- assert_eq!(DELTA_8.level_up(), RiskDie(3));
- assert_eq!(DELTA_10.level_up(), RiskDie(4));
- assert_eq!(DELTA_12.level_up(), RiskDie(5));
- assert_eq!(DELTA_20.level_up(), RiskDie(5));
+ assert_eq!(DELTA_4.level_up(), DELTA_6);
+ assert_eq!(DELTA_6.level_up(), DELTA_8);
+ assert_eq!(DELTA_8.level_up(), DELTA_10);
+ assert_eq!(DELTA_10.level_up(), DELTA_12);
+ assert_eq!(DELTA_12.level_up(), DELTA_20);
+ assert_eq!(DELTA_20.level_up(), DELTA_20);
}
#[test]