#!/usr/bin/python3 import pygame from button import Button from rules import pixel import copy import random pygame.init() ## funktionen def get_debug_text(): def text(text, line_counter): debug_text = default_font.render(str(text), True, (255, 255, 255)) screen.blit(debug_text, (0, line_counter * default_font.get_height())) line_counter = 1 globalvars = globals() for a in globalvars: text(f"{str(a)} = {str(globalvars[a])}", line_counter) line_counter += 1 def centered_text(text=str, pos=tuple, color=tuple): text = default_font.render(str(text), True, color, (255, 255, 255)) screen.blit(text, (pos[0] - text.get_width() / 2, pos[1])) def draw_feld(feld, block_size): for a in range(len(feld[0])): for b in range(len(feld)): if feld[b][a]: pygame.draw.rect( screen, (255, 255, 255), (a * block_size, b * block_size, block_size, block_size), ) def finde_nachbarn(x, y): feldx, feldy = len(feld[0]), len(feld) ov = (y - 1) % feldy, x % feldx ovr = (y - 1) % feldy, (x + 1) % feldx ovl = (y - 1) % feldy, (x - 1) % feldx r = y, (x + 1) % feldx l = y, (x - 1) % feldx be = (y + 1) % feldy, x % feldx ber = (y + 1) % feldy, (x + 1) % feldx bel = (y + 1) % feldy, (x - 1) % feldx return [ovl, ov, ovr, r, l, bel, be, ber] ## Funktion zum Verarbeiten des Feldes def verarbeite_feld(feld): feldx, feldy = len(feld[0]), len(feld) # bekomme feld größe feld2 = copy.deepcopy(feld) # mache neue kopie for y in range(feldy): # spalte for x in range(feldx): # zeile lives = 0 for pos in finde_nachbarn(x, y): if feld[pos[0]][pos[1]]: lives += 1 feld2[y][x] = pixel(feld[y][x], str(lives)) return feld2 # gib kopie zurück def make_feld(size, rand): x = screensize[0] // size y = screensize[1] // size if rand: feld = [[random.choice([False, True]) for _ in range(x)] for _ in range(y)] else: feld = [[False for _ in range(x)] for _ in range(y)] return feld, x, y def resize_feld(feld, new_size, fill_with=False): sx = screensize[0] // new_size sy = screensize[1] // new_size old_feld_size = len(feld[0]), len(feld) new_feld = [[" " for _ in range(sx)] for _ in range(sy)] for y in range(len(new_feld)): for x in range(len(new_feld[0])): if x < old_feld_size[0] and y < old_feld_size[1]: new_feld[y][x] = feld[y][x] else: new_feld[y][x] = fill_with return new_feld, sx, sy def setbutton_pos(): global buttons for i, button in enumerate(buttons): i += 1 button.pos = (screensize[0] - 70, button_abstandy * i) ## klassen ## variablen screen = pygame.display.set_mode((800, 500), pygame.RESIZABLE) pygame.display.set_caption("GoL") screensize = pygame.display.get_window_size() clock = pygame.time.Clock() default_font = pygame.font.SysFont("sans", 14) feld, feldx, feldy = make_feld(20, True) pause = False pixelsize = 20 # größe eines pixels button_abstandy = 30 # abstand von buttons buttons = [ Button(screen, (200, 200, 200), (screensize[0] - 70, 50), 25, 25, "\/"), Button(screen, (200, 200, 200), (screensize[0] - 70, 50), 100, 25, "Debug"), Button(screen, (200, 200, 200), (screensize[0] - 70, 50), 100, 25, "Reset"), Button(screen, (200, 200, 200), (screensize[0] - 70, 50), 100, 25, "Zoom"), Button(screen, (200, 200, 200), (screensize[0] - 70, 50), 100, 25, "Pause"), Button(screen, (200, 200, 200), (screensize[0] - 70, 50), 100, 25, "Randomize"), Button(screen, (200, 200, 200), (screensize[0] - 70, 50), 100, 25, "Clear"), ] buttona = { "dropdown": 0, "debug": 1, "reset": 2, "zoom": 3, "pause": 4, "random": 5, "clear": 6, } setbutton_pos() buttonhovered = [False, False, False, False, False, False, False] buttons_to_render = 6 # button begrenzung dropdown = True before_buttonhovered = [False, False, False] key_counter = 0 pressed_keys = pygame.key.get_pressed() show_debug = False running = True if __name__ == "__main__": while running: ## key managment key_counter += 1 if key_counter == 5: key_counter = 0 pressed_keys = pygame.key.get_pressed() if True in pressed_keys: if pressed_keys[pygame.K_ESCAPE]: exit() if ( pressed_keys[pygame.K_PLUS] and not before_pressed_keys[pygame.K_PLUS] ): pixelsize += 2 feld, feldx, feldy = resize_feld(feld, pixelsize) if ( pressed_keys[pygame.K_MINUS] and not before_pressed_keys[pygame.K_MINUS] ): pixelsize -= 2 feld, feldx, feldy = resize_feld(feld, pixelsize) if pressed_keys[pygame.K_d] and not before_pressed_keys[pygame.K_d]: show_debug = not show_debug if ( pressed_keys[pygame.K_SPACE] and not before_pressed_keys[pygame.K_SPACE] ): pause = not pause if pressed_keys[pygame.K_r] and not before_pressed_keys[pygame.K_r]: feld, feldx, feldy = make_feld(pixelsize, False) if ( pressed_keys[pygame.K_RETURN] and not before_pressed_keys[pygame.K_RETURN] ): feld, feldx, feldy = make_feld(pixelsize, True) ## event managment for event in pygame.event.get(): if event.type == pygame.QUIT: exit() if event.type == pygame.WINDOWRESIZED: screensize = pygame.display.get_window_size() feld, feldx, feldy = resize_feld(feld, pixelsize) setbutton_pos() draw_feld(feld, pixelsize) # male feld mit color_key mx, my = pygame.mouse.get_pos() mousepressed = pygame.mouse.get_pressed() for button in buttons[:buttons_to_render]: # male jeden button button.draw() if True in mousepressed: for i, button in enumerate(buttons[:buttons_to_render]): # checke alle button ob die maus auf einen ist und schreibe es in die liste buttonhovered if button.check_hovered((mx, my)): buttonhovered[i] = True else: buttonhovered[i] = False if not True in buttonhovered: # wenn nicht maus über button if mousepressed[0] == True: feld[my // pixelsize][mx // pixelsize] = True else: feld[my // pixelsize][mx // pixelsize] = False if ( mousepressed[0] and not before_mousepressed[0] ): # einmalklick von maus erfassen if buttonhovered[ buttona["dropdown"] ]: # falls button "dropdown" mit index von buttona = True dropdown = not dropdown if dropdown: buttons_to_render = len( buttons ) # dropdown menü begrenzen indem man nicht alle buttons verarbeitet buttons[buttona["dropdown"]].text = "\/" else: buttons_to_render = 1 buttons[buttona["dropdown"]].text = "/\\" if buttonhovered[buttona["debug"]]: show_debug = not show_debug if buttonhovered[buttona["reset"]]: feld, feldx, feldy = make_feld(pixelsize, False) if buttonhovered[buttona["zoom"]]: pixelsize += 2 feld, feldx, feldy = resize_feld( feld, pixelsize, False ) # make_feld(pixelsize,False) if buttonhovered[buttona["clear"]]: feld, feldx, feldy = make_feld(pixelsize, False) if buttonhovered[buttona["random"]]: feld, feldx, feldy = make_feld(pixelsize, True) if buttonhovered[buttona["pause"]]: pause = not pause if mousepressed[2] and not before_mousepressed[2]: if buttonhovered[buttona["zoom"]]: pixelsize -= 2 feld, feldx, feldy = resize_feld( feld, pixelsize, False ) # make_feld(pixelsize,False) before_buttonhovered = ( buttonhovered # bevorige maus und button hover daten erfassen ) before_mousepressed = mousepressed before_pressed_keys = pressed_keys if not pause: feld = verarbeite_feld(feld) # feld neu machen if show_debug: # debug text zeichnen get_debug_text() ## bildschirm aktuallisierung pygame.display.flip() clock.tick(60) screen.fill((0, 0, 0))