From 23e36f95b51bc063a8e99bf46f34c231395fa841 Mon Sep 17 00:00:00 2001 From: Beardedmoose Date: Sun, 17 Dec 2023 16:34:28 -0800 Subject: [PATCH 1/3] Adding a plow character option that clears the screen --- snowmachine/__init__.py | 243 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 242 insertions(+), 1 deletion(-) diff --git a/snowmachine/__init__.py b/snowmachine/__init__.py index b51c43a..26450a4 100644 --- a/snowmachine/__init__.py +++ b/snowmachine/__init__.py @@ -23,6 +23,8 @@ # "rainbow", ] + + bad_colors = ["RESET"] codes = vars(Fore) colors = [] @@ -231,6 +233,215 @@ def tree(light_delay, color, lights_color, snow_color, particle, snow, snow_part final_speed = 1.0 / snow_speed time.sleep(final_speed) +@cli.command() +@click.option("--speed", default=14, help="Increase to make it snow faster.") +@click.option( + "--plowchar", + default="truck", + help="Choose your plow character", + type=click.Choice(["truck","person"]), +) +@click.option( + "--min_snowtimer", + default=120, + help="Minimum time to snow before starting to plow. Defaults to 120 cylces", +) +@click.option( + "--max_snowtimer", + default=200, + help="maximum time to snow before starting to plow. Defaults to 200 cycles", +) +@click.option( + "--particle", + default=None, + help="Change the particle used.", +) +@click.option( + "--color", + default=None, + help="Change the color of the particle.", + type=click.Choice(colors + ["rainbow"]), +) +def snowplow(speed, plowchar, min_snowtimer, max_snowtimer, particle, color): + clear_screen() + # This ends up formatted as column being the key and then [0] is row and + # [1] is the particle. For example: + # {"1": [0, "*"]} + snowflakes = {} + current_rows = {} + snowTimer = random.randrange(min_snowtimer,max_snowtimer) + curSnowTimer = 0 + waitForLastFlakeTime = rows + curWaitForLastFlakeTimer = 0 + isSnowing = True + isPlowing = False + hasLastFlakeFallen = False + curSnowPlowColumn = columns + maxPlowCharWidth = 0 + isMovingLeft = True + + # The spaces are used to blank out characters so make sure to pad the images. + asciiTruckLeft = { + 7:" /================ ", + 6:" ___ // @||----------| ", + 5:" _|___|_//_\_|||_____|____| ", + 4:" | ____ | || /___ |> ", + 3:" | | \|_____||___| \ |> ", + 2:"]_/|_| O \__________| O \|| ", + 1:"] \___/~~ \___/~~ " + + } + + asciiTruckRight = { + 7:" ================\\ ", + 6:" |----------||@ \\\ ___ ", + 5:" |____|_____|||_/_\\\_|___|_ ", + 4:" <| ___\ || | ____ | ", + 3:" <| / |___||_____|/ | | ", + 2:" ||/ O |__________/ O |_|\_[", + 1:" \___/ \___/ [" + } + + asciiPersonLeft = { + 3:" @ ", + 2:" /|\ ", + 1:"]//^\ " + } + + # Sometimes escape trickery is needed like with the backslash. + asciiPersonRight = { + 3:" @ ", + 2:" /|\ ", + 1:" /^\\\[" + } + + # If the plowchar is truck, then we need to flip the left and right + if (plowchar == "truck" and isMovingLeft): + plowchar = asciiTruckLeft + elif (plowchar == "truck"): + plowchar = asciiTruckRight + # If the plowchar is person, then we need to flip the left and right + if (plowchar == "person" and isMovingLeft): + plowchar = asciiPersonLeft + elif (plowchar == "person"): + plowchar = asciiPersonRight + # Get the longest string in the ascii array, used to calculate screen buffer spice on the sides so they can move offscreen. + maxPlowCharWidth = max(len(value) for value in plowchar.values()) + + + + while True: + col = random.choice(range(1, int(columns))) + + # Don't print snowflakes right next to each other, since + # unicode flakes take 2 spaces + if col % 2 == 0: + continue + + # its already on the screen, move it + if col in snowflakes.keys() and hasLastFlakeFallen == False: + move_plow_flake(snowflakes, col, particle, color, isSnowing) + else: + # we only want to move snowflakes if it's snowing. + if (isSnowing): + # otherwise put it on the screen + flake = particle if particle else get_random_flake() + snowflakes[col] = [1, flake] + print_snowflake_col(snowflakes, col, color) + + # key any flakes on the screen moving + for flake in snowflakes.keys(): + if (hasLastFlakeFallen == False): + move_plow_flake(snowflakes, flake, particle, color, isSnowing) + # if it's snowing do the regular speed + if (isSnowing): + final_speed = 1.0 / speed + curSnowTimer += 1 + else: + # It's plow time! + if (isPlowing): + maxPlowCharWidth = max(len(value) for value in plowchar.values()) + # Speed up time for plowing * 2 + final_speed = 0.5 / speed + + # If there is a snowflake in our current column, erase the flake delete it from snowflakes. + if curSnowPlowColumn in snowflakes.keys(): + print("\033[%s;%sH " % (snowflakes[curSnowPlowColumn][0], curSnowPlowColumn)) + snowflakes.pop(curSnowPlowColumn) + + if (isMovingLeft): + # Lets the plow drive off the screen to the left. + if curSnowPlowColumn + maxPlowCharWidth >= 0: + # This is magic, let's iterate through each row and print out each character of the ascii truck. + for key, value in plowchar.items(): + for index, character in enumerate(value): + print_character(rows-key,curSnowPlowColumn + index,character,color) + # decrease the plow column + curSnowPlowColumn -= 1 + + else: + # If we aren't plowing anymore let's clear the screen and reset variables. + clear_screen() + isPlowing = False + isSnowing = True + hasLastFlakeFallen = False + isMovingLeft = False + if (plowchar == asciiTruckLeft): + plowchar = asciiTruckRight + if (plowchar == asciiPersonLeft): + plowchar = asciiPersonRight + + elif (not isMovingLeft): + # Lets the plow drive off the screen to the right. + if curSnowPlowColumn <= columns + maxPlowCharWidth: + # This is magic, let's iterate through each row and print out each character of the ascii truck. + for key, value in plowchar.items(): + for index, character in enumerate(reversed(value)): + print_character(rows-key,curSnowPlowColumn - index,character,color) + # increase the plow column since we're going right + curSnowPlowColumn += 1 + else: + # If we aren't plowing anymore let's clear the screen and reset variables. + clear_screen() + isPlowing = False + isSnowing = True + hasLastFlakeFallen = False + isMovingLeft = True + if (plowchar == asciiTruckRight): + plowchar = asciiTruckLeft + if (plowchar == asciiPersonRight): + plowchar = asciiPersonLeft + + + else: + # We want to wait until all of the snowflakes have fallen before we start plowing. + if (hasLastFlakeFallen): + # We are ready to plow, last snowflake has fallen + isPlowing = True + # right before we plow lets set the plow position based on moving direction. + if (isMovingLeft): + curSnowPlowColumn = columns + elif (not isMovingLeft): + curSnowPlowColumn = 0 + + curWaitForLastFlakeTimer = 0 + else: + if (curWaitForLastFlakeTimer >= waitForLastFlakeTime): + hasLastFlakeFallen = True + else: + curWaitForLastFlakeTimer += 1 + #Time for now until the timer reaches the snowTimer. + if (curSnowTimer >= snowTimer): + # Time to stop snowing + isSnowing = False + curSnowTimer = 0 + snowTimer = random.randrange(min_snowtimer,max_snowtimer) + + try: + time.sleep(final_speed) + except KeyboardInterrupt: + clear_screen() + sys.exit(0) def clear_screen(numlines=100): """Clear the console. @@ -298,6 +509,36 @@ def print_character(row, column, character, color): def print_snowflake_col(snowflakes, col, color): print_character(snowflakes[col][0], col, snowflakes[col][1], color) +def move_plow_flake(snowflakes, col, particle, color, isSnowing): + # Rows is the max amount of rows on the screen, + # so settings the column to the rows count means + # putting it at the bottom of the screen + + current_row = rows + + # If next row is the end, lets start a new snow flake, but only if it's snowing. + if isSnowing: + if snowflakes[col][0] + 1 == current_row: + char = particle + if not particle: + char = get_random_flake() + snowflakes[col] = [1, char] + print_snowflake_col(snowflakes, col, color) + + else: + # erase the flake in current location + print("\033[%s;%sH " % (snowflakes[col][0], col)) + # move down by one + snowflakes[col][0] += 1 + print_snowflake_col(snowflakes, col, color) + # If it's not snowing and the snowflake isn't touching the ground let's move it down. + else: + if snowflakes[col][0] +1 != current_row: + # erase the flake in current location + print("\033[%s;%sH " % (snowflakes[col][0], col)) + # move down by one + snowflakes[col][0] += 1 + print_snowflake_col(snowflakes, col, color) def move_flake(snowflakes, current_rows, col, stack, particle, color): # Rows is the max amount of rows on the screen, @@ -346,4 +587,4 @@ def signal_handler(sig, frame): signal.signal(signal.SIGINT, signal_handler) if __name__ == "__main__": - cli() + cli() \ No newline at end of file From 773885860b9ee3522b818671581159ac841c8796 Mon Sep 17 00:00:00 2001 From: Matt Neumann Date: Mon, 18 Dec 2023 10:43:58 -0800 Subject: [PATCH 2/3] Updated readme to reflect snowplow addition --- README.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 07d0da4..c7337e2 100644 --- a/README.md +++ b/README.md @@ -38,13 +38,19 @@ $ snowmachine snow ``` -or render a tree: +render a tree: ```bash $ snowmachine tree ``` +or clean up the snow with a plow: + +```bash +$ snowmachine snowplow +``` + You can also tell it to stack the snow if you prefer. ```bash @@ -70,6 +76,10 @@ In addition you can change the speed of particles: $ snowmachine --speed=5 ``` +You can also specify the type of plow you want to use: +```bash +$ snowmachine snowplow --plowchar=person +``` You can find a bash(shell) script version of this here: https://gist.github.com/sontek/1505483 From 1ac905e39e31e88352f4447981b17175ddbb7937 Mon Sep 17 00:00:00 2001 From: Matt Neumann Date: Mon, 18 Dec 2023 10:57:52 -0800 Subject: [PATCH 3/3] Fixed Ascii truck to look the same left and right --- snowmachine/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snowmachine/__init__.py b/snowmachine/__init__.py index 26450a4..1a38183 100644 --- a/snowmachine/__init__.py +++ b/snowmachine/__init__.py @@ -299,7 +299,7 @@ def snowplow(speed, plowchar, min_snowtimer, max_snowtimer, particle, color): 4:" <| ___\ || | ____ | ", 3:" <| / |___||_____|/ | | ", 2:" ||/ O |__________/ O |_|\_[", - 1:" \___/ \___/ [" + 1:" ~~\___/ ~~\___/ [" } asciiPersonLeft = {