diff options
author | David Gay <eapoems@riseup.net> | 2023-09-30 21:37:07 -0400 |
---|---|---|
committer | David Gay <eapoems@riseup.net> | 2023-09-30 21:37:07 -0400 |
commit | c0400e87ce8acef2f201a86e00a46a8ae5c7257f (patch) | |
tree | 3b42e661e11d9ee5725a95c34c3f0424b7b4bebb | |
parent | 4dcdf1b06f82c18dbec55577556080e944e4c3df (diff) |
Simple die roller
-rw-r--r-- | src/dice.rs | 41 | ||||
-rw-r--r-- | src/main.rs | 5 |
2 files changed, 45 insertions, 1 deletions
diff --git a/src/dice.rs b/src/dice.rs new file mode 100644 index 0000000..b238a0b --- /dev/null +++ b/src/dice.rs @@ -0,0 +1,41 @@ +use rand::Rng; + +/// Roll a single die with the specified number of sides. +pub fn roll_die(sides: u32) -> u32 { + let mut rng = rand::thread_rng(); + rng.gen_range(1..=sides) +} + +/// Parse and roll dice from a dice formula (e.g. "4d6+2" or "d12*3"). +// TODO: Have rolls return a RollResult or something. +pub fn roll_formula(formula: &str) -> Option<u32> { + let delimiters = ['d', '+', '-', '*', '/']; // Only d implemented right now. + let parts: Vec<&str> = formula.split(|c| delimiters.contains(&c)).collect(); + + if parts.len() < 2 { + return None; + } + + let num_dice = if parts[0].is_empty() { + 1 + } else { + match parts[0].parse::<u32>() { + Ok(num) => num, + Err(_) => return None, + } + }; + + let sides = match parts[1].parse::<u32>() { + Ok(num) => num, + Err(_) => return None, + }; + + let mut total = 0; + + for _ in 0..num_dice { + let roll = roll_die(sides); + total += roll; + } + + Some(total) +} diff --git a/src/main.rs b/src/main.rs index e7a11a9..2b4aca7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,6 @@ +mod dice; + fn main() { - println!("Hello, world!"); + println!("Rolling d20:"); + println!("{}", dice::roll_die(20)); } |