"""BSP Traversal Orders Demo Demonstrates: traverse() with different Traversal orders Shows how traversal order affects leaf enumeration. """ import mcrfpy from mcrfpy import automation GRID_WIDTH, GRID_HEIGHT = 64, 48 CELL_SIZE = 16 def run_demo(runtime): panel_w = GRID_WIDTH // 3 panel_h = GRID_HEIGHT // 2 traversal_orders = [ (mcrfpy.Traversal.PRE_ORDER, "PRE_ORDER", "Root first, then children"), (mcrfpy.Traversal.IN_ORDER, "IN_ORDER", "Left, node, right"), (mcrfpy.Traversal.POST_ORDER, "POST_ORDER", "Children before parent"), (mcrfpy.Traversal.LEVEL_ORDER, "LEVEL_ORDER", "Breadth-first by level"), (mcrfpy.Traversal.INVERTED_LEVEL_ORDER, "INV_LEVEL", "Deepest levels first"), ] panels = [ (0, 0), (panel_w, 0), (panel_w * 2, 0), (0, panel_h), (panel_w, panel_h), (panel_w * 2, panel_h) ] # Distinct color palette for 8+ leaves leaf_colors = [ mcrfpy.Color(220, 60, 60), # Red mcrfpy.Color(60, 180, 60), # Green mcrfpy.Color(60, 100, 220), # Blue mcrfpy.Color(220, 180, 40), # Yellow mcrfpy.Color(180, 60, 180), # Magenta mcrfpy.Color(60, 200, 200), # Cyan mcrfpy.Color(220, 120, 60), # Orange mcrfpy.Color(160, 100, 200), # Purple mcrfpy.Color(100, 200, 120), # Mint mcrfpy.Color(200, 100, 140), # Pink ] for panel_idx, (order, name, desc) in enumerate(traversal_orders): if panel_idx >= 6: break ox, oy = panels[panel_idx] # Create BSP for this panel bsp = mcrfpy.BSP(pos=(ox + 2, oy + 4), size=(panel_w - 4, panel_h - 6)) bsp.split_recursive(depth=3, min_size=(5, 4), seed=42) # Fill panel background (dark gray = walls) color_layer.fill_rect((ox, oy), (panel_w, panel_h), mcrfpy.Color(40, 35, 45)) # Traverse and color ONLY LEAVES by their position in traversal leaf_idx = 0 for node in bsp.traverse(order): if not node.is_leaf: continue # Skip branch nodes color = leaf_colors[leaf_idx % len(leaf_colors)] pos = node.pos size = node.size # Shrink by 1 to show walls between rooms for y in range(pos[1] + 1, pos[1] + size[1] - 1): for x in range(pos[0] + 1, pos[0] + size[0] - 1): if 0 <= x < GRID_WIDTH and 0 <= y < GRID_HEIGHT: color_layer.set(((x, y)), color) # Draw leaf index in center cx, cy = node.center() # Draw index as a darker spot if 0 <= cx < GRID_WIDTH and 0 <= cy < GRID_HEIGHT: dark = mcrfpy.Color(color.r // 2, color.g // 2, color.b // 2) color_layer.set(((cx, cy)), dark) if cx + 1 < GRID_WIDTH: color_layer.set(((cx + 1, cy)), dark) leaf_idx += 1 # Add labels label = mcrfpy.Caption(text=f"{name}", pos=(ox * CELL_SIZE + 5, oy * CELL_SIZE + 5)) label.fill_color = mcrfpy.Color(255, 255, 255) label.outline = 1 label.outline_color = mcrfpy.Color(0, 0, 0) scene.children.append(label) desc_label = mcrfpy.Caption(text=f"{desc} ({leaf_idx} leaves)", pos=(ox * CELL_SIZE + 5, oy * CELL_SIZE + 22)) desc_label.fill_color = mcrfpy.Color(200, 200, 200) desc_label.outline = 1 desc_label.outline_color = mcrfpy.Color(0, 0, 0) scene.children.append(desc_label) # Panel 6: Show tree depth levels (branch AND leaf nodes) ox, oy = panels[5] bsp = mcrfpy.BSP(pos=(ox + 2, oy + 4), size=(panel_w - 4, panel_h - 6)) bsp.split_recursive(depth=3, min_size=(5, 4), seed=42) color_layer.fill_rect((ox, oy), (panel_w, panel_h), mcrfpy.Color(40, 35, 45)) # Draw by level - deepest first so leaves are on top level_colors = [ mcrfpy.Color(60, 40, 40), # Level 0 (root) - dark mcrfpy.Color(80, 60, 50), # Level 1 mcrfpy.Color(100, 80, 60), # Level 2 mcrfpy.Color(140, 120, 80), # Level 3 (leaves usually) ] # Use INVERTED_LEVEL_ORDER so leaves are drawn last for node in bsp.traverse(mcrfpy.Traversal.INVERTED_LEVEL_ORDER): level = node.level color = level_colors[min(level, len(level_colors) - 1)] # Make leaves brighter if node.is_leaf: color = mcrfpy.Color( min(255, color.r + 80), min(255, color.g + 80), min(255, color.b + 60) ) pos = node.pos size = node.size for y in range(pos[1], pos[1] + size[1]): for x in range(pos[0], pos[0] + size[0]): if 0 <= x < GRID_WIDTH and 0 <= y < GRID_HEIGHT: # Draw border if x == pos[0] or x == pos[0] + size[0] - 1 or \ y == pos[1] or y == pos[1] + size[1] - 1: border = mcrfpy.Color(20, 20, 30) color_layer.set(((x, y)), border) else: color_layer.set(((x, y)), color) label = mcrfpy.Caption(text="BY LEVEL (depth)", pos=(ox * CELL_SIZE + 5, oy * CELL_SIZE + 5)) label.fill_color = mcrfpy.Color(255, 255, 255) label.outline = 1 label.outline_color = mcrfpy.Color(0, 0, 0) scene.children.append(label) desc_label = mcrfpy.Caption(text="Darker=root, Bright=leaves", pos=(ox * CELL_SIZE + 5, oy * CELL_SIZE + 22)) desc_label.fill_color = mcrfpy.Color(200, 200, 200) desc_label.outline = 1 desc_label.outline_color = mcrfpy.Color(0, 0, 0) scene.children.append(desc_label) # Grid lines for y in range(GRID_HEIGHT): color_layer.set(((panel_w - 1, y)), mcrfpy.Color(60, 60, 60)) color_layer.set(((panel_w * 2 - 1, y)), mcrfpy.Color(60, 60, 60)) for x in range(GRID_WIDTH): color_layer.set(((x, panel_h - 1)), mcrfpy.Color(60, 60, 60)) # Setup scene = mcrfpy.Scene("bsp_traversal_demo") grid = mcrfpy.Grid( grid_size=(GRID_WIDTH, GRID_HEIGHT), pos=(0, 0), size=(GRID_WIDTH * CELL_SIZE, GRID_HEIGHT * CELL_SIZE), layers={} ) grid.fill_color = mcrfpy.Color(0, 0, 0) color_layer = grid.add_layer("color", z_index=-1) scene.children.append(grid) scene.activate() # Run the demo run_demo(0) # Take screenshot automation.screenshot("procgen_11_bsp_traversal.png") print("Screenshot saved: procgen_11_bsp_traversal.png")