import dash
import dash_html_components as html
import dash_core_components as dcc
from dash.dependencies import Input, Output
import plotly.graph_objects as go
import numpy as np
import random
# Initialize the Dash app
app = dash.Dash(__name__)
# Parameters
maze_size = 20 # Maze size (maze_size x maze_size)
cell_size = 20 # Size of each cell in the maze
interval = 200 # Interval in milliseconds
# Function to generate a maze using depth-first search
def generate_maze(size):
maze = np.zeros((size, size), dtype=bool)
stack = [(0, 0)]
visited = set(stack)
while stack:
x, y = stack[-1]
maze[x, y] = True
neighbors = []
if x > 1 and (x - 2, y) not in visited:
neighbors.append((x - 2, y))
if x < size - 2 and (x + 2, y) not in visited:
neighbors.append((x + 2, y))
if y > 1 and (x, y - 2) not in visited:
neighbors.append((x, y - 2))
if y < size - 2 and (x, y + 2) not in visited:
neighbors.append((x, y + 2))
if neighbors:
nx, ny = random.choice(neighbors)
visited.add((nx, ny))
stack.append((nx, ny))
maze[(x + nx) // 2, (y + ny) // 2] = True
else:
stack.pop()
return maze
# Generate the maze
maze = generate_maze(maze_size)
# Function to create the maze layout
def create_maze_layout(maze):
fig = go.Figure()
for x in range(maze_size):
for y in range(maze_size):
if not maze[x, y]:
fig.add_shape(
type="rect",
x0=x * cell_size,
y0=y * cell_size,
x1=(x + 1) * cell_size,
y1=(y + 1) * cell_size,
line=dict(color="black"),
fillcolor="black"
)
return fig
# Initialize agent positions
agent1_pos = [0, 0]
agent2_pos = [maze_size - 1, maze_size - 1]
# Function to update agent positions
def update_agents(agent1_pos, agent2_pos):
def get_valid_moves(pos):
moves = []
x, y = pos
if x > 0 and maze[x - 1, y]:
moves.append((x - 1, y))
if x < maze_size - 1 and maze[x + 1, y]:
moves.append((x + 1, y))
if y > 0 and maze[x, y - 1]:
moves.append((x, y - 1))
if y < maze_size - 1 and maze[x, y + 1]:
moves.append((x, y + 1))
return moves
def move_agent(agent_pos, target_pos):
valid_moves = get_valid_moves(agent_pos)
if valid_moves:
return min(valid_moves, key=lambda move: np.linalg.norm(np.array(move) - np.array(target_pos)))
return agent_pos
agent1_pos = move_agent(agent1_pos, agent2_pos)
agent2_pos = move_agent(agent2_pos, agent1_pos)
return agent1_pos, agent2_pos
# Define the layout of the Dash app
app.layout = html.Div([
html.H1("AI Agents in a Maze", style={'color': 'white', 'textAlign': 'center'}),
dcc.Graph(id='maze-graph', style={'height': '80vh'}),
dcc.Interval(id='interval-component', interval=interval, n_intervals=0)
], style={'backgroundColor': 'black', 'padding': '20px'})
# Define the callback to update the maze and agent positions
@app.callback(
Output('maze-graph', 'figure'),
[Input('interval-component', 'n_intervals')]
)
def update_maze(n):
global agent1_pos, agent2_pos
# Update agent positions
agent1_pos, agent2_pos = update_agents(agent1_pos, agent2_pos)
# Create maze layout
fig = create_maze_layout(maze)
# Add agent positions
fig.add_trace(go.Scatter(
x=[agent1_pos[0] * cell_size + cell_size / 2],
y=[agent1_pos[1] * cell_size + cell_size / 2],
mode='markers',
marker=dict(size=20, color='red'),
name='Agent 1'
))
fig.add_trace(go.Scatter(
x=[agent2_pos[0] * cell_size + cell_size / 2],
y=[agent2_pos[1] * cell_size + cell_size / 2],
mode='markers',
marker=dict(size=20, color='blue'),
name='Agent 2'
))
fig.update_layout(
xaxis=dict(visible=False, range=[0, maze_size * cell_size]),
yaxis=dict(visible=False, range=[0, maze_size * cell_size], scaleanchor='x'),
paper_bgcolor='black',
plot_bgcolor='black',
margin=dict(l=0, r=0, t=0, b=0),
showlegend=False
)
return fig
# Run the app
if __name__ == '__main__':
app.run_server(debug=True)