Skip to main content

basic_usage/
basic_usage.rs

1//! Basic usage examples for the dice-nom library.
2//!
3//! This example demonstrates the core functionality of the dice-nom library,
4//! including simple dice rolling, complex expressions, and various operators.
5
6use dice_nom::{parse, roller};
7
8fn main() {
9    let mut rng = rand::rng();
10
11    println!("=== Basic Dice Rolling ===");
12
13    // Simple dice rolls using the roller function
14    let simple_d6 = roller(1, 6, None);
15    let result = simple_d6.generate(&mut rng);
16    println!("1d6: {}", result);
17
18    let multiple_dice = roller(3, 6, None);
19    let result = multiple_dice.generate(&mut rng);
20    println!("3d6: {}", result);
21
22    println!("\n=== Parsing Complex Expressions ===");
23
24    // Parse and roll various dice expressions
25    let expressions = vec![
26        "3d6+4",   // Basic arithmetic
27        "2d8-1",   // Subtraction
28        "1d20+5",  // Common D&D roll
29        "4d6^3",   // Keep highest 3 of 4 dice
30        "2d20ADV", // Advantage (roll twice, keep higher)
31        "2d20DIS", // Disadvantage (roll twice, keep lower)
32    ];
33
34    for expr in expressions {
35        match parse(expr) {
36            Ok(generator) => {
37                let result = generator.generate(&mut rng);
38                println!("{}: {}", expr, result);
39            }
40            Err(_) => println!("Failed to parse: {}", expr),
41        }
42    }
43
44    println!("\n=== Exploding Dice ===");
45
46    // Exploding dice examples
47    let exploding_expressions = vec![
48        "3d6!",   // Explode on max (reroll once if all dice are 6)
49        "2d8!!",  // Explode until (keep rerolling while all dice are max)
50        "4d6*",   // Explode each (reroll each die that's max)
51        "3d10**", // Explode each until (keep rerolling each max die)
52    ];
53
54    for expr in exploding_expressions {
55        if let Ok(generator) = parse(expr) {
56            let result = generator.generate(&mut rng);
57            println!("{}: {}", expr, result);
58        }
59    }
60
61    println!("\n=== Target Numbers and Success Counting ===");
62
63    // Target-based rolling
64    let target_expressions = vec![
65        "6d6[4]",     // Count dice >= 4 as successes
66        "4d10(3)",    // Count dice <= 3 as successes
67        "3d6{12}",    // Success if total >= 12
68        "2d10{15,5}", // 1 success at 15, +1 for every 5 above
69    ];
70
71    for expr in target_expressions {
72        if let Ok(generator) = parse(expr) {
73            let result = generator.generate(&mut rng);
74            println!("{}: {}", expr, result);
75        }
76    }
77
78    println!("\n=== Pool Manipulation ===");
79
80    // Pool operations
81    let pool_expressions = vec![
82        "5d6^3", // Keep highest 3
83        "5d6`2", // Keep lowest 2
84        "6d6~4", // Keep middle 4
85        "5d6Y",  // Keep largest group of matching dice
86    ];
87
88    for expr in pool_expressions {
89        if let Ok(generator) = parse(expr) {
90            let result = generator.generate(&mut rng);
91            println!("{}: {}", expr, result);
92        }
93    }
94
95    println!("\n=== Comparisons ===");
96
97    // Comparison operations
98    let comparison_expressions = vec![
99        "3d6 > 2d8",    // Left vs right comparison
100        "1d20+5 >= 15", // Skill check vs DC
101        "2d6 = 7",      // Exact match
102        "3d6 <=> 3d6",  // Three-way comparison (-1, 0, or 1)
103    ];
104
105    for expr in comparison_expressions {
106        if let Ok(generator) = parse(expr) {
107            let result = generator.generate(&mut rng);
108            println!(
109                "{}: {} ({})",
110                expr,
111                result,
112                if result.sum() == 1 {
113                    "Success"
114                } else if result.sum() == -1 {
115                    "Failure"
116                } else if result.sum() == 0 {
117                    "Tie/False"
118                } else {
119                    "Unknown"
120                }
121            );
122        }
123    }
124
125    println!("\n=== Multiple Rolls ===");
126
127    // Demonstrate multiple rolls of the same expression
128    if let Ok(generator) = parse("3d6") {
129        println!("Rolling 3d6 five times:");
130        for i in 1..=5 {
131            let result = generator.generate(&mut rng);
132            println!("Roll {}: {}", i, result);
133        }
134    }
135
136    println!("\n=== Error Handling ===");
137
138    // Show error handling for invalid expressions
139    let invalid_expressions = vec!["attack the goblin", "3d6 + invalid", "d", ""];
140
141    for expr in invalid_expressions {
142        match parse(expr) {
143            Ok(_) => println!("{}: Parsed successfully (unexpected!)", expr),
144            Err(remaining) => println!("{}: Failed to parse, remaining: '{}'", expr, remaining),
145        }
146    }
147}