summaryrefslogtreecommitdiff
path: root/src/dice.rs
diff options
context:
space:
mode:
authorDavid Gay <eapoems@riseup.net>2023-09-30 21:37:07 -0400
committerDavid Gay <eapoems@riseup.net>2023-09-30 21:37:07 -0400
commitc0400e87ce8acef2f201a86e00a46a8ae5c7257f (patch)
tree3b42e661e11d9ee5725a95c34c3f0424b7b4bebb /src/dice.rs
parent4dcdf1b06f82c18dbec55577556080e944e4c3df (diff)
Simple die roller
Diffstat (limited to 'src/dice.rs')
-rw-r--r--src/dice.rs41
1 files changed, 41 insertions, 0 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)
+}