Skip to main content

Rng

Struct Rng 

Source
pub struct Rng { /* private fields */ }
Expand description

Seeded RNG wrapper for deterministic generation.

All terrain generation uses this RNG so that identical seeds produce identical output across runs and platforms.

Implementations§

Source§

impl Rng

Source

pub fn new(seed: u64) -> Self

Creates a new RNG from the given seed.

Examples found in repository?
examples/bsp_analysis.rs (line 10)
3fn main() {
4    println!("=== BSP Algorithm Analysis ===\n");
5
6    let mut grid = Grid::new(40, 30);
7    algorithms::get("bsp").unwrap().generate(&mut grid, 12345);
8
9    let extractor = SemanticExtractor::for_rooms();
10    let mut rng = Rng::new(12345);
11    let semantic = extractor.extract(&grid, &mut rng);
12
13    println!("Generated map analysis:");
14    println!("  Floor tiles: {}", grid.count(|t| t.is_floor()));
15    println!("  Total regions: {}", semantic.regions.len());
16
17    println!("\nRegion breakdown:");
18    let mut region_counts = std::collections::HashMap::new();
19    for region in &semantic.regions {
20        *region_counts.entry(&region.kind).or_insert(0) += 1;
21    }
22
23    for (kind, count) in &region_counts {
24        println!("  {}: {}", kind, count);
25    }
26
27    println!("\nMarker breakdown:");
28    let mut marker_counts = std::collections::HashMap::new();
29    for marker in &semantic.markers {
30        *marker_counts.entry(marker.tag()).or_insert(0) += 1;
31    }
32
33    for (tag, count) in &marker_counts {
34        println!("  {}: {}", tag, count);
35    }
36}
More examples
Hide additional examples
examples/phase1_demo.rs (line 23)
16fn demo_hierarchical_markers() {
17    println!("🎯 Demo 1: Hierarchical Marker Types");
18
19    let mut grid = Grid::new(40, 30);
20    algorithms::get("bsp").unwrap().generate(&mut grid, 12345);
21
22    let extractor = SemanticExtractor::for_rooms();
23    let mut rng = Rng::new(12345);
24    let mut semantic = extractor.extract(&grid, &mut rng);
25
26    // Add hierarchical markers manually for demo
27    if let Some(region) = semantic.regions.first() {
28        let (x, y) = region.cells[0];
29
30        // Quest markers
31        semantic.markers.push(Marker::new(
32            x,
33            y,
34            MarkerType::QuestObjective { priority: 1 },
35        ));
36        semantic
37            .markers
38            .push(Marker::new(x + 2, y, MarkerType::QuestStart));
39
40        // Loot markers
41        semantic
42            .markers
43            .push(Marker::new(x, y + 2, MarkerType::LootTier { tier: 3 }));
44        semantic
45            .markers
46            .push(Marker::new(x + 1, y + 2, MarkerType::Treasure));
47
48        // Encounter zones
49        semantic.markers.push(Marker::new(
50            x + 3,
51            y + 1,
52            MarkerType::EncounterZone { difficulty: 5 },
53        ));
54        semantic
55            .markers
56            .push(Marker::new(x + 4, y + 1, MarkerType::BossRoom));
57    }
58
59    // Show marker categories
60    let mut categories = std::collections::HashMap::new();
61    for marker in &semantic.markers {
62        *categories.entry(marker.marker_type.category()).or_insert(0) += 1;
63    }
64
65    for (category, count) in categories {
66        println!("  {} markers: {}", category, count);
67    }
68
69    println!("  Sample markers:");
70    for marker in semantic.markers.iter().take(3) {
71        println!("    {} at ({}, {})", marker.tag(), marker.x, marker.y);
72    }
73    println!();
74}
examples/phase2_demo.rs (line 21)
16fn demo_conditional_pipeline() {
17    println!("🔀 Demo 1: Conditional Pipeline Operations");
18
19    let mut grid = Grid::new(30, 20);
20    let mut context = PipelineContext::new();
21    let mut rng = Rng::new(12345);
22
23    // Create conditional pipeline
24    let mut pipeline = ConditionalPipeline::new();
25
26    // Add algorithm operation
27    pipeline.add_operation(ConditionalOperation::simple(PipelineOperation::Algorithm {
28        name: "bsp".to_string(),
29        seed: Some(12345),
30    }));
31
32    // Add conditional operation based on floor density
33    pipeline.add_operation(ConditionalOperation::conditional(
34        PipelineOperation::Log {
35            message: "Evaluating floor density".to_string(),
36        },
37        PipelineCondition::Density {
38            min: Some(0.2),
39            max: Some(0.6),
40        },
41        vec![ConditionalOperation::simple(
42            PipelineOperation::SetParameter {
43                key: "density_status".to_string(),
44                value: "acceptable".to_string(),
45            },
46        )],
47        vec![ConditionalOperation::simple(
48            PipelineOperation::SetParameter {
49                key: "density_status".to_string(),
50                value: "out_of_range".to_string(),
51            },
52        )],
53    ));
54
55    // Execute pipeline
56    let result = pipeline.execute(&mut grid, &mut context, &mut rng);
57
58    println!(
59        "  Pipeline execution: {}",
60        if result.success {
61            "✅ Success"
62        } else {
63            "❌ Failed"
64        }
65    );
66    if let Some(msg) = result.message {
67        println!("  Message: {}", msg);
68    }
69
70    println!("  Floor tiles: {}", grid.count(|t| t.is_floor()));
71    println!(
72        "  Density status: {}",
73        context
74            .get_parameter("density_status")
75            .unwrap_or(&"unknown".to_string())
76    );
77    println!("  Execution log: {:?}", context.execution_history());
78    println!();
79}
80
81fn demo_pipeline_templates() {
82    println!("📋 Demo 2: Pipeline Templates");
83
84    // Create custom template
85    let template = PipelineTemplate::new("custom_dungeon", "Customizable dungeon template")
86        .with_parameter("algorithm", "cellular")
87        .with_parameter("seed", "54321")
88        .with_parameter("type", "dungeon")
89        .with_operation(ConditionalOperation::simple(PipelineOperation::Algorithm {
90            name: "{algorithm}".to_string(),
91            seed: Some(54321),
92        }))
93        .with_operation(ConditionalOperation::simple(
94            PipelineOperation::SetParameter {
95                key: "generation_type".to_string(),
96                value: "{type}".to_string(),
97            },
98        ));
99
100    // Instantiate with custom parameters
101    let mut custom_params = std::collections::HashMap::new();
102    custom_params.insert("algorithm".to_string(), "bsp".to_string());
103    custom_params.insert("type".to_string(), "fortress".to_string());
104
105    let pipeline = template.instantiate(Some(custom_params));
106
107    let mut grid = Grid::new(25, 25);
108    let mut context = PipelineContext::new();
109    let mut rng = Rng::new(98765);
110
111    let result = pipeline.execute(&mut grid, &mut context, &mut rng);
112
113    println!("  Template: {}", template.name);
114    println!("  Description: {}", template.description);
115    println!(
116        "  Execution: {}",
117        if result.success {
118            "✅ Success"
119        } else {
120            "❌ Failed"
121        }
122    );
123    println!(
124        "  Generation type: {}",
125        context
126            .get_parameter("generation_type")
127            .unwrap_or(&"unknown".to_string())
128    );
129    println!("  Floor tiles: {}", grid.count(|t| t.is_floor()));
130    println!();
131}
132
133fn demo_template_library() {
134    println!("📚 Demo 3: Template Library");
135
136    let library = TemplateLibrary::new();
137
138    println!("  Available templates:");
139    for name in library.template_names() {
140        if let Some(template) = library.get_template(name) {
141            println!("    - {}: {}", name, template.description);
142        }
143    }
144
145    // Use built-in template
146    if let Some(template) = library.get_template("simple_dungeon") {
147        let pipeline = template.instantiate(None);
148
149        let mut grid = Grid::new(40, 30);
150        let mut context = PipelineContext::new();
151        let mut rng = Rng::new(11111);
152
153        let result = pipeline.execute(&mut grid, &mut context, &mut rng);
154
155        println!("\n  Executed 'simple_dungeon' template:");
156        println!(
157            "    Result: {}",
158            if result.success {
159                "✅ Success"
160            } else {
161                "❌ Failed"
162            }
163        );
164        println!("    Floor tiles: {}", grid.count(|t| t.is_floor()));
165        println!("    Steps executed: {}", context.execution_history().len());
166    }
167    println!();
168}
examples/hierarchical_markers.rs (line 11)
3fn main() {
4    println!("=== Hierarchical Marker Types Demo ===\n");
5
6    // Generate a basic dungeon
7    let mut grid = Grid::new(30, 20);
8    algorithms::get("bsp").unwrap().generate(&mut grid, 12345);
9
10    let extractor = SemanticExtractor::for_rooms();
11    let mut rng = Rng::new(12345);
12    let mut semantic = extractor.extract(&grid, &mut rng);
13
14    // Add hierarchical markers
15    if let Some(region) = semantic.regions.first() {
16        let (x, y) = region.cells[0];
17
18        // Quest markers with priorities
19        semantic.markers.push(Marker::new(
20            x,
21            y,
22            MarkerType::QuestObjective { priority: 1 },
23        ));
24        semantic.markers.push(Marker::new(
25            x + 2,
26            y,
27            MarkerType::QuestObjective { priority: 3 },
28        ));
29        semantic
30            .markers
31            .push(Marker::new(x + 4, y, MarkerType::QuestStart));
32
33        // Loot with different tiers
34        semantic
35            .markers
36            .push(Marker::new(x, y + 2, MarkerType::LootTier { tier: 1 }));
37        semantic
38            .markers
39            .push(Marker::new(x + 2, y + 2, MarkerType::LootTier { tier: 3 }));
40        semantic
41            .markers
42            .push(Marker::new(x + 4, y + 2, MarkerType::Treasure));
43
44        // Encounter zones
45        semantic.markers.push(Marker::new(
46            x,
47            y + 4,
48            MarkerType::EncounterZone { difficulty: 2 },
49        ));
50        semantic
51            .markers
52            .push(Marker::new(x + 2, y + 4, MarkerType::BossRoom));
53        semantic
54            .markers
55            .push(Marker::new(x + 4, y + 4, MarkerType::SafeZone));
56    }
57
58    // Show marker categories and types
59    println!("Generated {} markers:", semantic.markers.len());
60    for marker in &semantic.markers {
61        println!(
62            "  {} at ({}, {}) - Category: {}",
63            marker.tag(),
64            marker.x,
65            marker.y,
66            marker.marker_type.category()
67        );
68    }
69
70    // Group by category
71    let mut categories = std::collections::HashMap::new();
72    for marker in &semantic.markers {
73        *categories.entry(marker.marker_type.category()).or_insert(0) += 1;
74    }
75
76    println!("\nMarker distribution:");
77    for (category, count) in categories {
78        println!("  {}: {} markers", category, count);
79    }
80}
examples/conditional_pipelines.rs (line 48)
3fn main() {
4    println!("=== Conditional Pipeline Demo ===\n");
5
6    // Demo 1: Simple conditional pipeline
7    println!("1. Density-Based Conditional Pipeline:");
8
9    let mut pipeline = ConditionalPipeline::new();
10
11    // Generate initial map
12    pipeline.add_operation(ConditionalOperation::simple(PipelineOperation::Algorithm {
13        name: "cellular".to_string(),
14        seed: Some(12345),
15    }));
16
17    // Check density and apply different effects
18    pipeline.add_operation(ConditionalOperation::conditional(
19        PipelineOperation::Log {
20            message: "Checking density".to_string(),
21        },
22        PipelineCondition::Density {
23            min: Some(0.3),
24            max: Some(0.7),
25        },
26        vec![
27            ConditionalOperation::simple(PipelineOperation::SetParameter {
28                key: "quality".to_string(),
29                value: "good".to_string(),
30            }),
31            ConditionalOperation::simple(PipelineOperation::Log {
32                message: "Density is acceptable".to_string(),
33            }),
34        ],
35        vec![
36            ConditionalOperation::simple(PipelineOperation::SetParameter {
37                key: "quality".to_string(),
38                value: "poor".to_string(),
39            }),
40            ConditionalOperation::simple(PipelineOperation::Log {
41                message: "Density needs adjustment".to_string(),
42            }),
43        ],
44    ));
45
46    let mut grid = Grid::new(40, 30);
47    let mut context = PipelineContext::new();
48    let mut rng = Rng::new(12345);
49
50    let result = pipeline.execute(&mut grid, &mut context, &mut rng);
51
52    println!(
53        "  Result: {}",
54        if result.success {
55            "✅ Success"
56        } else {
57            "❌ Failed"
58        }
59    );
60    println!("  Floor tiles: {}", grid.count(|t| t.is_floor()));
61    println!(
62        "  Quality assessment: {}",
63        context
64            .get_parameter("quality")
65            .unwrap_or(&"unknown".to_string())
66    );
67    println!("  Execution steps: {}", context.execution_history().len());
68
69    // Demo 2: Floor count conditional
70    println!("\n2. Floor Count Conditional Pipeline:");
71
72    let mut pipeline2 = ConditionalPipeline::new();
73
74    pipeline2.add_operation(ConditionalOperation::simple(PipelineOperation::Algorithm {
75        name: "bsp".to_string(),
76        seed: Some(54321),
77    }));
78
79    pipeline2.add_operation(ConditionalOperation::conditional(
80        PipelineOperation::Log {
81            message: "Evaluating floor count".to_string(),
82        },
83        PipelineCondition::FloorCount {
84            min: Some(100),
85            max: Some(500),
86        },
87        vec![ConditionalOperation::simple(
88            PipelineOperation::SetParameter {
89                key: "size_category".to_string(),
90                value: "medium".to_string(),
91            },
92        )],
93        vec![ConditionalOperation::simple(
94            PipelineOperation::SetParameter {
95                key: "size_category".to_string(),
96                value: "large_or_small".to_string(),
97            },
98        )],
99    ));
100
101    let mut grid2 = Grid::new(35, 25);
102    let mut context2 = PipelineContext::new();
103    let mut rng2 = Rng::new(54321);
104
105    let result2 = pipeline2.execute(&mut grid2, &mut context2, &mut rng2);
106
107    println!(
108        "  Result: {}",
109        if result2.success {
110            "✅ Success"
111        } else {
112            "❌ Failed"
113        }
114    );
115    println!("  Floor tiles: {}", grid2.count(|t| t.is_floor()));
116    println!(
117        "  Size category: {}",
118        context2
119            .get_parameter("size_category")
120            .unwrap_or(&"unknown".to_string())
121    );
122
123    println!("\n  Execution log:");
124    for (i, step) in context2.execution_history().iter().enumerate() {
125        println!("    {}. {}", i + 1, step);
126    }
127}
examples/pipeline_templates.rs (line 23)
3fn main() {
4    println!("=== Pipeline Templates Demo ===\n");
5
6    // Demo 1: Using built-in templates
7    println!("1. Built-in Template Library:");
8
9    let library = TemplateLibrary::new();
10    println!("  Available templates:");
11    for name in library.template_names() {
12        if let Some(template) = library.get_template(name) {
13            println!("    - {}: {}", name, template.description);
14        }
15    }
16
17    // Use the simple_dungeon template
18    if let Some(template) = library.get_template("simple_dungeon") {
19        let pipeline = template.instantiate(None);
20
21        let mut grid = Grid::new(40, 30);
22        let mut context = PipelineContext::new();
23        let mut rng = Rng::new(11111);
24
25        let result = pipeline.execute(&mut grid, &mut context, &mut rng);
26
27        println!("\n  Executed 'simple_dungeon' template:");
28        println!(
29            "    Result: {}",
30            if result.success {
31                "✅ Success"
32            } else {
33                "❌ Failed"
34            }
35        );
36        println!("    Floor tiles: {}", grid.count(|t| t.is_floor()));
37        println!("    Steps executed: {}", context.execution_history().len());
38    }
39
40    // Demo 2: Custom template with parameters
41    println!("\n2. Custom Parameterized Template:");
42
43    let custom_template = PipelineTemplate::new(
44        "adaptive_dungeon",
45        "Dungeon that adapts based on size parameter",
46    )
47    .with_parameter("size", "medium")
48    .with_parameter("algorithm", "bsp")
49    .with_parameter("complexity", "normal")
50    .with_operation(ConditionalOperation::simple(PipelineOperation::Log {
51        message: "Generating {size} dungeon with {algorithm}".to_string(),
52    }))
53    .with_operation(ConditionalOperation::simple(PipelineOperation::Algorithm {
54        name: "{algorithm}".to_string(),
55        seed: Some(22222),
56    }))
57    .with_operation(ConditionalOperation::simple(
58        PipelineOperation::SetParameter {
59            key: "dungeon_type".to_string(),
60            value: "{size}_{complexity}".to_string(),
61        },
62    ));
63
64    // Instantiate with default parameters
65    println!("  Default parameters:");
66    let pipeline1 = custom_template.instantiate(None);
67    let mut grid1 = Grid::new(30, 20);
68    let mut context1 = PipelineContext::new();
69    let mut rng1 = Rng::new(22222);
70
71    let result1 = pipeline1.execute(&mut grid1, &mut context1, &mut rng1);
72    println!(
73        "    Result: {}",
74        if result1.success {
75            "✅ Success"
76        } else {
77            "❌ Failed"
78        }
79    );
80    println!(
81        "    Dungeon type: {}",
82        context1
83            .get_parameter("dungeon_type")
84            .unwrap_or(&"unknown".to_string())
85    );
86
87    // Instantiate with custom parameters
88    println!("  Custom parameters:");
89    let mut custom_params = std::collections::HashMap::new();
90    custom_params.insert("size".to_string(), "large".to_string());
91    custom_params.insert("algorithm".to_string(), "cellular".to_string());
92    custom_params.insert("complexity".to_string(), "high".to_string());
93
94    let pipeline2 = custom_template.instantiate(Some(custom_params));
95    let mut grid2 = Grid::new(50, 40);
96    let mut context2 = PipelineContext::new();
97    let mut rng2 = Rng::new(33333);
98
99    let result2 = pipeline2.execute(&mut grid2, &mut context2, &mut rng2);
100    println!(
101        "    Result: {}",
102        if result2.success {
103            "✅ Success"
104        } else {
105            "❌ Failed"
106        }
107    );
108    println!(
109        "    Dungeon type: {}",
110        context2
111            .get_parameter("dungeon_type")
112            .unwrap_or(&"unknown".to_string())
113    );
114    println!("    Floor tiles: {}", grid2.count(|t| t.is_floor()));
115
116    // Demo 3: Template with conditional logic
117    println!("\n3. Template with Conditional Logic:");
118
119    let smart_template = PipelineTemplate::new(
120        "smart_generator",
121        "Generator that chooses algorithm based on size",
122    )
123    .with_parameter("width", "40")
124    .with_parameter("height", "30")
125    .with_operation(ConditionalOperation::simple(PipelineOperation::Algorithm {
126        name: "bsp".to_string(),
127        seed: Some(44444),
128    }))
129    .with_operation(ConditionalOperation::conditional(
130        PipelineOperation::Log {
131            message: "Analyzing generated map".to_string(),
132        },
133        PipelineCondition::Density {
134            min: Some(0.2),
135            max: Some(0.6),
136        },
137        vec![ConditionalOperation::simple(
138            PipelineOperation::SetParameter {
139                key: "analysis".to_string(),
140                value: "optimal_density".to_string(),
141            },
142        )],
143        vec![ConditionalOperation::simple(
144            PipelineOperation::SetParameter {
145                key: "analysis".to_string(),
146                value: "suboptimal_density".to_string(),
147            },
148        )],
149    ));
150
151    let pipeline3 = smart_template.instantiate(None);
152    let mut grid3 = Grid::new(40, 30);
153    let mut context3 = PipelineContext::new();
154    let mut rng3 = Rng::new(44444);
155
156    let result3 = pipeline3.execute(&mut grid3, &mut context3, &mut rng3);
157    println!(
158        "  Result: {}",
159        if result3.success {
160            "✅ Success"
161        } else {
162            "❌ Failed"
163        }
164    );
165    println!(
166        "  Analysis: {}",
167        context3
168            .get_parameter("analysis")
169            .unwrap_or(&"unknown".to_string())
170    );
171    println!(
172        "  Density: {:.2}",
173        grid3.count(|t| t.is_floor()) as f32 / (grid3.width() * grid3.height()) as f32
174    );
175}
Source

