class Game: def __init__(self, network, color): self.screen = None self.scale = START_SCALE self.base_x, self.base_y = None, None self.paused = False self.running = False self.clock = None self.network = network self.color_id = color self.colors = COLORS self.color = COLORS[self.color_id] self.c = 0 self.placing_cells_mode = True self.showing_info_mode = False self.eating_mode = False self.w, self.h = None, None self.alive = None self.new_round_info = Note(15, 15, WIDTH - 30, HEIGHT - 30) self.scores = None self.caption = "Life game" self.captions = { "eat": "Eating time", "place_cells": "Placing cells time", "show_info": "" } self.watching_settings = False self.color_picker = ColorPicker(20, 20, WIDTH - 40, HEIGHT - 40, job_on_set=self.set_color) close_btn_icon = "x.png" self.close_color_picker_btn = Button( WIDTH - 70, 30, job_on_click=self.close_color_picker, icon_path_1=close_btn_icon, icon_path_2=close_btn_icon) self.settings_button = Button(20, 20, job_on_click=self.open_settings, icon_path_1="settings44px.png", icon_path_2="settings44px.png") def set_color(self): r = int(self.color_picker.r) g = int(self.color_picker.g) b = int(self.color_picker.b) self.network.send( f"(set_color int:{self.color_id} int:{r} int:{g} int:{b})") self.watching_settings = False def close_color_picker(self): self.watching_settings = False def open_settings(self): self.watching_settings = True def center(self): cell_count_h = HEIGHT // self.scale cell_count_w = WIDTH // self.scale received = self.network.send("(bounding_box )", res=True) min_x, min_y, max_x, max_y = pickle.loads(received) self.base_x = min_x - (cell_count_w - (max_x - min_x + 1)) // 2 self.base_y = min_y - (cell_count_h - (max_y - min_y + 1)) // 2 def start_game(self): pygame.init() self.screen = SCREEN pygame.display.set_caption(f'Game of Life') self.center() self.clock = pygame.time.Clock() self.main() def on_key_down(self, event): if not self.watching_settings: key = event.key if key == K_ESCAPE: self.running = False elif key == K_LEFT: self.base_x -= SCROLL_DELTA elif key == K_RIGHT: self.base_x += SCROLL_DELTA elif key == K_UP: self.base_y -= SCROLL_DELTA elif key == K_DOWN: self.base_y += SCROLL_DELTA elif event.key == K_EQUALS: if self.scale < MAX_SCALE: self.scale += SCALE_DELTA elif event.key == K_MINUS: if self.scale > MIN_SCALE: self.scale -= SCALE_DELTA elif event.unicode == 'c': self.center() def on_mouse_buttondown(self): self.settings_button.update() if self.placing_cells_mode and not self.watching_settings: mouse_x, mouse_y = pygame.mouse.get_pos() x = mouse_x // self.scale + self.base_x y = mouse_y // self.scale + self.base_y data = f"(toggle int:{x} int:{y} int:{self.color_id})" self.network.send(data) if self.watching_settings: self.close_color_picker_btn.update() def set_caption(self, cmd): if self.caption != self.captions[cmd]: self.caption = self.captions[cmd] pygame.display.set_caption(self.caption) def change_mode(self, cmd): if cmd == "show_info": self.showing_info_mode = True self.placing_cells_mode = False self.eating_mode = False elif cmd == "eat": pygame.display.set_caption("eating") self.eating_mode = True self.placing_cells_mode = False self.showing_info_mode = False elif cmd == "place_cells": pygame.display.set_caption("placing") self.placing_cells_mode = True self.showing_info_mode = False self.eating_mode = False def update(self): if not self.watching_settings: self.colors = pickle.loads( self.network.send("(get_colors )", res=True)) cmd = self.network.send(f"(what_now? int:{self.color_id})", res=True).decode() self.set_caption(cmd) self.change_mode(cmd) if self.placing_cells_mode: received = self.network.send("(get_alive )", res=True) self.alive = pickle.loads(received) elif self.eating_mode: received = self.network.send("(advance )", res=True) self.alive = pickle.loads(received) elif self.showing_info_mode: received = self.network.send(f"(get_scores )", res=True) # print(received) self.scores = pickle.loads(received) pygame_events = pygame.event.get(EVENT_TYPES) for event in pygame_events: if self.watching_settings: print("heeeeere") self.color_picker.update(event.type) pygame_event_type = event.type if pygame_event_type == QUIT: pygame.quit() sys.exit() elif pygame_event_type == MOUSEBUTTONDOWN: print("here") self.on_mouse_buttondown() elif pygame_event_type == KEYDOWN: self.on_key_down(event) def draw(self): if self.showing_info_mode: self.draw_cells() self.draw_new_round() elif self.watching_settings: self.color_picker.display(self.screen) self.close_color_picker_btn.display(self.screen) else: self.draw_cells() self.settings_button.display(self.screen) pygame.display.flip() def draw_cells(self): self.screen.fill(WHITE) for x in range(0, WIDTH, self.scale): # draw vertical lines pygame.draw.line(self.screen, BLACK, (x, 0), (x, HEIGHT)) for y in range(0, HEIGHT, self.scale): # draw horizontal lines pygame.draw.line(self.screen, BLACK, (0, y), (WIDTH, y)) for x, y in self.alive: # draw live cells pygame.draw.rect( self.screen, self.colors[self.alive.getitem((y, x))], ((x - self.base_x) * self.scale + GRID_LINE_WIDTH + CELL_MARGIN, (y - self.base_y) * self.scale + GRID_LINE_WIDTH + CELL_MARGIN, self.scale - GRID_LINE_WIDTH - 2 * CELL_MARGIN, self.scale - GRID_LINE_WIDTH - 2 * CELL_MARGIN)) def draw_new_round(self): # print(scores) scoreboard = list(sorted(list(self.scores.items()), key=lambda x: x[1])) lines = [ ("Round ended.", None), ] for color_id, score in scoreboard: lines.append((f" - {score}", color_id)) self.new_round_info.display(self.screen, lines, self.colors) def main(self): while True: self.clock.tick(FPS) self.update() self.draw()