#!/usr/bin/python3 import pygame import threading RESOLUTION = 8 FPS = 60 pygame.init() screen = pygame.display.set_mode((1600, 900), flags=pygame.RESIZABLE) white = (240, 240, 240) red = (200, 40, 40) gray = (40, 40, 40) sponge = None sponge_step = 0 sponge_last_step = (RESOLUTION - 1) * 3 * 3 clock = pygame.time.Clock() sponge_surface = pygame.Surface((3**RESOLUTION, 3**RESOLUTION)) sponge_surface.fill(gray) font = pygame.font.Font(pygame.font.get_default_font(), 32) class SimpleArray: def __init__(self, size: tuple, fill=None): self.size = size self.width, self.height = size self.fill = fill self.array = [] self.empty_array = [] self.create_array() def __str__(self): array_string = "" for y in self.array: for x in y: array_string += str(x) array_string += "\n" return array_string def create_array(self): for y in range(self.height): array = [] for x in range(self.width): array.append(self.fill) self.array.append(array) self.empty_array = self.array def set(self, pos: tuple, value): x, y = pos self.array[y - 1][x - 1] = value def set_all(self, array: list): self.array = array def merge(self, pos: tuple, array): width, height = array.size offset_x, offset_y = pos for y in range(height): for x in range(width): self.set((x + offset_x + 1, y + offset_y + 1), array.get((x + 1, y + 1))) def get(self, pos: tuple): x, y = pos return self.array[y - 1][x - 1] def get_all(self): return self.array def reset(self): self.array = self.empty_array def generate_sponge(): global sponge global sponge_step pattern = SimpleArray((1, 1), fill=1) for pattern_number in range(2, RESOLUTION + 1): if not running: return old_size = pattern.height new_size = old_size * 3 new_pattern = SimpleArray((new_size, new_size), fill=0) for y in range(1, 4): for x in range(1, 4): if not x == 2 or not y == 2: new_pattern.merge((x * old_size - old_size, y * old_size - old_size), pattern) sponge_step += 1 pattern = new_pattern sponge = pattern draw_sponge() def draw_sponge(): global sponge_step sponge_surface.fill(gray) for y in range(3**(RESOLUTION - 1)): for x in range(3**(RESOLUTION - 1)): if sponge.get((x + 1, y + 1)) == 1: sponge_surface.set_at((x, y), white) def update(): screen.fill(gray) screen.blit(sponge_surface, (0, 0)) calculate_progress() check_events() if not running: return pygame.display.update() def calculate_progress(): if not sponge_step == sponge_last_step: percent = 100 / sponge_last_step step_percent = round(percent * sponge_step) loading_text = font.render("Loading: " + str(step_percent) + "%", True, red) x, y = screen.get_size() tx, ty = loading_text.get_size() screen.blit(loading_text, (x / 2 - tx / 2, y / 2 - ty / 2)) def check_events(): for event in pygame.event.get(): if event.type == pygame.QUIT: close() def close(): global running running = False running = True threading.Thread(target=generate_sponge).start() while running: update() clock.tick(FPS) pygame.quit() print("Exit.")