Last active
December 5, 2020 17:08
-
-
Save feelingnothing/ce80e6804688a3c55d619f9df89859ef to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from random import choice | |
| from typing import List, Tuple, Optional | |
| import pygame | |
| pygame.init() | |
| WHITE = pygame.Color(255, 255, 255) | |
| GREEN = pygame.Color(0, 255, 0) | |
| RED = pygame.Color(255, 0, 0) | |
| def pointInRect(point, rect): | |
| x1, y1, w, h = rect | |
| x2, y2 = x1 + w, y1 + h | |
| x, y = point | |
| if x1 < x < x2: | |
| if y1 < y < y2: | |
| return True | |
| return False | |
| class Board: | |
| # создание поля | |
| def __init__(self, width: int, height: int): | |
| self.current = True | |
| self.width = width | |
| self.height = height | |
| self.board: List[List[int]] = [[0 for _ in range(width)] for _ in range(height)] | |
| self.left: int = 10 | |
| self.top: int = 10 | |
| self.cell_size: int = 30 | |
| def get_cell(self, pos) -> Optional[Tuple[int, int]]: | |
| for x in range(self.height): | |
| for y in range(self.width): | |
| if pointInRect(pos, (x * self.cell_size + self.left, | |
| y * self.cell_size + self.top, | |
| self.cell_size, self.cell_size)): | |
| return x, y | |
| return None | |
| def get_click(self, mouse_pos): | |
| cell = self.get_cell(mouse_pos) | |
| self.on_click(cell) | |
| def on_click(self, cell: Tuple[int, int]) -> None: | |
| pass | |
| def render(self) -> None: | |
| c = self.cell_size | |
| for x in range(self.height): | |
| for y in range(self.width): | |
| pos = (x * c + self.left, y * c + self.top, c, c) | |
| pygame.draw.rect(screen, WHITE, pos, 1) | |
| # настройка внешнего вида | |
| def set_view(self, left: int, top: int, cell_size: int) -> None: | |
| self.left = left | |
| self.top = top | |
| self.cell_size = cell_size | |
| class Life(Board): | |
| def __init__(self): | |
| super(Life, self).__init__(30, 30) | |
| self.is_drawing = False | |
| def on_click(self, cell: Tuple[int, int]) -> None: | |
| if skip or not cell: | |
| return | |
| x, y = cell | |
| self.board[x][y] = (self.board[x][y] + 1) % 2 | |
| def get_neighbours(self, cell: Tuple[int, int]) -> int: | |
| x, y = cell | |
| c = 0 | |
| for i in range(-1, 2): | |
| for j in range(-1, 2): | |
| if self.board[(x + i) % self.width][(y + j) % self.height] and (i or j): | |
| c += 1 | |
| return c | |
| def get_next_generation(self): | |
| tmp = self.board.copy() | |
| for x in range(self.height): | |
| for y in range(self.width): | |
| alive = self.get_neighbours((x, y)) | |
| if alive: | |
| pos = (x * self.cell_size + self.left, y * self.cell_size + self.top, | |
| self.cell_size, self.cell_size) | |
| pygame.draw.rect(screen, RED, pos) | |
| if self.board[x][y]: | |
| if alive < 2 or alive > 3: | |
| tmp[x][y] = 0 | |
| else: | |
| tmp[x][y] = 1 | |
| else: | |
| if alive == 3: | |
| tmp[x][y] = 1 | |
| self.board[:] = tmp[:] | |
| def render(self) -> None: | |
| super(Life, self).render() | |
| if self.is_drawing: | |
| self.get_next_generation() | |
| for x in range(self.height): | |
| for y in range(self.width): | |
| pos = (x * self.cell_size + self.left, y * self.cell_size + self.top, | |
| self.cell_size, self.cell_size) | |
| if self.board[x][y]: | |
| pygame.draw.rect(screen, GREEN, pos) | |
| board = Life() | |
| board.set_view(10, 10, 16) | |
| screen = pygame.display.set_mode((500, 500)) | |
| running, skip = True, False | |
| clock = pygame.time.Clock() | |
| while running: | |
| for event in pygame.event.get(): | |
| if event.type == pygame.QUIT: | |
| running = False | |
| if event.type == pygame.MOUSEBUTTONDOWN: | |
| board.get_click(event.pos) | |
| if event.type in (pygame.KEYDOWN, pygame.KEYUP): | |
| if event.key == pygame.K_SPACE: | |
| if not skip: | |
| board.is_drawing = not board.is_drawing | |
| skip = not skip | |
| screen.fill((0, 0, 0)) | |
| board.render() | |
| clock.tick(10) | |
| pygame.display.flip() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment