From 183e39d9ebfe6e48e5ce666dee36b5347d47f53e Mon Sep 17 00:00:00 2001 From: 简律纯 Date: Fri, 12 Sep 2025 18:06:17 +0800 Subject: feat: add unique modifier to dice calculations and parsing --- src/calculator.rs | 14 +++++++++++++- src/oneroll/grammar.pest | 2 ++ src/parser.rs | 3 +++ src/types.rs | 1 + 4 files changed, 19 insertions(+), 1 deletion(-) (limited to 'src') 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 = 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 } -- cgit v1.2.3-70-g09d2