pub fn range(&mut self, min: i32, max: i32) -> i32

Returns a random i32 in [min, max).

Source

pub fn range_usize(&mut self, min: usize, max: usize) -> usize

Returns a random usize in [min, max).

Source

pub fn random(&mut self) -> f64

Returns a random f64 in [0.0, 1.0).

Examples found in repository?
examples/complete_workflow.rs (line 152)
3fn main() {
4    println!("=== Complete Phase 1 & 2 Feature Demo ===\n");
5
6    // Demo: Complete workflow using all new features
7    println!("🏰 Generating Advanced Multi-Feature Dungeon\n");
8
9    // Step 1: Use pipeline template with custom parameters
10    println!("1. Pipeline Template Generation:");
11    let library = TemplateLibrary::new();
12    let template = library.get_template("simple_dungeon").unwrap();
13
14    let mut custom_params = std::collections::HashMap::new();
15    custom_params.insert("seed".to_string(), "12345".to_string());
16
17    let pipeline = template.instantiate(Some(custom_params));
18
19    let mut grid = Grid::new(40, 30);
20    let mut context = PipelineContext::new();
21    let mut rng = Rng::new(12345);
22
23    let result = pipeline.execute(&mut grid, &mut context, &mut rng);
24    println!(
25        "   Template execution: {}",
26        if result.success {
27            "✅ Success"
28        } else {
29            "❌ Failed"
30        }
31    );
32    println!("   Floor tiles: {}", grid.count(|t| t.is_floor()));
33
34    // Step 2: Extract semantic information
35    println!("\n2. Semantic Analysis:");
36    let extractor = SemanticExtractor::for_rooms();
37    let mut semantic = extractor.extract(&grid, &mut rng);
38
39    println!("   Regions found: {}", semantic.regions.len());
40    println!("   Original markers: {}", semantic.markers.len());
41
42    // Step 3: Add hierarchical markers based on regions
43    println!("\n3. Hierarchical Marker Placement:");
44    let mut quest_count = 0;
45    let mut loot_count = 0;
46    let mut encounter_count = 0;
47
48    for (i, region) in semantic.regions.iter().enumerate() {
49        if !region.cells.is_empty() {
50            let (x, y) = region.cells[region.cells.len() / 2]; // Middle of region
51
52            match i % 3 {
53                0 => {
54                    // Quest area
55                    semantic.markers.push(Marker::new(
56                        x,
57                        y,
58                        MarkerType::QuestObjective {
59                            priority: (i % 3 + 1) as u8,
60                        },
61                    ));
62                    quest_count += 1;
63                }
64                1 => {
65                    // Loot area
66                    semantic.markers.push(Marker::new(
67                        x,
68                        y,
69                        MarkerType::LootTier {
70                            tier: (i % 3 + 1) as u8,
71                        },
72                    ));
73                    loot_count += 1;
74                }
75                2 => {
76                    // Encounter area
77                    if i == 2 {
78                        semantic
79                            .markers
80                            .push(Marker::new(x, y, MarkerType::BossRoom));
81                    } else {
82                        semantic.markers.push(Marker::new(
83                            x,
84                            y,
85                            MarkerType::EncounterZone {
86                                difficulty: (i % 5 + 1) as u8,
87                            },
88                        ));
89                    }
90                    encounter_count += 1;
91                }
92                _ => {}
93            }
94        }
95    }
96
97    println!("   Added {} quest markers", quest_count);
98    println!("   Added {} loot markers", loot_count);
99    println!("   Added {} encounter markers", encounter_count);
100
101    // Step 4: Validate with requirements
102    println!("\n4. Requirement Validation:");
103    let mut requirements = SemanticRequirements::none();
104    requirements.min_regions.insert("Hall".to_string(), 1);
105    requirements
106        .required_markers
107        .insert(MarkerType::Custom("PlayerStart".to_string()), 1);
108
109    let validation_result = requirements.validate(&semantic);
110    println!(
111        "   Requirements met: {}",
112        if validation_result {
113            "✅ Yes"
114        } else {
115            "❌ No"
116        }
117    );
118
119    // Step 5: Marker constraints analysis
120    println!("\n5. Marker Constraint Analysis:");
121    let quest_constraints = MarkerConstraints::quest_objective();
122    let loot_constraints = MarkerConstraints::loot();
123
124    println!("   Quest marker constraints:");
125    println!(
126        "     Min distance (same type): {:?}",
127        quest_constraints.min_distance_same
128    );
129    println!(
130        "     Excluded types: {} types",
131        quest_constraints.exclude_types.len()
132    );
133
134    println!("   Loot marker constraints:");
135    println!(
136        "     Min distance (same type): {:?}",
137        loot_constraints.min_distance_same
138    );
139    println!(
140        "     Min distance (any): {:?}",
141        loot_constraints.min_distance_any
142    );
143
144    // Step 6: Multi-floor connectivity simulation
145    println!("\n6. Multi-Floor Connectivity:");
146
147    // Create a second floor based on the first
148    let mut floor2 = Grid::new(40, 30);
149    // Copy some areas from floor 1 to create overlapping regions
150    for y in 5..25 {
151        for x in 5..35 {
152            if grid.get(x, y).is_some_and(|t| t.is_floor()) && rng.random() < 0.6 {
153                floor2.set(x, y, terrain_forge::Tile::Floor);
154            }
155        }
156    }
157
158    let floors = vec![grid.clone(), floor2];
159    let mut connectivity = VerticalConnectivity::new();
160
161    connectivity.analyze_stair_candidates(&floors, 2);
162    connectivity.place_stairs(3);
163
164    println!("   Floor 1 tiles: {}", floors[0].count(|t| t.is_floor()));
165    println!("   Floor 2 tiles: {}", floors[1].count(|t| t.is_floor()));
166    println!(
167        "   Stair candidates: {}",
168        connectivity.stair_candidates.len()
169    );
170    println!("   Stairs placed: {}", connectivity.stairs.len());
171
172    // Step 7: Final summary
173    println!("\n🎯 Generation Summary:");
174    println!("   Grid size: {}x{}", grid.width(), grid.height());
175    println!("   Total floor area: {}", grid.count(|t| t.is_floor()));
176    println!(
177        "   Density: {:.1}%",
178        (grid.count(|t| t.is_floor()) as f32 / (grid.width() * grid.height()) as f32) * 100.0
179    );
180    println!("   Regions: {}", semantic.regions.len());
181    println!("   Total markers: {}", semantic.markers.len());
182
183    // Group markers by category
184    let mut categories = std::collections::HashMap::new();
185    for marker in &semantic.markers {
186        *categories.entry(marker.marker_type.category()).or_insert(0) += 1;
187    }
188
189    println!("   Marker distribution:");
190    for (category, count) in categories {
191        println!("     {}: {}", category, count);
192    }
193
194    println!(
195        "   Pipeline steps executed: {}",
196        context.execution_history().len()
197    );
198    println!("   Multi-floor stairs: {}", connectivity.stairs.len());
199
200    println!("\n✨ Advanced dungeon generation complete!");
201}
Source

pub fn next_u64(&mut self) -> u64

Returns a random u64.

Source

pub fn chance(&mut self, probability: f64) -> bool

Returns true with the given probability (0.0–1.0).

Source

pub fn pick<'a, T>(&mut self, slice: &'a [T]) -> Option<&'a T>

Picks a random element from the slice, or None if empty.

Source

pub fn shuffle<T>(&mut self, slice: &mut [T])

Shuffles the slice in place (Fisher-Yates).

Trait Implementations§

Source§

impl Clone for Rng

Source§

fn clone(&self) -> Rng

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Rng

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl Freeze for Rng

§

impl RefUnwindSafe for Rng

§

impl Send for Rng

§

impl Sync for Rng

§

impl Unpin for Rng

§

impl UnwindSafe for Rng

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V