forked from projectmoon/tenebrous-dicebot
Chance die should only succeed on 10. Added no-explode rolls.
This commit is contained in:
parent
dfa96f51bd
commit
16b5a3a51a
|
@ -10,6 +10,7 @@ pub enum DicePoolQuality {
|
||||||
EightAgain,
|
EightAgain,
|
||||||
Rote,
|
Rote,
|
||||||
ChanceDie,
|
ChanceDie,
|
||||||
|
NoExplode,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for DicePoolQuality {
|
impl fmt::Display for DicePoolQuality {
|
||||||
|
@ -20,6 +21,7 @@ impl fmt::Display for DicePoolQuality {
|
||||||
DicePoolQuality::EightAgain => write!(f, "eight-again"),
|
DicePoolQuality::EightAgain => write!(f, "eight-again"),
|
||||||
DicePoolQuality::Rote => write!(f, "rote quality"),
|
DicePoolQuality::Rote => write!(f, "rote quality"),
|
||||||
DicePoolQuality::ChanceDie => write!(f, "chance die"),
|
DicePoolQuality::ChanceDie => write!(f, "chance die"),
|
||||||
|
DicePoolQuality::NoExplode => write!(f, "no roll-agains"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,8 +49,12 @@ impl DicePool {
|
||||||
pub fn new(count: u32, successes_for_exceptional: u32, quality: DicePoolQuality) -> DicePool {
|
pub fn new(count: u32, successes_for_exceptional: u32, quality: DicePoolQuality) -> DicePool {
|
||||||
DicePool {
|
DicePool {
|
||||||
count: count,
|
count: count,
|
||||||
sides: 10, //TODO make configurable
|
sides: 10, //TODO make configurable
|
||||||
success_on: 8, //TODO make configurable
|
//TODO make configurable
|
||||||
|
success_on: match quality {
|
||||||
|
DicePoolQuality::ChanceDie => 10,
|
||||||
|
_ => 8,
|
||||||
|
},
|
||||||
exceptional_success: successes_for_exceptional,
|
exceptional_success: successes_for_exceptional,
|
||||||
quality: quality,
|
quality: quality,
|
||||||
}
|
}
|
||||||
|
@ -123,7 +129,7 @@ impl Roll for DicePool {
|
||||||
type Output = DicePoolRoll;
|
type Output = DicePoolRoll;
|
||||||
|
|
||||||
fn roll(&self) -> DicePoolRoll {
|
fn roll(&self) -> DicePoolRoll {
|
||||||
roll_dice(self)
|
roll_dice(self, &mut RngDieRoller(rand::thread_rng()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,7 +215,9 @@ fn roll_die<R: DieRoller>(roller: &mut R, sides: u32, quality: DicePoolQuality)
|
||||||
DicePoolQuality::NineAgain => results.append(&mut roll_exploding_die(roller, sides, 9)),
|
DicePoolQuality::NineAgain => results.append(&mut roll_exploding_die(roller, sides, 9)),
|
||||||
DicePoolQuality::EightAgain => results.append(&mut roll_exploding_die(roller, sides, 8)),
|
DicePoolQuality::EightAgain => results.append(&mut roll_exploding_die(roller, sides, 8)),
|
||||||
DicePoolQuality::Rote => results.append(&mut roll_rote_die(roller, sides)),
|
DicePoolQuality::Rote => results.append(&mut roll_rote_die(roller, sides)),
|
||||||
DicePoolQuality::ChanceDie => results.push(roller.roll_number(sides)),
|
DicePoolQuality::ChanceDie | DicePoolQuality::NoExplode => {
|
||||||
|
results.push(roller.roll_number(sides))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
results
|
results
|
||||||
|
@ -217,11 +225,9 @@ fn roll_die<R: DieRoller>(roller: &mut R, sides: u32, quality: DicePoolQuality)
|
||||||
|
|
||||||
///Roll the dice in a dice pool, according to behavior documented in the various rolling
|
///Roll the dice in a dice pool, according to behavior documented in the various rolling
|
||||||
///methods.
|
///methods.
|
||||||
fn roll_dice(pool: &DicePool) -> DicePoolRoll {
|
fn roll_dice<R: DieRoller>(pool: &DicePool, roller: &mut R) -> DicePoolRoll {
|
||||||
let mut roller = RngDieRoller(rand::thread_rng());
|
|
||||||
|
|
||||||
let rolls: Vec<u32> = (0..pool.count)
|
let rolls: Vec<u32> = (0..pool.count)
|
||||||
.flat_map(|_| roll_die(&mut roller, pool.sides, pool.quality))
|
.flat_map(|_| roll_die(roller, pool.sides, pool.quality))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
DicePoolRoll {
|
DicePoolRoll {
|
||||||
|
@ -260,6 +266,28 @@ mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Sanity checks
|
||||||
|
#[test]
|
||||||
|
pub fn chance_die_has_success_on_10_test() {
|
||||||
|
assert_eq!(
|
||||||
|
10,
|
||||||
|
DicePool::new(1, 5, DicePoolQuality::ChanceDie).success_on
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn non_chance_die_has_success_on_8_test() {
|
||||||
|
fn check_success_on(quality: DicePoolQuality) {
|
||||||
|
assert_eq!(8, DicePool::new(1, 5, quality).success_on);
|
||||||
|
}
|
||||||
|
|
||||||
|
check_success_on(DicePoolQuality::TenAgain);
|
||||||
|
check_success_on(DicePoolQuality::NineAgain);
|
||||||
|
check_success_on(DicePoolQuality::EightAgain);
|
||||||
|
check_success_on(DicePoolQuality::Rote);
|
||||||
|
check_success_on(DicePoolQuality::NoExplode);
|
||||||
|
}
|
||||||
|
|
||||||
//Dice rolling tests.
|
//Dice rolling tests.
|
||||||
#[test]
|
#[test]
|
||||||
pub fn ten_again_test() {
|
pub fn ten_again_test() {
|
||||||
|
@ -303,7 +331,15 @@ mod tests {
|
||||||
assert_eq!(vec![5, 10, 8], rolls);
|
assert_eq!(vec![5, 10, 8], rolls);
|
||||||
}
|
}
|
||||||
|
|
||||||
//DiceRoll tests
|
#[test]
|
||||||
|
pub fn no_explode_roll_test() {
|
||||||
|
let pool = DicePool::new(1, 5, DicePoolQuality::NoExplode);
|
||||||
|
let mut roller = SequentialDieRoller::new(vec![10, 8]);
|
||||||
|
let roll: DicePoolRoll = roll_dice(&pool, &mut roller);
|
||||||
|
assert_eq!(vec![10], roll.rolls());
|
||||||
|
}
|
||||||
|
|
||||||
|
//DicePool tests
|
||||||
#[test]
|
#[test]
|
||||||
fn is_successful_on_equal_test() {
|
fn is_successful_on_equal_test() {
|
||||||
let result = DicePoolRoll {
|
let result = DicePoolRoll {
|
||||||
|
@ -316,6 +352,30 @@ mod tests {
|
||||||
assert_eq!(1, result.successes());
|
assert_eq!(1, result.successes());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn chance_die_success_test() {
|
||||||
|
let result = DicePoolRoll {
|
||||||
|
quality: DicePoolQuality::TenAgain,
|
||||||
|
rolls: vec![10],
|
||||||
|
exceptional_on: 5,
|
||||||
|
success_on: 10,
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(1, result.successes());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn chance_die_fail_test() {
|
||||||
|
let result = DicePoolRoll {
|
||||||
|
quality: DicePoolQuality::TenAgain,
|
||||||
|
rolls: vec![9],
|
||||||
|
exceptional_on: 5,
|
||||||
|
success_on: 10,
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(0, result.successes());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn is_exceptional_test() {
|
fn is_exceptional_test() {
|
||||||
let result = DicePoolRoll {
|
let result = DicePoolRoll {
|
||||||
|
|
|
@ -24,7 +24,8 @@ fn parse_quality(input: &str) -> IResult<&str, DicePoolQuality> {
|
||||||
named!(quality(&str) -> DicePoolQuality, alt!(
|
named!(quality(&str) -> DicePoolQuality, alt!(
|
||||||
complete!(tag!("n")) => { |_| DicePoolQuality::NineAgain } |
|
complete!(tag!("n")) => { |_| DicePoolQuality::NineAgain } |
|
||||||
complete!(tag!("e")) => { |_| DicePoolQuality::EightAgain } |
|
complete!(tag!("e")) => { |_| DicePoolQuality::EightAgain } |
|
||||||
complete!(tag!("r")) => { |_| DicePoolQuality::Rote }
|
complete!(tag!("r")) => { |_| DicePoolQuality::Rote } |
|
||||||
|
complete!(tag!("x")) => { |_| DicePoolQuality::NoExplode }
|
||||||
));
|
));
|
||||||
|
|
||||||
let (input, dice_pool_quality) = quality(input)?;
|
let (input, dice_pool_quality) = quality(input)?;
|
||||||
|
@ -143,6 +144,7 @@ mod tests {
|
||||||
assert_eq!(parse_quality("n"), Ok(("", DicePoolQuality::NineAgain)));
|
assert_eq!(parse_quality("n"), Ok(("", DicePoolQuality::NineAgain)));
|
||||||
assert_eq!(parse_quality("e"), Ok(("", DicePoolQuality::EightAgain)));
|
assert_eq!(parse_quality("e"), Ok(("", DicePoolQuality::EightAgain)));
|
||||||
assert_eq!(parse_quality("r"), Ok(("", DicePoolQuality::Rote)));
|
assert_eq!(parse_quality("r"), Ok(("", DicePoolQuality::Rote)));
|
||||||
|
assert_eq!(parse_quality("x"), Ok(("", DicePoolQuality::NoExplode)));
|
||||||
assert_eq!(parse_quality("b"), Err(Err::Error(("b", ErrorKind::Alt))));
|
assert_eq!(parse_quality("b"), Err(Err::Error(("b", ErrorKind::Alt))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue