From c447007e3a59f2e36c98c7552c2b1e6ad34a20c6 Mon Sep 17 00:00:00 2001 From: Aiden Lyons <105181221+ricedbroccoli@users.noreply.github.com> Date: Sat, 21 Jun 2025 15:23:38 -0400 Subject: [PATCH 1/3] Create README.md --- submissions/terminal_aquarium/README.md | 28 +++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 submissions/terminal_aquarium/README.md diff --git a/submissions/terminal_aquarium/README.md b/submissions/terminal_aquarium/README.md new file mode 100644 index 00000000..ac243327 --- /dev/null +++ b/submissions/terminal_aquarium/README.md @@ -0,0 +1,28 @@ + +This is a project I made for the Terminalcraft YSWS + +It has small fish drawn in ASCII art floating around at random through the tank, and will shape itself to the size of your terminal window. + +Instructions: + +### 1) Make sure you install Python 3 + +### 2) Clone the repo from GitHub + +### 3) Extract the repository file + +### 4) Go to the location of the extracted repository in your terminal + +### 5) Enter the following command: + + +``` +python3 main.py +``` + + +### 6) Enjoy the aquarium + +I chose this project specifically because I love fishtank screen savers. Fish swimming around is just calming to me. So why not make one inside the terminal? + +Demo Video: https://youtu.be/bU37wko4UA8 From ecbfbb28e1e00c9ef36caa6547501a8c691a889a Mon Sep 17 00:00:00 2001 From: Aiden Lyons <105181221+ricedbroccoli@users.noreply.github.com> Date: Sat, 21 Jun 2025 15:26:30 -0400 Subject: [PATCH 2/3] Create main.py --- submissions/terminal_aquarium/main.py | 143 ++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 submissions/terminal_aquarium/main.py diff --git a/submissions/terminal_aquarium/main.py b/submissions/terminal_aquarium/main.py new file mode 100644 index 00000000..8d9eae26 --- /dev/null +++ b/submissions/terminal_aquarium/main.py @@ -0,0 +1,143 @@ +import os +import random +import time +import shutil + +fish_types = [ + "><((('>", + "><> ", + "><(((º>", + "><> ", + "><((°> ", + "<°)))>< ", + +] + +background_art = [ + # Rocks + {"art": [" _/\\_", " / \\", "/_/\\/\\_\\"], "min_width": 10}, + {"art": [" __", " _/ \\", "/ \\", "\\_/\\_/"], "min_width": 8}, + {"art": [" ___", " / \\", " / \\", "/_/\\_/\\_"], "min_width": 9}, + # Coral + {"art": [" |", " /|\\", "/_|_\\"], "min_width": 5}, + {"art": [" |", " /|", "/ |"], "min_width": 4}, + {"art": [" /\\", " / \\", " /_/\\_\\"], "min_width": 7}, + # Seaweed + {"art": [" |", " /|", "/ |"], "min_width": 4}, + {"art": [" |", " |/", " /|"], "min_width": 3}, + {"art": [" /", " /|", "/ |"], "min_width": 3}, + # Starfish + {"art": [" *", " /|\\", "<-O->", " \\|/"], "min_width": 5}, + # Pebbles + {"art": [" . .", " ..", " ."], "min_width": 4}, +] + +class Fish: + def __init__(self, y, x, direction, fish_type): + self.y = y + self.x = x + self.direction = direction # 1 for right, -1 for left + self.fish_type = fish_type if direction == 1 else fish_type[::-1] + + def move(self, width, height): + self.x += self.direction + # Bounce off walls + if self.x < 0: + self.direction = 1 + self.fish_type = self.fish_type[::-1] + self.x = 0 + elif self.x + len(self.fish_type) > width: + self.direction = -1 + self.fish_type = self.fish_type[::-1] + self.x = width - len(self.fish_type) + # Randomly move up/down + if random.random() < 0.1: + self.y += random.choice([-1, 1]) + self.y = max(0, min(height - 1, self.y)) + +class Bubble: + def __init__(self, x, y): + self.x = x + self.y = y + + def move(self): + self.y -= 1 + +def clear(): + os.system('cls' if os.name == 'nt' else 'clear') + + +def place_background(width, height): + # Randomly place background art at the bottom of the aquarium. + bg_map = [[" " for _ in range(width)] for _ in range(height)] + num_items = random.randint(2, 4) + for _ in range(num_items): + art_obj = random.choice(background_art) + art = art_obj["art"] + art_height = len(art) + art_width = max(len(line) for line in art) + if art_width > width: + continue + x = random.randint(0, width - art_width) + y = height - art_height + for dy, line in enumerate(art): + for dx, ch in enumerate(line): + if ch != " ": + bg_map[y + dy][x + dx] = ch + return bg_map + +def draw_aquarium(fishes, bubbles, bg_map, width, height): + aquarium = [[" " for _ in range(width)] for _ in range(height)] + # Place background art + for y in range(height): + for x in range(width): + if bg_map[y][x] != " ": + aquarium[y][x] = bg_map[y][x] + # Place bubbles + for bubble in bubbles: + if 0 <= bubble.y < height and 0 <= bubble.x < width: + aquarium[bubble.y][bubble.x] = "o" + # Place fish + for fish in fishes: + for i, ch in enumerate(fish.fish_type): + fx = fish.x + i + if 0 <= fx < width and 0 <= fish.y < height: + aquarium[fish.y][fx] = ch + print("+" + "-" * width + "+") + for row in aquarium: + print("|" + "".join(row) + "|") + print("+" + "-" * width + "+") + +def main(): + width, height = shutil.get_terminal_size((80, 24)) + width -= 2 + height -= 2 + num_fish = min(8, height) + fishes = [] + for _ in range(num_fish): + y = random.randint(0, height - 4) + x = random.randint(0, width - 8) + direction = random.choice([1, -1]) + fish_type = random.choice(fish_types) + fishes.append(Fish(y, x, direction, fish_type)) + bg_map = place_background(width, height) + bubbles = [] + try: + while True: + # Adds bubble from a random bottom position + if random.random() < 0.15: + bx = random.randint(0, width - 1) + bubbles.append(Bubble(bx, height - 1)) + # Move bubbles up and remove those that reach the top + for bubble in bubbles: + bubble.move() + bubbles = [b for b in bubbles if b.y >= 0] + clear() + draw_aquarium(fishes, bubbles, bg_map, width, height) + for fish in fishes: + fish.move(width, height) + time.sleep(0.2) + except KeyboardInterrupt: + print("\nAquarium closed.") + +main() From 917b43b60870c4f7201a87ba692a9e288b5d4e59 Mon Sep 17 00:00:00 2001 From: Aiden Lyons <105181221+ricedbroccoli@users.noreply.github.com> Date: Tue, 24 Jun 2025 14:19:09 -0400 Subject: [PATCH 3/3] Update main.py --- submissions/terminal_aquarium/main.py | 134 ++++++++++++++++---------- 1 file changed, 81 insertions(+), 53 deletions(-) diff --git a/submissions/terminal_aquarium/main.py b/submissions/terminal_aquarium/main.py index 8d9eae26..1a398518 100644 --- a/submissions/terminal_aquarium/main.py +++ b/submissions/terminal_aquarium/main.py @@ -1,55 +1,65 @@ -import os import random import time import shutil -fish_types = [ - "><((('>", - "><> ", - "><(((º>", - "><> ", - "><((°> ", - "<°)))>< ", +class Colors: + RESET = "\033[0m" + BLUE = "\033[94m" + CYAN = "\033[96m" + GREEN = "\033[92m" + YELLOW = "\033[93m" + WHITE = "\033[97m" + MAGENTA = "\033[95m" + + +fish_types = [ + {"art": "><((('>", "color": Colors.BLUE}, + {"art": "><> ", "color": Colors.MAGENTA}, + {"art": "><(((º>", "color": Colors.YELLOW}, + {"art": "><> ", "color": Colors.CYAN}, + {"art": "><((°> ", "color": Colors.GREEN}, + {"art": "<°)))>< ", "color": Colors.BLUE}, ] background_art = [ # Rocks - {"art": [" _/\\_", " / \\", "/_/\\/\\_\\"], "min_width": 10}, - {"art": [" __", " _/ \\", "/ \\", "\\_/\\_/"], "min_width": 8}, - {"art": [" ___", " / \\", " / \\", "/_/\\_/\\_"], "min_width": 9}, + {"art": [" _/\\_", " / \\", "/_/\\/\\_\\"], "min_width": 10, "color": Colors.WHITE}, + {"art": [" __", " _/ \\", "/ \\", "\\_/\\_/"], "min_width": 8, "color": Colors.WHITE}, + {"art": [" ___", " / \\", " / \\", "/_/\\_/\\_"], "min_width": 9, "color": Colors.WHITE}, # Coral - {"art": [" |", " /|\\", "/_|_\\"], "min_width": 5}, - {"art": [" |", " /|", "/ |"], "min_width": 4}, - {"art": [" /\\", " / \\", " /_/\\_\\"], "min_width": 7}, + {"art": [" |", " /|\\", "/_|_\\"], "min_width": 5, "color": Colors.MAGENTA}, + {"art": [" |", " /|", "/ |"], "min_width": 4, "color": Colors.MAGENTA}, # Seaweed - {"art": [" |", " /|", "/ |"], "min_width": 4}, - {"art": [" |", " |/", " /|"], "min_width": 3}, - {"art": [" /", " /|", "/ |"], "min_width": 3}, + {"art": [" /\\", " / \\", " /_/\\_\\"], "min_width": 7, "color": Colors.GREEN}, + {"art": [" |", " /|", "/ |"], "min_width": 4, "color": Colors.GREEN}, + {"art": [" |", " |/", " /|"], "min_width": 3, "color": Colors.GREEN}, # Starfish - {"art": [" *", " /|\\", "<-O->", " \\|/"], "min_width": 5}, + {"art": [" *", " /|\\", "<-O->", " \\|/"], "min_width": 5, "color": Colors.YELLOW}, # Pebbles - {"art": [" . .", " ..", " ."], "min_width": 4}, + {"art": [" . .", " ..", " ."], "min_width": 4, "color": Colors.WHITE}, ] class Fish: - def __init__(self, y, x, direction, fish_type): + + def __init__(self, y, x, direction, art, color): self.y = y self.x = x self.direction = direction # 1 for right, -1 for left - self.fish_type = fish_type if direction == 1 else fish_type[::-1] + self.art = art if direction == 1 else art[::-1] + self.color = color def move(self, width, height): self.x += self.direction # Bounce off walls if self.x < 0: self.direction = 1 - self.fish_type = self.fish_type[::-1] + self.art = self.art[::-1] self.x = 0 - elif self.x + len(self.fish_type) > width: + elif self.x + len(self.art) > width: self.direction = -1 - self.fish_type = self.fish_type[::-1] - self.x = width - len(self.fish_type) + self.art = self.art[::-1] + self.x = width - len(self.art) # Randomly move up/down if random.random() < 0.1: self.y += random.choice([-1, 1]) @@ -59,21 +69,24 @@ class Bubble: def __init__(self, x, y): self.x = x self.y = y + # --- New: Bubbles are now cyan --- + self.color = Colors.CYAN def move(self): self.y -= 1 def clear(): - os.system('cls' if os.name == 'nt' else 'clear') + print("\033[H", end="") def place_background(width, height): - # Randomly place background art at the bottom of the aquarium. - bg_map = [[" " for _ in range(width)] for _ in range(height)] - num_items = random.randint(2, 4) + + bg_map = [[(" ", Colors.RESET) for _ in range(width)] for _ in range(height)] + num_items = random.randint(3, 5) for _ in range(num_items): art_obj = random.choice(background_art) art = art_obj["art"] + color = art_obj["color"] art_height = len(art) art_width = max(len(line) for line in art) if art_width > width: @@ -83,61 +96,76 @@ def place_background(width, height): for dy, line in enumerate(art): for dx, ch in enumerate(line): if ch != " ": - bg_map[y + dy][x + dx] = ch + bg_map[y + dy][x + dx] = (ch, color) return bg_map def draw_aquarium(fishes, bubbles, bg_map, width, height): - aquarium = [[" " for _ in range(width)] for _ in range(height)] - # Place background art - for y in range(height): - for x in range(width): - if bg_map[y][x] != " ": - aquarium[y][x] = bg_map[y][x] - # Place bubbles + aquarium = [row[:] for row in bg_map] + for bubble in bubbles: if 0 <= bubble.y < height and 0 <= bubble.x < width: - aquarium[bubble.y][bubble.x] = "o" - # Place fish + aquarium[bubble.y][bubble.x] = ("o", bubble.color) + for fish in fishes: - for i, ch in enumerate(fish.fish_type): + for i, ch in enumerate(fish.art): fx = fish.x + i if 0 <= fx < width and 0 <= fish.y < height: - aquarium[fish.y][fx] = ch - print("+" + "-" * width + "+") + aquarium[fish.y][fx] = (ch, fish.color) + + output_str = [] + output_str.append(Colors.BLUE + "+" + "-" * width + "+" + Colors.RESET) for row in aquarium: - print("|" + "".join(row) + "|") - print("+" + "-" * width + "+") + line_str = [Colors.BLUE + "|" + Colors.RESET] + current_color = Colors.RESET + for char, color in row: + if color != current_color: + line_str.append(color) + current_color = color + line_str.append(char) + + if current_color != Colors.RESET: + line_str.append(Colors.RESET) + line_str.append(Colors.BLUE + "|" + Colors.RESET) + output_str.append("".join(line_str)) + output_str.append(Colors.BLUE + "+" + "-" * width + "+" + Colors.RESET) + + print("\n".join(output_str)) def main(): width, height = shutil.get_terminal_size((80, 24)) width -= 2 height -= 2 - num_fish = min(8, height) + num_fish = min(8, height // 2) fishes = [] for _ in range(num_fish): y = random.randint(0, height - 4) - x = random.randint(0, width - 8) + x = random.randint(0, width - 10) direction = random.choice([1, -1]) - fish_type = random.choice(fish_types) - fishes.append(Fish(y, x, direction, fish_type)) + fish_obj = random.choice(fish_types) + fishes.append(Fish(y, x, direction, fish_obj["art"], fish_obj["color"])) + bg_map = place_background(width, height) bubbles = [] try: while True: - # Adds bubble from a random bottom position if random.random() < 0.15: - bx = random.randint(0, width - 1) + bx = random.randint(1, width - 2) bubbles.append(Bubble(bx, height - 1)) - # Move bubbles up and remove those that reach the top + for bubble in bubbles: bubble.move() bubbles = [b for b in bubbles if b.y >= 0] + clear() draw_aquarium(fishes, bubbles, bg_map, width, height) + for fish in fishes: fish.move(width, height) + time.sleep(0.2) except KeyboardInterrupt: - print("\nAquarium closed.") -main() + print(f"\n{Colors.RESET}Aquarium closed.") + +if __name__ == "__main__": + main()