1use terrain_forge::{
6 algorithms::{
7 Bsp, PrefabConfig, PrefabData, PrefabLibrary, PrefabPlacer, Wfc, WfcConfig,
8 WfcPatternExtractor,
9 },
10 analysis::{DelaunayTriangulation, Graph, GraphAnalysis, Point},
11 Algorithm, Grid, Tile,
12};
13
14fn main() {
15 println!("=== Phase 4 Complete Workflow Demo ===\n");
16
17 println!("1. Generating Base Layout:");
19 let mut base_grid = Grid::new(35, 25);
20 let bsp = Bsp::default();
21 bsp.generate(&mut base_grid, 12345);
22
23 let base_floors = base_grid.count(|t| t.is_floor());
24 println!(
25 " Generated {}x{} base layout with {} floors",
26 base_grid.width(),
27 base_grid.height(),
28 base_floors
29 );
30
31 println!("\n2. Learning Patterns from Base Layout:");
33 let learned_patterns = WfcPatternExtractor::extract_patterns(&base_grid, 3);
34 println!(
35 " Extracted {} unique 3x3 patterns",
36 learned_patterns.len()
37 );
38
39 println!("\n3. Generating Enhanced Areas with Learned Patterns:");
41 let mut wfc_grid = Grid::new(20, 15);
42 let wfc = Wfc::new(WfcConfig {
43 floor_weight: 0.45,
44 pattern_size: 3,
45 enable_backtracking: true,
46 });
47 wfc.generate_with_patterns(&mut wfc_grid, learned_patterns.clone(), 54321);
48
49 let wfc_floors = wfc_grid.count(|t| t.is_floor());
50 println!(
51 " WFC generated {} floors with learned patterns",
52 wfc_floors
53 );
54
55 println!("\n4. Analyzing Room Connectivity:");
57 let room_centers = find_room_centers(&base_grid);
58 println!(" Identified {} room centers", room_centers.len());
59
60 println!("\n5. Creating Optimal Room Connections:");
62 if room_centers.len() >= 3 {
63 let triangulation = DelaunayTriangulation::new(room_centers.clone());
64 let mst_edges = triangulation.minimum_spanning_tree();
65
66 println!(" Delaunay triangulation:");
67 println!(" Triangles: {}", triangulation.triangles.len());
68 println!(" All edges: {}", triangulation.edges.len());
69
70 println!(" Minimum spanning tree:");
71 println!(" Optimal edges: {}", mst_edges.len());
72
73 let total_length: f32 = mst_edges
74 .iter()
75 .map(|edge| edge.length(&triangulation.points))
76 .sum();
77 println!(" Total corridor length: {:.1}", total_length);
78
79 let graph = Graph::new(triangulation.points.clone(), mst_edges);
81 let analysis = GraphAnalysis::analyze(&graph);
82
83 println!(" Connectivity analysis:");
84 println!(" Connected: {}", analysis.is_connected);
85 println!(" Diameter: {:.1}", analysis.diameter);
86 println!(" Clustering: {:.3}", analysis.average_clustering);
87 } else {
88 println!(" Not enough rooms for connectivity analysis");
89 }
90
91 println!("\n6. Creating Specialized Prefab Library:");
93 let library = create_specialized_library();
94
95 println!(
96 " Created library with {} prefabs:",
97 library.get_prefabs().len()
98 );
99 for prefab in library.get_prefabs() {
100 println!(
101 " - {} (weight: {:.1}, tags: {:?})",
102 prefab.name, prefab.weight, prefab.tags
103 );
104 }
105
106 println!("\n7. Placing Special Features:");
108 let mut feature_grid = Grid::new(30, 20);
109
110 let boss_config = PrefabConfig {
112 max_prefabs: 1,
113 min_spacing: 8,
114 allow_rotation: false,
115 allow_mirroring: false,
116 weighted_selection: true,
117 };
118
119 let boss_placer = PrefabPlacer::new(boss_config, library.clone());
120 boss_placer.generate(&mut feature_grid, 98765);
121
122 let treasure_config = PrefabConfig {
124 max_prefabs: 2,
125 min_spacing: 5,
126 allow_rotation: true,
127 allow_mirroring: true,
128 weighted_selection: true,
129 };
130
131 let treasure_placer = PrefabPlacer::new(treasure_config, library.clone());
132 treasure_placer.generate(&mut feature_grid, 13579);
133
134 let feature_floors = feature_grid.count(|t| t.is_floor());
135 println!(" Placed special features: {} floor tiles", feature_floors);
136
137 println!("\n8. Performance and Quality Metrics:");
139
140 let start = std::time::Instant::now();
142 let mut perf_grid = Grid::new(25, 20);
143 wfc.generate_with_patterns(&mut perf_grid, learned_patterns.clone(), 24680);
144 let wfc_time = start.elapsed();
145
146 let start = std::time::Instant::now();
148 let placer = PrefabPlacer::new(PrefabConfig::default(), library.clone());
149 let mut prefab_grid = Grid::new(25, 20);
150 placer.generate(&mut prefab_grid, 24680);
151 let prefab_time = start.elapsed();
152
153 let start = std::time::Instant::now();
155 let _ = DelaunayTriangulation::new(room_centers.clone());
156 let delaunay_time = start.elapsed();
157
158 println!(" Performance metrics:");
159 println!(" WFC generation: {:?}", wfc_time);
160 println!(" Prefab placement: {:?}", prefab_time);
161 println!(" Delaunay triangulation: {:?}", delaunay_time);
162
163 println!("\n9. Quality Comparison:");
165
166 let mut basic_grid = Grid::new(25, 20);
168 bsp.generate(&mut basic_grid, 11111);
169 let basic_floors = basic_grid.count(|t| t.is_floor());
170
171 let enhanced_floors = perf_grid.count(|t| t.is_floor()) + prefab_grid.count(|t| t.is_floor());
173
174 println!(" Floor tile comparison:");
175 println!(
176 " Basic BSP: {} floors ({:.1}%)",
177 basic_floors,
178 100.0 * basic_floors as f32 / (25 * 20) as f32
179 );
180 println!(
181 " Enhanced (WFC + Prefabs): {} floors ({:.1}%)",
182 enhanced_floors,
183 100.0 * enhanced_floors as f32 / (50 * 20) as f32
184 );
185
186 println!("\n10. Saving Configuration:");
188 match library.save_to_json("phase4_library.json") {
189 Ok(()) => println!(" ā
Saved prefab library to phase4_library.json"),
190 Err(e) => println!(" ā Failed to save library: {}", e),
191 }
192
193 println!("\nā
Phase 4 complete workflow finished!");
194 println!(" Workflow summary:");
195 println!(" 1. Generated base layout with BSP algorithm");
196 println!(
197 " 2. Learned {} patterns for WFC enhancement",
198 learned_patterns.len()
199 );
200 println!(
201 " 3. Analyzed {} room connections with Delaunay triangulation",
202 room_centers.len()
203 );
204 println!(" 4. Placed specialized features with weighted prefab selection");
205 println!(" 5. Achieved optimal room connectivity with MST");
206 println!(" 6. Demonstrated pattern learning and constraint propagation");
207 println!(" \n Phase 4 features enable:");
208 println!(" - Intelligent pattern-based generation");
209 println!(" - Mathematically optimal room connections");
210 println!(" - Flexible, reusable prefab systems");
211 println!(" - Advanced graph analysis for level design");
212}
213
214fn find_room_centers(grid: &Grid<Tile>) -> Vec<Point> {
215 let mut centers = Vec::new();
216 let mut visited = vec![vec![false; grid.width()]; grid.height()];
217
218 for y in 0..grid.height() {
219 for x in 0..grid.width() {
220 if !visited[y][x] {
221 if let Some(tile) = grid.get(x as i32, y as i32) {
222 if tile.is_floor() {
223 let center = find_room_center(grid, &mut visited, x, y);
224 centers.push(center);
225 }
226 }
227 }
228 }
229 }
230
231 centers
232}
233
234fn find_room_center(
235 grid: &Grid<Tile>,
236 visited: &mut [Vec<bool>],
237 start_x: usize,
238 start_y: usize,
239) -> Point {
240 let mut room_cells = Vec::new();
241 let mut stack = vec![(start_x, start_y)];
242
243 while let Some((x, y)) = stack.pop() {
244 if visited[y][x] {
245 continue;
246 }
247 visited[y][x] = true;
248 room_cells.push((x, y));
249
250 for (dx, dy) in [(-1, 0), (1, 0), (0, -1), (0, 1)] {
251 let nx = x as i32 + dx;
252 let ny = y as i32 + dy;
253
254 if nx >= 0 && ny >= 0 && (nx as usize) < grid.width() && (ny as usize) < grid.height() {
255 let nx = nx as usize;
256 let ny = ny as usize;
257
258 if !visited[ny][nx] {
259 if let Some(tile) = grid.get(nx as i32, ny as i32) {
260 if tile.is_floor() {
261 stack.push((nx, ny));
262 }
263 }
264 }
265 }
266 }
267 }
268
269 let sum_x: usize = room_cells.iter().map(|(x, _)| x).sum();
271 let sum_y: usize = room_cells.iter().map(|(_, y)| y).sum();
272 let count = room_cells.len();
273
274 Point::new(sum_x as f32 / count as f32, sum_y as f32 / count as f32)
275}
276
277fn create_specialized_library() -> PrefabLibrary {
278 let mut library = PrefabLibrary::new();
279
280 let boss_room = PrefabData {
282 name: "boss_chamber".to_string(),
283 width: 9,
284 height: 7,
285 pattern: vec![
286 "#########".to_string(),
287 "#.......#".to_string(),
288 "#..###..#".to_string(),
289 "#..#B#..#".to_string(),
290 "#..###..#".to_string(),
291 "#.......#".to_string(),
292 "#########".to_string(),
293 ],
294 weight: 0.2,
295 tags: vec![
296 "boss".to_string(),
297 "special".to_string(),
298 "large".to_string(),
299 ],
300 };
301 library.add_prefab(terrain_forge::algorithms::Prefab::from_data(boss_room));
302
303 let treasure_room = PrefabData {
305 name: "treasure_vault".to_string(),
306 width: 5,
307 height: 5,
308 pattern: vec![
309 "#####".to_string(),
310 "#...#".to_string(),
311 "#.T.#".to_string(),
312 "#...#".to_string(),
313 "#####".to_string(),
314 ],
315 weight: 0.8,
316 tags: vec![
317 "treasure".to_string(),
318 "special".to_string(),
319 "small".to_string(),
320 ],
321 };
322 library.add_prefab(terrain_forge::algorithms::Prefab::from_data(treasure_room));
323
324 let secret_passage = PrefabData {
326 name: "secret_passage".to_string(),
327 width: 3,
328 height: 7,
329 pattern: vec![
330 "###".to_string(),
331 "#.#".to_string(),
332 "#.#".to_string(),
333 "#.#".to_string(),
334 "#.#".to_string(),
335 "#.#".to_string(),
336 "###".to_string(),
337 ],
338 weight: 1.2,
339 tags: vec!["secret".to_string(), "corridor".to_string()],
340 };
341 library.add_prefab(terrain_forge::algorithms::Prefab::from_data(secret_passage));
342
343 library
344}