From a0fafce90cb3632bf9cf79909e9b680d84cf06e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=85dne=20E=2E=20Moldes=C3=A6ter?= Date: Sat, 22 Aug 2020 22:07:28 +0200 Subject: [PATCH] Added diceroll/modifier grouping --- src/lib.rs | 50 +++++++++++++++++++++++++++++++++++++++++++++++-- src/lib_test.rs | 26 ++++++++++++++++++++++++- 2 files changed, 73 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 8eb3dcd..f0b7a4e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,16 +1,17 @@ use regex::Regex; use thiserror::Error; use anyhow::Result; +use rand::Rng; #[cfg(test)] mod lib_test; -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Clone)] enum DiceFilter { DropLowest(i32), DropHighest(i32), KeepLowest(i32), KeepHighest(i32), } -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Clone)] enum Segment { DiceRoll{ op: char, @@ -87,3 +88,48 @@ fn parse_dice_segments(cmd: &str) -> Result> { regex.captures_iter(cmd).map(construct_dice_segment).collect() } + +#[derive(Debug, PartialEq, Clone)] +struct RollWithModifier { + diceroll: Segment, + modifiers: Vec +} + +fn group_modifiers_to_dicerolls(segments: &[Segment]) -> Vec { + let mut results = Vec::new(); + + let mut current_diceroll : Option = None; + let mut current_modifiers = Vec::new(); + + for segment in segments { + if let Segment::DiceRoll {..} = segment { + if let Option::Some(current) = current_diceroll { + let with_modifier = RollWithModifier { + diceroll: current.clone(), + modifiers: current_modifiers.clone(), + }; + + current_modifiers.clear(); + + results.push(with_modifier); + } + current_diceroll = Some(segment.clone()); + } + else if let Segment::Modifier { .. } = segment { + current_modifiers.push(segment.clone()); + } + } + + if let Option::Some(current) = current_diceroll { + let with_modifier = RollWithModifier { + diceroll: current.clone(), + modifiers: current_modifiers.clone(), + }; + + current_modifiers.clear(); + + results.push(with_modifier); + } + + results +} diff --git a/src/lib_test.rs b/src/lib_test.rs index 326f2a2..a4f150b 100644 --- a/src/lib_test.rs +++ b/src/lib_test.rs @@ -1,7 +1,7 @@ use super::*; #[test] -fn test_roll_dice() { +fn test_parse_dice_segments() { let mut results = parse_dice_segments("2d6").expect("Failed to unpack results"); assert_eq!(results, vec![ Segment::DiceRoll{ op: '+', count: 2, size: 6, filter: None } ]); @@ -34,3 +34,27 @@ fn test_roll_dice() { Segment::Modifier{ op: '/', amount: 2 }, ]); } + +#[test] +fn test_group_modifiers_to_dicerolls() { + let mut segments = parse_dice_segments("2d20 / 2 + 2 + 4d6 * 2 * 2").expect("Failed to unpack results"); + + let mut results = group_modifiers_to_dicerolls(&segments); + + assert_eq!(results, vec![ + RollWithModifier{ + diceroll: Segment::DiceRoll{ op: '+', count: 2, size: 20, filter: None }, + modifiers: vec![ + Segment::Modifier{ op: '/', amount: 2 }, + Segment::Modifier{ op: '+', amount: 2 }, + ] + }, + RollWithModifier{ + diceroll: Segment::DiceRoll{ op: '+', count: 4, size: 6, filter: None }, + modifiers: vec![ + Segment::Modifier{ op: '*', amount: 2 }, + Segment::Modifier{ op: '*', amount: 2 }, + ] + }, + ]); +}