Adding calculations for keep, and adding validation on keep input
This commit is contained in:
parent
1860eaf378
commit
15163ac11d
|
@ -41,7 +41,12 @@ fn parse_dice(input: &str) -> IResult<&str, Dice> {
|
||||||
// if ok, keep expression is present
|
// if ok, keep expression is present
|
||||||
Ok(r) => {
|
Ok(r) => {
|
||||||
input = r.0;
|
input = r.0;
|
||||||
|
// don't allow keep greater than number of dice, and don't allow keep zero
|
||||||
|
if r.1.1 <= count && r.1.1 != "0" {
|
||||||
keep = r.1.1;
|
keep = r.1.1;
|
||||||
|
} else {
|
||||||
|
keep = count;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// otherwise absent and keep all dice
|
// otherwise absent and keep all dice
|
||||||
Err(_) => keep = count,
|
Err(_) => keep = count,
|
||||||
|
|
|
@ -19,15 +19,21 @@ pub trait Rolled {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
pub struct DiceRoll(pub Vec<u32>);
|
// array of rolls in order, and how many dice to keep
|
||||||
|
pub struct DiceRoll (pub Vec<u32>, usize);
|
||||||
|
|
||||||
impl DiceRoll {
|
impl DiceRoll {
|
||||||
pub fn rolls(&self) -> &[u32] {
|
pub fn rolls(&self) -> &[u32] {
|
||||||
&self.0
|
&self.0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn keep(&self) -> usize {
|
||||||
|
self.1
|
||||||
|
}
|
||||||
|
|
||||||
|
// only count kept dice in total
|
||||||
pub fn total(&self) -> u32 {
|
pub fn total(&self) -> u32 {
|
||||||
self.0.iter().sum()
|
self.0[..=(self.1-1)].iter().sum()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,11 +47,16 @@ impl fmt::Display for DiceRoll {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
write!(f, "{}", self.rolled_value())?;
|
write!(f, "{}", self.rolled_value())?;
|
||||||
let rolls = self.rolls();
|
let rolls = self.rolls();
|
||||||
let mut iter = rolls.iter();
|
let keep = self.keep();
|
||||||
|
let mut iter = rolls.iter().enumerate();
|
||||||
if let Some(first) = iter.next() {
|
if let Some(first) = iter.next() {
|
||||||
write!(f, " ({}", first)?;
|
write!(f, " ({}", first.1)?;
|
||||||
for roll in iter {
|
for roll in iter {
|
||||||
write!(f, " + {}", roll)?;
|
if roll.0 < keep {
|
||||||
|
write!(f, " + {}", roll.1)?;
|
||||||
|
} else {
|
||||||
|
write!(f, " + [{}]", roll.1)?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
write!(f, ")")?;
|
write!(f, ")")?;
|
||||||
}
|
}
|
||||||
|
@ -58,11 +69,13 @@ impl Roll for dice::Dice {
|
||||||
|
|
||||||
fn roll(&self) -> DiceRoll {
|
fn roll(&self) -> DiceRoll {
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::thread_rng();
|
||||||
let rolls: Vec<_> = (0..self.count)
|
let mut rolls: Vec<_> = (0..self.count)
|
||||||
.map(|_| rng.gen_range(1..=self.sides))
|
.map(|_| rng.gen_range(1..=self.sides))
|
||||||
.collect();
|
.collect();
|
||||||
|
// sort rolls in descending order
|
||||||
|
rolls.sort_by(|a, b| b.cmp(a));
|
||||||
|
|
||||||
DiceRoll(rolls)
|
DiceRoll(rolls,self.keep as usize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue