237 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			237 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			Python
		
	
	
	
#!/usr/bin/env python3
 | 
						|
"""
 | 
						|
Dijkstra Demo - Cycles Through Different Path Combinations
 | 
						|
==========================================================
 | 
						|
 | 
						|
Shows paths between different entity pairs, skipping impossible paths.
 | 
						|
"""
 | 
						|
 | 
						|
import mcrfpy
 | 
						|
import sys
 | 
						|
 | 
						|
# High contrast colors
 | 
						|
WALL_COLOR = mcrfpy.Color(40, 20, 20)      # Very dark red/brown
 | 
						|
FLOOR_COLOR = mcrfpy.Color(60, 60, 80)     # Dark blue-gray
 | 
						|
PATH_COLOR = mcrfpy.Color(0, 255, 0)       # Bright green
 | 
						|
START_COLOR = mcrfpy.Color(255, 100, 100)  # Light red
 | 
						|
END_COLOR = mcrfpy.Color(100, 100, 255)    # Light blue
 | 
						|
 | 
						|
# Global state
 | 
						|
grid = None
 | 
						|
entities = []
 | 
						|
current_path_index = 0
 | 
						|
path_combinations = []
 | 
						|
current_path = []
 | 
						|
 | 
						|
def create_map():
 | 
						|
    """Create the map with entities"""
 | 
						|
    global grid, entities
 | 
						|
    
 | 
						|
    mcrfpy.createScene("dijkstra_cycle")
 | 
						|
    
 | 
						|
    # Create grid
 | 
						|
    grid = mcrfpy.Grid(grid_x=14, grid_y=10)
 | 
						|
    grid.fill_color = mcrfpy.Color(0, 0, 0)
 | 
						|
    
 | 
						|
    # Map layout
 | 
						|
    map_layout = [
 | 
						|
        "..............",  # Row 0
 | 
						|
        "..W.....WWWW..",  # Row 1
 | 
						|
        "..W.W...W.EW..",  # Row 2 - Entity 1 at (10,2) is TRAPPED!
 | 
						|
        "..W.....W..W..",  # Row 3
 | 
						|
        "..W...E.WWWW..",  # Row 4 - Entity 2 at (6,4)
 | 
						|
        "E.W...........",  # Row 5 - Entity 3 at (0,5)
 | 
						|
        "..W...........",  # Row 6
 | 
						|
        "..W...........",  # Row 7
 | 
						|
        "..W.WWW.......",  # Row 8
 | 
						|
        "..............",  # Row 9
 | 
						|
    ]
 | 
						|
    
 | 
						|
    # Create the map
 | 
						|
    entity_positions = []
 | 
						|
    for y, row in enumerate(map_layout):
 | 
						|
        for x, char in enumerate(row):
 | 
						|
            cell = grid.at(x, y)
 | 
						|
            
 | 
						|
            if char == 'W':
 | 
						|
                cell.walkable = False
 | 
						|
                cell.color = WALL_COLOR
 | 
						|
            else:
 | 
						|
                cell.walkable = True
 | 
						|
                cell.color = FLOOR_COLOR
 | 
						|
                
 | 
						|
                if char == 'E':
 | 
						|
                    entity_positions.append((x, y))
 | 
						|
    
 | 
						|
    # Create entities
 | 
						|
    entities = []
 | 
						|
    for i, (x, y) in enumerate(entity_positions):
 | 
						|
        entity = mcrfpy.Entity(x, y)
 | 
						|
        entity.sprite_index = 49 + i  # '1', '2', '3'
 | 
						|
        grid.entities.append(entity)
 | 
						|
        entities.append(entity)
 | 
						|
    
 | 
						|
    print("Entities created:")
 | 
						|
    for i, (x, y) in enumerate(entity_positions):
 | 
						|
        print(f"  Entity {i+1} at ({x}, {y})")
 | 
						|
    
 | 
						|
    # Check which entity is trapped
 | 
						|
    print("\nChecking accessibility:")
 | 
						|
    for i, e in enumerate(entities):
 | 
						|
        # Try to path to each other entity
 | 
						|
        can_reach = []
 | 
						|
        for j, other in enumerate(entities):
 | 
						|
            if i != j:
 | 
						|
                path = e.path_to(int(other.x), int(other.y))
 | 
						|
                if path:
 | 
						|
                    can_reach.append(j+1)
 | 
						|
        
 | 
						|
        if not can_reach:
 | 
						|
            print(f"  Entity {i+1} at ({int(e.x)}, {int(e.y)}) is TRAPPED!")
 | 
						|
        else:
 | 
						|
            print(f"  Entity {i+1} can reach entities: {can_reach}")
 | 
						|
    
 | 
						|
    # Generate valid path combinations (excluding trapped entity)
 | 
						|
    global path_combinations
 | 
						|
    path_combinations = []
 | 
						|
    
 | 
						|
    # Only paths between entities 2 and 3 (indices 1 and 2) will work
 | 
						|
    # since entity 1 (index 0) is trapped
 | 
						|
    if len(entities) >= 3:
 | 
						|
        # Entity 2 to Entity 3
 | 
						|
        path = entities[1].path_to(int(entities[2].x), int(entities[2].y))
 | 
						|
        if path:
 | 
						|
            path_combinations.append((1, 2, path))
 | 
						|
        
 | 
						|
        # Entity 3 to Entity 2
 | 
						|
        path = entities[2].path_to(int(entities[1].x), int(entities[1].y))
 | 
						|
        if path:
 | 
						|
            path_combinations.append((2, 1, path))
 | 
						|
    
 | 
						|
    print(f"\nFound {len(path_combinations)} valid paths")
 | 
						|
 | 
						|
def clear_path_colors():
 | 
						|
    """Reset all floor tiles to original color"""
 | 
						|
    global current_path
 | 
						|
    
 | 
						|
    for y in range(grid.grid_y):
 | 
						|
        for x in range(grid.grid_x):
 | 
						|
            cell = grid.at(x, y)
 | 
						|
            if cell.walkable:
 | 
						|
                cell.color = FLOOR_COLOR
 | 
						|
    
 | 
						|
    current_path = []
 | 
						|
 | 
						|
def show_path(index):
 | 
						|
    """Show a specific path combination"""
 | 
						|
    global current_path_index, current_path
 | 
						|
    
 | 
						|
    if not path_combinations:
 | 
						|
        status_text.text = "No valid paths available (Entity 1 is trapped!)"
 | 
						|
        return
 | 
						|
    
 | 
						|
    current_path_index = index % len(path_combinations)
 | 
						|
    from_idx, to_idx, path = path_combinations[current_path_index]
 | 
						|
    
 | 
						|
    # Clear previous path
 | 
						|
    clear_path_colors()
 | 
						|
    
 | 
						|
    # Get entities
 | 
						|
    e_from = entities[from_idx]
 | 
						|
    e_to = entities[to_idx]
 | 
						|
    
 | 
						|
    # Color the path
 | 
						|
    current_path = path
 | 
						|
    if path:
 | 
						|
        # Color start and end
 | 
						|
        grid.at(int(e_from.x), int(e_from.y)).color = START_COLOR
 | 
						|
        grid.at(int(e_to.x), int(e_to.y)).color = END_COLOR
 | 
						|
        
 | 
						|
        # Color intermediate steps
 | 
						|
        for i, (x, y) in enumerate(path):
 | 
						|
            if i > 0 and i < len(path) - 1:
 | 
						|
                grid.at(x, y).color = PATH_COLOR
 | 
						|
    
 | 
						|
    # Update status
 | 
						|
    status_text.text = f"Path {current_path_index + 1}/{len(path_combinations)}: Entity {from_idx+1} → Entity {to_idx+1} ({len(path)} steps)"
 | 
						|
    
 | 
						|
    # Update path display
 | 
						|
    path_display = []
 | 
						|
    for i, (x, y) in enumerate(path[:5]):  # Show first 5 steps
 | 
						|
        path_display.append(f"({x},{y})")
 | 
						|
    if len(path) > 5:
 | 
						|
        path_display.append("...")
 | 
						|
    path_text.text = "Path: " + " → ".join(path_display) if path_display else "Path: None"
 | 
						|
 | 
						|
