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
impl Rng
Sourcepub fn new(seed: u64) -> Self
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(®ion.kind).or_insert(0) += 1;
21 }
22
23 for (kind, count) in ®ion_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
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}Additional examples can be found in:
Sourcepub fn range_usize(&mut self, min: usize, max: usize) -> usize
pub fn range_usize(&mut self, min: usize, max: usize) -> usize
Returns a random usize in [min, max).
Sourcepub fn random(&mut self) -> f64
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}Sourcepub fn chance(&mut self, probability: f64) -> bool
pub fn chance(&mut self, probability: f64) -> bool
Returns true with the given probability (0.0–1.0).
Trait Implementations§
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> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more