diff --git a/assets/graphics/connected_lines/corner/left_bottom.png b/assets/graphics/connected_lines/corner/left_bottom.png deleted file mode 100644 index 6bfef33..0000000 Binary files a/assets/graphics/connected_lines/corner/left_bottom.png and /dev/null differ diff --git a/assets/graphics/connected_lines/corner/left_top.png b/assets/graphics/connected_lines/corner/left_top.png deleted file mode 100644 index 1be071b..0000000 Binary files a/assets/graphics/connected_lines/corner/left_top.png and /dev/null differ diff --git a/assets/graphics/connected_lines/corner/right_bottom.png b/assets/graphics/connected_lines/corner/right_bottom.png deleted file mode 100644 index 322b432..0000000 Binary files a/assets/graphics/connected_lines/corner/right_bottom.png and /dev/null differ diff --git a/assets/graphics/connected_lines/corner/right_top.png b/assets/graphics/connected_lines/corner/right_top.png deleted file mode 100644 index a2ded3f..0000000 Binary files a/assets/graphics/connected_lines/corner/right_top.png and /dev/null differ diff --git a/assets/graphics/power_source.png b/assets/graphics/power_source.png new file mode 100644 index 0000000..c41f0ff Binary files /dev/null and b/assets/graphics/power_source.png differ diff --git a/assets/graphics/powered_lines/corner/left_bottom.png b/assets/graphics/powered_lines/corner/left_bottom.png new file mode 100644 index 0000000..1b4df80 Binary files /dev/null and b/assets/graphics/powered_lines/corner/left_bottom.png differ diff --git a/assets/graphics/powered_lines/corner/left_top.png b/assets/graphics/powered_lines/corner/left_top.png new file mode 100644 index 0000000..047b947 Binary files /dev/null and b/assets/graphics/powered_lines/corner/left_top.png differ diff --git a/assets/graphics/powered_lines/corner/right_bottom.png b/assets/graphics/powered_lines/corner/right_bottom.png new file mode 100644 index 0000000..5339967 Binary files /dev/null and b/assets/graphics/powered_lines/corner/right_bottom.png differ diff --git a/assets/graphics/powered_lines/corner/right_top.png b/assets/graphics/powered_lines/corner/right_top.png new file mode 100644 index 0000000..efcda30 Binary files /dev/null and b/assets/graphics/powered_lines/corner/right_top.png differ diff --git a/assets/graphics/connected_lines/line/horizontal.png b/assets/graphics/powered_lines/line/horizontal.png similarity index 100% rename from assets/graphics/connected_lines/line/horizontal.png rename to assets/graphics/powered_lines/line/horizontal.png diff --git a/assets/graphics/connected_lines/line/vertical.png b/assets/graphics/powered_lines/line/vertical.png similarity index 100% rename from assets/graphics/connected_lines/line/vertical.png rename to assets/graphics/powered_lines/line/vertical.png diff --git a/assets/graphics/unconnected_lines/corner/left_bottom.png b/assets/graphics/unconnected_lines/corner/left_bottom.png deleted file mode 100644 index b3734ce..0000000 Binary files a/assets/graphics/unconnected_lines/corner/left_bottom.png and /dev/null differ diff --git a/assets/graphics/unconnected_lines/corner/left_top.png b/assets/graphics/unconnected_lines/corner/left_top.png deleted file mode 100644 index 37147ed..0000000 Binary files a/assets/graphics/unconnected_lines/corner/left_top.png and /dev/null differ diff --git a/assets/graphics/unconnected_lines/corner/right_bottom.png b/assets/graphics/unconnected_lines/corner/right_bottom.png deleted file mode 100644 index 34f7fc3..0000000 Binary files a/assets/graphics/unconnected_lines/corner/right_bottom.png and /dev/null differ diff --git a/assets/graphics/unconnected_lines/corner/right_top.png b/assets/graphics/unconnected_lines/corner/right_top.png deleted file mode 100644 index 71d9c12..0000000 Binary files a/assets/graphics/unconnected_lines/corner/right_top.png and /dev/null differ diff --git a/assets/graphics/unpowered_lines/corner/left_bottom.png b/assets/graphics/unpowered_lines/corner/left_bottom.png new file mode 100644 index 0000000..7e01c78 Binary files /dev/null and b/assets/graphics/unpowered_lines/corner/left_bottom.png differ diff --git a/assets/graphics/unpowered_lines/corner/left_top.png b/assets/graphics/unpowered_lines/corner/left_top.png new file mode 100644 index 0000000..419c5f3 Binary files /dev/null and b/assets/graphics/unpowered_lines/corner/left_top.png differ diff --git a/assets/graphics/unpowered_lines/corner/right_bottom.png b/assets/graphics/unpowered_lines/corner/right_bottom.png new file mode 100644 index 0000000..cc058a0 Binary files /dev/null and b/assets/graphics/unpowered_lines/corner/right_bottom.png differ diff --git a/assets/graphics/unpowered_lines/corner/right_top.png b/assets/graphics/unpowered_lines/corner/right_top.png new file mode 100644 index 0000000..7c09a07 Binary files /dev/null and b/assets/graphics/unpowered_lines/corner/right_top.png differ diff --git a/assets/graphics/unconnected_lines/line/horizontal.png b/assets/graphics/unpowered_lines/line/horizontal.png similarity index 100% rename from assets/graphics/unconnected_lines/line/horizontal.png rename to assets/graphics/unpowered_lines/line/horizontal.png diff --git a/assets/graphics/unconnected_lines/line/vertical.png b/assets/graphics/unpowered_lines/line/vertical.png similarity index 100% rename from assets/graphics/unconnected_lines/line/vertical.png rename to assets/graphics/unpowered_lines/line/vertical.png diff --git a/game/play.py b/game/play.py index da3dd6c..5543ca3 100644 --- a/game/play.py +++ b/game/play.py @@ -3,6 +3,8 @@ import arcade, arcade.gui, random from utils.constants import button_style from utils.preload import button_texture, button_hovered_texture +from collections import deque + from game.power_line import PowerLine class Game(arcade.gui.UIView): @@ -14,6 +16,7 @@ class Game(arcade.gui.UIView): self.difficulty = difficulty self.power_lines = [] + self.power_sources = [] self.anchor = self.add_widget(arcade.gui.UIAnchorLayout(size_hint=(1, 1))) self.grid_size = list(map(int, difficulty.split("x"))) @@ -29,17 +32,51 @@ class Game(arcade.gui.UIView): for row in range(self.grid_size[0]): self.power_lines.append([]) for col in range(self.grid_size[1]): - left_neighbor = self.power_lines[row][col - 1] if col > 0 else None - top_neighbor = self.power_lines[row - 1][col] if row > 0 else None + left_neighbour = self.power_lines[row][col - 1] if col > 0 else None + top_neighbour = self.power_lines[row - 1][col] if row > 0 else None + + line_type = random.choice(["line", "corner", "power_source"]) + power_line = PowerLine(line_type, left_neighbour, top_neighbour) + + if line_type == "power_source": + self.power_sources.append(power_line) - power_line = PowerLine(random.choice(["line", "corner"]), left_neighbor, top_neighbor) self.power_grid.add(power_line, row=row, column=col) self.power_lines[row].append(power_line) - if left_neighbor: - left_neighbor.right_neighbor = power_line - if top_neighbor: - top_neighbor.bottom_neighbor = power_line + if left_neighbour: + left_neighbour.right_neighbour = power_line + if top_neighbour: + top_neighbour.bottom_neighbour = power_line + + arcade.schedule(self.update_grid, 1 / 10) + + def update_grid(self, _): + for row in self.power_lines: + for power_line in row: + if power_line.line_type != "power_source": + power_line.powered = False + + queue = deque(self.power_sources) + visited = set() + + while queue: + current = queue.popleft() + + if id(current) in visited: + continue + + visited.add(id(current)) + + current.powered = True + + for connected_neighbour in current.get_connected_neighbours(): + if id(connected_neighbour) not in visited: + queue.append(connected_neighbour) + + for row in self.power_lines: + for power_line in row: + power_line.update_visual() def main_exit(self): from menus.main import Main diff --git a/game/power_line.py b/game/power_line.py index 963a9d1..d7ac242 100644 --- a/game/power_line.py +++ b/game/power_line.py @@ -3,79 +3,101 @@ import arcade, arcade.gui from utils.preload import * TEXTURE_MAP = { - ("vertical", True): vertical_connected, - ("vertical", False): vertical_unconnected, + ("line", "vertical", True): vertical_powered, + ("line", "vertical", False): vertical_unpowered, - ("horizontal", True): horizontal_connected, - ("horizontal", False): horizontal_unconnected, + ("line", "horizontal", True): horizontal_powered, + ("line", "horizontal", False): horizontal_unpowered, - ("left_bottom", True): left_bottom_connected, - ("left_bottom", False): left_bottom_unconnected, + ("corner", "left_bottom", True): left_bottom_powered, + ("corner", "left_bottom", False): left_bottom_unpowered, - ("left_top", True): left_top_connected, - ("left_top", False): left_top_unconnected, + ("corner", "left_top", True): left_top_powered, + ("corner", "left_top", False): left_top_unpowered, - ("right_bottom", True): right_bottom_connected, - ("right_bottom", False): right_bottom_unconnected, + ("corner", "right_bottom", True): right_bottom_powered, + ("corner", "right_bottom", False): right_bottom_unpowered, - ("right_top", True): right_top_connected, - ("right_top", False): right_top_unconnected, + ("corner", "right_top", True): right_top_powered, + ("corner", "right_top", False): right_top_unpowered, + + ("power_source", "all", True): power_source, } ROTATIONS = { "line": ["vertical", "horizontal"], - "corner": ["left_top", "right_top", "right_bottom", "left_bottom"] + "corner": ["right_bottom", "left_bottom", "left_top", "right_top"], + "power_source": ["all"] } NEIGHBOURS = { - "vertical": lambda l, r, t, b: bool((b and b.connected) or (t and t.connected)), - "horizontal": lambda l, r, t, b: bool((l and l.connected) or (r and r.connected)), - "left_bottom": lambda l, r, t, b: bool(((l and l.connected) or (b and b.connected))), - "right_bottom": lambda l, r, t, b: bool(((r and r.connected) or (b and b.connected))), - "left_top": lambda l, r, t, b: bool(((l and l.connected) or (t and t.connected))), - "right_top": lambda l, r, t, b: bool(((r and r.connected) or (t and t.connected))) + "vertical": ["b", "t"], + "horizontal": ["l", "r"], + "left_bottom": ["l", "b"], + "right_bottom": ["r", "b"], + "left_top": ["l", "t"], + "right_top": ["r", "t"], + "all": ["l", "r", "t", "b"] } +def get_opposite(direction): + if direction == "l": + return "r" + elif direction == "r": + return "l" + elif direction == "t": + return "b" + elif direction == "b": + return "t" + class PowerLine(arcade.gui.UITextureButton): - def __init__(self, line_type, left_neighbor, top_neighbour): - super().__init__(texture=TEXTURE_MAP[ROTATIONS[line_type][0], False]) + def __init__(self, line_type, left_neighbour, top_neighbour): + super().__init__(texture=TEXTURE_MAP[line_type, ROTATIONS[line_type][0], line_type == "power_source"]) self.line_type = line_type self.rotation = ROTATIONS[line_type][0] - self.connected = False + self.powered = self.line_type == "power_source" - self.left_neighbour, self.top_neighbour = left_neighbor, top_neighbour + self.left_neighbour, self.top_neighbour = left_neighbour, top_neighbour self.right_neighbour, self.bottom_neighbour = None, None self.on_click = lambda e: self.next_rotation() - self.update() + self.update_visual() def next_rotation(self): current_index = ROTATIONS[self.line_type].index(self.rotation) - if current_index + 1 == len(ROTATIONS[self.line_type]) - 1: + if current_index + 1 == len(ROTATIONS[self.line_type]): self.rotation = ROTATIONS[self.line_type][0] else: self.rotation = ROTATIONS[self.line_type][current_index + 1] - self.update() + self.update_visual() - def update_neighbours(self): - if self.rotation == "horizontal": - self.left_neighbour.update() if self.left_neighbour else None - self.right_neighbour.update() if self.right_neighbour else None - elif self.rotation == "vertical": - self.top_neighbour.update() if self.top_neighbour else None - self.bottom_neighbour.update() if self.bottom_neighbour else None + def get_neighbour(self, name): + if name == "l": + return self.left_neighbour + elif name == "r": + return self.right_neighbour + elif name == "b": + return self.bottom_neighbour + elif name == "t": + return self.top_neighbour - def update(self): - if not self.connected: - old_connected = self.connected - self.connected = NEIGHBOURS[self.rotation](self.left_neighbour, self.right_neighbour, self.top_neighbour, self.bottom_neighbour) - if self.connected != old_connected: - self.update_neighbours() + def get_connected_neighbours(self): + return [ + self.get_neighbour(neighbour_direction) for neighbour_direction in NEIGHBOURS[self.rotation] + if ( + self.get_neighbour(neighbour_direction) and + get_opposite(neighbour_direction) in NEIGHBOURS[self.get_neighbour(neighbour_direction).rotation] + ) + ] - self.texture = TEXTURE_MAP[(self.rotation, self.connected)] - self.texture_hovered = TEXTURE_MAP[(self.rotation, self.connected)] + def update_value(self): + self.powered = any([neighbour.powered for neighbour in self.get_connected_neighbours()]) + + def update_visual(self): + self.texture = TEXTURE_MAP[(self.line_type, self.rotation, self.powered)] + self.texture_hovered = TEXTURE_MAP[(self.line_type, self.rotation, self.powered)] self._requires_render = True \ No newline at end of file diff --git a/utils/preload.py b/utils/preload.py index 77487cd..43fe057 100644 --- a/utils/preload.py +++ b/utils/preload.py @@ -3,16 +3,18 @@ import arcade.gui, arcade button_texture = arcade.gui.NinePatchTexture(64 // 4, 64 // 4, 64 // 4, 64 // 4, arcade.load_texture("assets/graphics/button.png")) button_hovered_texture = arcade.gui.NinePatchTexture(64 // 4, 64 // 4, 64 // 4, 64 // 4, arcade.load_texture("assets/graphics/button_hovered.png")) -vertical_connected = arcade.load_texture("assets/graphics/connected_lines/line/vertical.png") -horizontal_connected = arcade.load_texture("assets/graphics/connected_lines/line/horizontal.png") -left_bottom_connected = arcade.load_texture("assets/graphics/connected_lines/corner/left_bottom.png") -left_top_connected = arcade.load_texture("assets/graphics/connected_lines/corner/left_top.png") -right_bottom_connected = arcade.load_texture("assets/graphics/connected_lines/corner/right_bottom.png") -right_top_connected = arcade.load_texture("assets/graphics/connected_lines/corner/right_top.png") +vertical_powered = arcade.load_texture("assets/graphics/powered_lines/line/vertical.png") +horizontal_powered = arcade.load_texture("assets/graphics/powered_lines/line/horizontal.png") +left_bottom_powered = arcade.load_texture("assets/graphics/powered_lines/corner/left_bottom.png") +left_top_powered = arcade.load_texture("assets/graphics/powered_lines/corner/left_top.png") +right_bottom_powered = arcade.load_texture("assets/graphics/powered_lines/corner/right_bottom.png") +right_top_powered = arcade.load_texture("assets/graphics/powered_lines/corner/right_top.png") -vertical_unconnected = arcade.load_texture("assets/graphics/unconnected_lines/line/vertical.png") -horizontal_unconnected = arcade.load_texture("assets/graphics/unconnected_lines/line/horizontal.png") -left_bottom_unconnected = arcade.load_texture("assets/graphics/unconnected_lines/corner/left_bottom.png") -left_top_unconnected = arcade.load_texture("assets/graphics/unconnected_lines/corner/left_top.png") -right_bottom_unconnected = arcade.load_texture("assets/graphics/unconnected_lines/corner/right_bottom.png") -right_top_unconnected = arcade.load_texture("assets/graphics/unconnected_lines/corner/right_top.png") \ No newline at end of file +vertical_unpowered = arcade.load_texture("assets/graphics/unpowered_lines/line/vertical.png") +horizontal_unpowered = arcade.load_texture("assets/graphics/unpowered_lines/line/horizontal.png") +left_bottom_unpowered = arcade.load_texture("assets/graphics/unpowered_lines/corner/left_bottom.png") +left_top_unpowered = arcade.load_texture("assets/graphics/unpowered_lines/corner/left_top.png") +right_bottom_unpowered = arcade.load_texture("assets/graphics/unpowered_lines/corner/right_bottom.png") +right_top_unpowered = arcade.load_texture("assets/graphics/unpowered_lines/corner/right_top.png") + +power_source = arcade.load_texture("assets/graphics/power_source.png")