Composed parsing and rolling functionality into roll_dice function
This commit is contained in:
parent
c8de11d2b1
commit
6a1f5b6035
29
src/lib.rs
29
src/lib.rs
@ -147,8 +147,10 @@ struct Roll {
|
|||||||
enum RollError {
|
enum RollError {
|
||||||
#[error("Roll failed. Empty RollWithModifier")]
|
#[error("Roll failed. Empty RollWithModifier")]
|
||||||
EmptyRollWithModifier,
|
EmptyRollWithModifier,
|
||||||
#[error("Roll failed. Invalid filter operator")]
|
#[error("Roll failed. Invalid filter operator '{0}'")]
|
||||||
InvalidFilterOperator,
|
InvalidFilterOperator(char),
|
||||||
|
#[error("Roll failed. Invalid segment operator '{0}'")]
|
||||||
|
InvalidOperator(char),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn roll_dice_segments<R: Rng>(rwms: &[RollWithModifier], mut rng: R) -> Result<Vec<Roll>, RollError> {
|
fn roll_dice_segments<R: Rng>(rwms: &[RollWithModifier], mut rng: R) -> Result<Vec<Roll>, RollError> {
|
||||||
@ -203,7 +205,7 @@ fn roll_dice_segments<R: Rng>(rwms: &[RollWithModifier], mut rng: R) -> Result<V
|
|||||||
'/' => { total /= amount; },
|
'/' => { total /= amount; },
|
||||||
'*' => { total *= amount; },
|
'*' => { total *= amount; },
|
||||||
_ => {
|
_ => {
|
||||||
return Err(RollError::InvalidFilterOperator);
|
return Err(RollError::InvalidFilterOperator(*op));
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -213,3 +215,24 @@ fn roll_dice_segments<R: Rng>(rwms: &[RollWithModifier], mut rng: R) -> Result<V
|
|||||||
})
|
})
|
||||||
.collect::<Result<Vec<_>,_>>()
|
.collect::<Result<Vec<_>,_>>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn roll_dice<R : Rng>(s: &str, mut rng: R) -> Result<(i32, Vec<(Roll, Vec<Segment>)>)> {
|
||||||
|
let segments = parse_dice_segments(s)?;
|
||||||
|
|
||||||
|
let groups = group_modifiers_to_dicerolls(&segments);
|
||||||
|
|
||||||
|
let rolls = roll_dice_segments(&groups, &mut rng)?;
|
||||||
|
|
||||||
|
let total = rolls.iter().try_fold(0, |acc,roll| match roll.operator {
|
||||||
|
'+' => Ok(acc + roll.total),
|
||||||
|
'-' => Ok(acc - roll.total),
|
||||||
|
'*' => Ok(acc * roll.total),
|
||||||
|
'/' => Ok(acc / roll.total),
|
||||||
|
_ => Err(RollError::InvalidOperator(roll.operator))
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let rolls_with_modifiers = rolls.into_iter()
|
||||||
|
.zip(groups.into_iter().map(|grp| grp.modifiers)).collect();
|
||||||
|
|
||||||
|
Ok((total, rolls_with_modifiers))
|
||||||
|
}
|
||||||
|
|||||||
@ -111,3 +111,35 @@ fn test_roll_dice_segments() {
|
|||||||
Roll{operator: '*', results: vec![6], total: 4},
|
Roll{operator: '*', results: vec![6], total: 4},
|
||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_roll_dice() {
|
||||||
|
|
||||||
|
let input = "4d6d2 + 2 - 1d4";
|
||||||
|
|
||||||
|
let mut rng = StdRng::seed_from_u64(2);
|
||||||
|
|
||||||
|
let result = roll_dice(input, &mut rng);
|
||||||
|
|
||||||
|
let expected = (8i32, vec![
|
||||||
|
(Roll {
|
||||||
|
operator: '+',
|
||||||
|
results: vec![5, 5],
|
||||||
|
total: 12
|
||||||
|
},
|
||||||
|
vec![Segment::Modifier { op: '+', amount: 2 }]),
|
||||||
|
|
||||||
|
(Roll {
|
||||||
|
operator: '-',
|
||||||
|
results: vec![4],
|
||||||
|
total: 4
|
||||||
|
},
|
||||||
|
vec![])]);
|
||||||
|
|
||||||
|
if let Ok(result) = result {
|
||||||
|
assert_eq!(result, expected);
|
||||||
|
} else {
|
||||||
|
panic!("Expected Ok, was: {:?}", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user