import tkinter as tk class SquareWindow: def __init__(self): # Configuration: [(parent_number, count), ...] # (None, 11) means draw 11 squares inside square #0 (the main square) # (2, 7) means draw 7 squares inside square #2 self.config = [(None, 3), (1, 66), (2, 23), (55, 7), (98, 5)] # Set window size to 1000x1000 pixels (needed for calculate_squares) self.window_size = 1000 # Calculate squares based on config self.squares = self.calculate_squares() # Create the main window self.root = tk.Tk() self.root.title("Square Window") self.root.geometry(f"{self.window_size}x{self.window_size}") # Create a canvas to draw on self.canvas = tk.Canvas(self.root, width=self.window_size, height=self.window_size, bg="white") self.canvas.pack(fill=tk.BOTH, expand=True) # Property to store square information: {number: (x, y, size, parent_number)} self.square_positions = {} # Draw all squares based on the calculated squares dictionary for number, (x, y, size, parent_number) in self.squares.items(): self.draw_square_at_location(x, y, size, number, parent_number) # Print the square positions dictionary output_content = f"Square positions: {self.square_positions}" print(output_content) # Save the output to print.log file with open("print.log", "w", encoding="utf-8") as f: f.write(output_content) def calculate_squares(self): """ Calculate all squares based on the config. Config format: [(parent_number, count), ...] (None, count) means draw 'count' squares inside the main square (number 0) (number, count) means draw 'count' squares inside square with 'number' """ import math # Initialize the main square (number 0) main_square_size = int(self.window_size * 0.9) # 90% of 1000 = 900 margin = (self.window_size - main_square_size) // 2 # (1000 - 900) / 2 = 50 # Dictionary to store all squares: {number: (x, y, size, parent_number)} squares = {} # Add the main square (number 0) squares[0] = (margin, margin, main_square_size, None) # Track the next available number for new squares next_number = 1 # Process each configuration entry for parent_number, count in self.config: if parent_number is None: # Draw 'count' squares inside the main square (number 0) parent_num = 0 else: parent_num = parent_number # Get the parent square's info if parent_num in squares: parent_x, parent_y, parent_size, _ = squares[parent_num] # Calculate grid size for the child squares n = math.ceil(math.sqrt(count)) # Number of rows/columns needed child_size = (parent_size // n) - 2 # Size of each child square minus padding # Calculate spacing to distribute squares evenly with gaps total_used_space = n * child_size # Total space occupied by squares remaining_space = parent_size - total_used_space # Remaining space for gaps gap = remaining_space // (n + 1) # Gap between squares and margins # Draw 'count' child squares inside the parent square squares_drawn = 0 for i in range(n): # Rows for j in range(n): # Columns if squares_drawn >= count: break # Calculate position for each child square with proper spacing child_x = parent_x + gap + j * (child_size + gap) child_y = parent_y + gap + i * (child_size + gap) # Add the child square to the dictionary squares[next_number] = (child_x, child_y, child_size, parent_num) next_number += 1 squares_drawn += 1 if squares_drawn >= count: break return squares def draw_square_at_location(self, x, y, size, number, parent_number): """ Draw a square at a specific location with a number in the center. Args: x: X coordinate of the top-left corner y: Y coordinate of the top-left corner size: Size of the square (width and height) number: Number to display in the center parent_number: The number of the parent square (None if no parent) """ # Calculate the level of the square (how deep it is in the hierarchy) level = self.get_square_level(number) # Define light colors for different levels (with transparency effect) colors = [ "#E0E0E0", # Level 0 (light gray, main square) "#FFCCCC", # Level 1 (light red) "#CCE5FF", # Level 2 (light blue) "#CCFFCC", # Level 3 (light green) "#E5CCFF", # Level 4 (light purple) "#FFE5CC", # Level 5 (light orange) "#D9CCAA", # Level 6 (light brown) "#FFD9E5", # Level 7 (light pink) "#FFFFCC", # Level 8 (light yellow) "#CCFFFF" # Level 9+ (light cyan) ] # Select color based on level color = colors[level] if level < len(colors) else "gray" # Draw the square with light colored fill (simulating transparency) and darker outline outline_color = color.replace("#", "") # Get hex color without # # Darken the outline color by reducing RGB values if len(outline_color) == 6: # Convert hex to RGB, then darken r = max(0, int(outline_color[0:2], 16) - 60) g = max(0, int(outline_color[2:4], 16) - 60) b = max(0, int(outline_color[4:6], 16) - 60) dark_outline = f"#{r:02x}{g:02x}{b:02x}" else: dark_outline = "black" # fallback self.canvas.create_rectangle(x, y, x + size, y + size, outline=dark_outline, fill=color, width=1) # Add number in the center of the square (ensure it's drawn last so it's not covered) center_x = x + size // 2 center_y = y + size // 2 # Use black text for better contrast against any background self.canvas.create_text(center_x, center_y, text=str(number), fill="black", font=("Arial", 10)) # Record the square's position information self.square_positions[number] = (x, y, size, parent_number) def get_square_level(self, number): """ Calculate the level of a square in the hierarchy. Level 0: Main square (number 0) Level 1: Direct children of main square Level 2: Children of level 1 squares etc. """ if number == 0: return 0 level = 1 # Start at level 1 since we're past the main square current_parent = self.squares[number][3] # Get parent number from (x, y, size, parent_number) while current_parent is not None: level += 1 if current_parent == 0: break current_parent = self.squares[current_parent][3] # Get parent's parent return level def run(self): self.root.mainloop() if __name__ == "__main__": app = SquareWindow() app.run()