def handle_keypress(key_str, state):
 | 
						|
    """Handle keyboard input"""
 | 
						|
    global current_path_index
 | 
						|
    if state == "end": return
 | 
						|
    if key_str == "Esc":
 | 
						|
        print("\nExiting...")
 | 
						|
        sys.exit(0)
 | 
						|
    elif key_str == "N" or key_str == "Space":
 | 
						|
        show_path(current_path_index + 1)
 | 
						|
    elif key_str == "P":
 | 
						|
        show_path(current_path_index - 1)
 | 
						|
    elif key_str == "R":
 | 
						|
        show_path(current_path_index)
 | 
						|
 | 
						|
# Create the demo
 | 
						|
print("Dijkstra Path Cycling Demo")
 | 
						|
print("==========================")
 | 
						|
print("Note: Entity 1 is trapped by walls!")
 | 
						|
print()
 | 
						|
 | 
						|
create_map()
 | 
						|
 | 
						|
# Set up UI
 | 
						|
ui = mcrfpy.sceneUI("dijkstra_cycle")
 | 
						|
ui.append(grid)
 | 
						|
 | 
						|
# Scale and position
 | 
						|
grid.size = (560, 400)
 | 
						|
grid.position = (120, 100)
 | 
						|
 | 
						|
# Add title
 | 
						|
title = mcrfpy.Caption("Dijkstra Pathfinding - Cycle Paths", 200, 20)
 | 
						|
title.fill_color = mcrfpy.Color(255, 255, 255)
 | 
						|
ui.append(title)
 | 
						|
 | 
						|
# Add status
 | 
						|
status_text = mcrfpy.Caption("Press SPACE to cycle paths", 120, 60)
 | 
						|
status_text.fill_color = mcrfpy.Color(255, 255, 100)
 | 
						|
ui.append(status_text)
 | 
						|
 | 
						|
# Add path display
 | 
						|
path_text = mcrfpy.Caption("Path: None", 120, 520)
 | 
						|
path_text.fill_color = mcrfpy.Color(200, 200, 200)
 | 
						|
ui.append(path_text)
 | 
						|
 | 
						|
# Add controls
 | 
						|
controls = mcrfpy.Caption("SPACE/N=Next, P=Previous, R=Refresh, Q=Quit", 120, 540)
 | 
						|
controls.fill_color = mcrfpy.Color(150, 150, 150)
 | 
						|
ui.append(controls)
 | 
						|
 | 
						|
# Add legend
 | 
						|
legend = mcrfpy.Caption("Red=Start, Blue=End, Green=Path, Dark=Wall", 120, 560)
 | 
						|
legend.fill_color = mcrfpy.Color(150, 150, 150)
 | 
						|
ui.append(legend)
 | 
						|
 | 
						|
# Show first valid path
 | 
						|
mcrfpy.setScene("dijkstra_cycle")
 | 
						|
mcrfpy.keypressScene(handle_keypress)
 | 
						|
 | 
						|
# Display initial path
 | 
						|
if path_combinations:
 | 
						|
    show_path(0)
 | 
						|
else:
 | 
						|
    status_text.text = "No valid paths! Entity 1 is trapped!"
 | 
						|
 | 
						|
print("\nDemo ready!")
 | 
						|
print("Controls:")
 | 
						|
print("  SPACE or N - Next path")
 | 
						|
print("  P - Previous path")
 | 
						|
print("  R - Refresh current path")
 | 
						|
print("  Q - Quit")
 |