Keep/Drop Function #92
|
@ -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) => {
|
||||||
kg333 marked this conversation as resolved
Outdated
|
|||||||
input = r.0;
|
input = r.0;
|
||||||
keep = r.1.1;
|
// 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;
|
||||||
|
} 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
|
||||||
kg333 marked this conversation as resolved
Outdated
projectmoon
commented
Add a third Add a third `/` to get the Rustdoc working. It may also be good to more thoroughly describe what keep and drop mean here, namely that they mean keeping the highest or dropping the highest rolls.
|
|||||||
|
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
Rust supports tuple destructuring in pattern matching, which may be useful here and the other match:
rest
being the rest of the input in this case.Ooh, that's much more human-readable, thanks!