4 changed files with 112 additions and 5 deletions
File diff suppressed because one or more lines are too long
@ -0,0 +1,103 @@
|
||||
# DFS: Depth First Search |
||||
import random |
||||
import tkinter as tk |
||||
import json |
||||
import time |
||||
|
||||
class MazeGenerator: |
||||
def __init__(self, width=10, height=10): |
||||
self.width = width * 2 + 1 # Considera le pareti nel calcolo della larghezza |
||||
self.height = height * 2 + 1 # Considera le pareti nel calcolo dell'altezza |
||||
self.generate_maze() |
||||
self.window = tk.Tk() |
||||
self.window.title("Maze") |
||||
self.canvas = tk.Canvas(self.window, width=self.width*10, height=self.height*10) |
||||
self.canvas.pack() |
||||
self.arrival_point = (self.width - 2, self.height - 2) # Aggiorna il punto di arrivo |
||||
self.backtrack = [] |
||||
|
||||
def generate_maze(self): |
||||
# Inizializza il labirinto con muri (True) |
||||
self.maze = [[True for _ in range(self.width)] for _ in range(self.height)] |
||||
|
||||
# Definisci le direzioni (N, S, E, W) |
||||
self.directions = [(-2, 0), (2, 0), (0, -2), (0, 2)] |
||||
|
||||
# Punto di partenza |
||||
start_x, start_y = (1, 1) |
||||
self.maze[start_y][start_x] = False |
||||
self.stack = [(start_x, start_y)] |
||||
|
||||
def stack_iteration(self): |
||||
if not self.stack: # Check if the stack is empty |
||||
return |
||||
|
||||
current_x, current_y = self.stack[-1] |
||||
|
||||
# Function to get the unvisited neighbors |
||||
def get_unvisited_neighbors(x, y): |
||||
time.sleep(0.005) |
||||
neighbors = [] |
||||
if not (self.arrival_point == (x,y)): |
||||
for dx, dy in self.directions: |
||||
nx, ny = x + dx, y + dy |
||||
if 1 <= nx < self.width - 1 and 1 <= ny < self.height - 1 and self.maze[ny][nx]: |
||||
neighbors.append((nx, ny)) |
||||
return neighbors |
||||
|
||||
neighbors = get_unvisited_neighbors(current_x, current_y) |
||||
|
||||
if neighbors: |
||||
# Choose a random unvisited neighbor |
||||
chosen_x, chosen_y = random.choice(neighbors) |
||||
|
||||
# Remove the wall between the current cell and the chosen cell |
||||
self.maze[(current_y + chosen_y) // 2][(current_x + chosen_x) // 2] = False |
||||
|
||||
# Mark the chosen cell as visited |
||||
self.maze[chosen_y][chosen_x] = False |
||||
|
||||
# Push the chosen cell to the stack |
||||
self.stack.append((chosen_x, chosen_y)) |
||||
else: |
||||
# Backtrack if no unvisited neighbors are found |
||||
self.backtrack.append(self.stack.pop()) |
||||
|
||||
def update_maze(self): |
||||
self.stack_iteration() |
||||
self.draw_maze() |
||||
if self.stack: # Continue updating only if there are cells left to visit |
||||
self.window.after(10, self.update_maze) |
||||
else: |
||||
# After the maze is generated, remove some walls randomly |
||||
for _ in range(int((self.width - 1) * (self.height - 1) * 0.1 // 4)): |
||||
x = random.randrange(1, self.width - 1, 2) |
||||
y = random.randrange(1, self.height - 1, 2) |
||||
self.maze[y][x] = False |
||||
self.draw_maze() |
||||
with open('maze.json', 'w') as json_file: |
||||
json.dump(self.maze, json_file) |
||||
|
||||
def draw_maze(self): |
||||
self.canvas.delete("all") |
||||
for i in range(self.height): |
||||
for j in range(self.width): |
||||
color = "black" if self.maze[i][j] else "white" |
||||
# if (i, j) in self.backtrack: |
||||
# color="yellow" |
||||
if (i, j) == self.arrival_point: |
||||
color = "green" # Color the arrival point green |
||||
elif (i, j) == (1 ,1): |
||||
color = "red" # Color the arrival point green |
||||
elif self.stack and (j, i) == self.stack[-1]: |
||||
color = "blue" # Color the current position blue |
||||
self.canvas.create_rectangle(j*10, i*10, (j+1)*10, (i+1)*10, fill=color) |
||||
|
||||
def run(self): |
||||
self.update_maze() |
||||
|
||||
self.window.mainloop() |
||||
|
||||
# Crea e avvia il generatore di labirinti |
||||
generator = MazeGenerator(7, 5) |
||||
generator.run() |
||||
Loading…
Reference in new issue