| Crates.io | prd |
| lib.rs | prd |
| version | 0.1.0 |
| created_at | 2026-01-19 07:26:52.428481+00 |
| updated_at | 2026-01-19 07:26:52.428481+00 |
| description | An elegant, type-safe probability distribution library with PRD, dice rolling, and weighted random |
| homepage | |
| repository | https://github.com/daleione/prd |
| max_upload_size | |
| id | 2053935 |
| size | 130,850 |
A type-safe, composable probability distribution library for Rust.
This library provides multiple probability distribution strategies with a unified trait-based interface. It enables fine-grained control over randomness for applications requiring consistent, predictable, or customizable random behavior.
[dependencies]
prd = "0.1.0"
use prd::prelude::*;
// True random: 25% independent probability
let mut dist = TrueRandomDistribution::new(0.25, DefaultRandomSource::new());
if dist.next() {
println!("Triggered!");
}
// PRD: Reduces extreme streaks while maintaining 25% overall
let mut prd = PseudoRandomDistribution::new(0.25, DefaultRandomSource::new());
println!("Current probability: {:.1}%", prd.current_probability() * 100.0);
// Dice: 3d6 with normal distribution
let mut roller = DiceRoller::new(3, 6, DefaultRandomSource::new());
let value = roller.roll(); // 3-18, clusters around 10-11
// Weighted: Custom probability table
let mut table = WeightedTable::new(DefaultRandomSource::new());
table.add_item("Common", 60.0);
table.add_item("Rare", 30.0);
table.add_item("Legendary", 10.0);
let item = table.select();
| Distribution | Use Case | Consistency | Variance |
|---|---|---|---|
| True Random | Simple probability, independent events | Low | High |
| PRD | Critical systems, competitive balance | High | Low |
| Dice (NdS) | Value generation with controllable spread | Medium | Adjustable |
| Weighted | Non-uniform selection, priority systems | N/A | N/A |
cargo run --example demo
This demonstrates all distribution types with statistical comparisons and visualizations.
PRD starts with low probability that increases on each failure, eliminating long unlucky streaks:
let mut prd = PseudoRandomDistribution::new(0.25, rng);
// Attempt 1: 8.5% chance
// Attempt 2: 17.0% chance
// Attempt 3: 25.5% chance
// ...continues increasing until success
// On success: resets to 8.5%
Result: Same long-term probability (25%), but maximum failure streak reduced from 25+ to ~10.
// Basic roll
let mut d6 = DiceRoller::new(3, 6, rng); // 3d6
let damage = d6.roll(); // 3-18, normal distribution
// With modifier
let mut attack = DiceRoller::new(2, 10, rng).with_modifier(5); // 2d10+5
let value = attack.roll(); // 7-25
// From notation
let mut check = DiceRoller::from_notation("1d20", rng)?;
let result = check.roll(); // 1-20, uniform
use prd::utils::DistributionAnalyzer;
let mut analyzer = DistributionAnalyzer::new(dist);
let stats = analyzer.run_simulation(10_000);
println!("Success rate: {:.2}%", stats.success_rate * 100.0);
println!("Max failure streak: {}", stats.max_failure_streak);
MIT