diff options
| author | 2025-09-12 18:06:17 +0800 | |
|---|---|---|
| committer | 2025-09-12 18:06:17 +0800 | |
| commit | 183e39d9ebfe6e48e5ce666dee36b5347d47f53e (patch) | |
| tree | 88a512d05a49d805be392a1113054297d3461188 /src | |
| parent | b8fa77736a3c3b9c9d898e7ffa87e057cfab005d (diff) | |
| download | OneRoll-183e39d9ebfe6e48e5ce666dee36b5347d47f53e.tar.gz OneRoll-183e39d9ebfe6e48e5ce666dee36b5347d47f53e.zip | |
feat: add unique modifier to dice calculations and parsing
Diffstat (limited to 'src')
| -rw-r--r-- | src/calculator.rs | 14 | ||||
| -rw-r--r-- | src/oneroll/grammar.pest | 2 | ||||
| -rw-r--r-- | src/parser.rs | 3 | ||||
| -rw-r--r-- | src/types.rs | 1 |
4 files changed, 19 insertions, 1 deletions
diff --git a/src/calculator.rs b/src/calculator.rs index 9611a2b..7289921 100644 --- a/src/calculator.rs +++ b/src/calculator.rs @@ -61,7 +61,7 @@ impl DiceCalculator { rolls.push(final_rolls); } - // handle high/low and discard high/low + // handle high/low, discard high/low and unique deduplication let mut final_rolls = rolls; for modifier in &dice.modifiers { match modifier { @@ -89,6 +89,17 @@ impl DiceCalculator { sorted.sort(); final_rolls = sorted.iter().skip(*n as usize).map(|&v| vec![v]).collect(); } + DiceModifier::Unique => { + use std::collections::HashSet; + let mut seen = HashSet::new(); + let mut uniques: Vec<i32> = Vec::new(); + for v in final_rolls.iter().flatten() { + if seen.insert(*v) { + uniques.push(*v); + } + } + final_rolls = uniques.into_iter().map(|v| vec![v]).collect(); + } _ => {} } } @@ -204,6 +215,7 @@ impl DiceCalculator { DiceModifier::KeepLow(n) => result.push_str(&format!("kl{}", n)), DiceModifier::DropHigh(n) => result.push_str(&format!("dh{}", n)), DiceModifier::DropLow(n) => result.push_str(&format!("dl{}", n)), + DiceModifier::Unique => result.push('u'), } } result diff --git a/src/oneroll/grammar.pest b/src/oneroll/grammar.pest index 01b97e9..27d1c5e 100644 --- a/src/oneroll/grammar.pest +++ b/src/oneroll/grammar.pest @@ -28,6 +28,7 @@ modifier = { | keep_low | drop_high | drop_low + | unique } explode = { "!" } @@ -37,6 +38,7 @@ keep_high = { "kh" ~ number } keep_low = { "kl" ~ number } drop_high = { "dh" ~ number } drop_low = { "dl" ~ number } +unique = { "u" } op = { "+" | "-" | "*" | "/" | "^" } diff --git a/src/parser.rs b/src/parser.rs index 8f4633e..a1800a2 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -140,6 +140,9 @@ impl DiceParser { .map_err(|_| DiceError::ParseError("无效的丢弃低数值".to_string()))?; Ok(DiceModifier::DropLow(num)) } + Rule::unique => { + Ok(DiceModifier::Unique) + } _ => Err(DiceError::ParseError("未知的修饰符".to_string())), } } diff --git a/src/types.rs b/src/types.rs index a88cbab..6f4c54c 100644 --- a/src/types.rs +++ b/src/types.rs @@ -26,6 +26,7 @@ pub enum DiceModifier { KeepLow(i32), // klX DropHigh(i32), // dhX DropLow(i32), // dlX + Unique, // u } |
