Skip to content

Instantly share code, notes, and snippets.

@feelingnothing
Last active December 5, 2020 17:08
Show Gist options
  • Select an option

  • Save feelingnothing/ce80e6804688a3c55d619f9df89859ef to your computer and use it in GitHub Desktop.

Select an option

Save feelingnothing/ce80e6804688a3c55d619f9df89859ef to your computer and use it in GitHub Desktop.
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