From 70caea12433a5ab772121ad7df1b10886ec8aa52 Mon Sep 17 00:00:00 2001 From: steve Date: Sat, 10 Jan 2026 16:39:00 -0500 Subject: [PATCH] refactor: unify planting logic with `on_plant` callback and improve variable naming --- sunflowers.py | 33 ++++++++++---- utils.py | 120 ++++++++++++-------------------------------------- 2 files changed, 51 insertions(+), 102 deletions(-) diff --git a/sunflowers.py b/sunflowers.py index 8b17f3d..b0cca4c 100644 --- a/sunflowers.py +++ b/sunflowers.py @@ -6,7 +6,7 @@ import utils # Places sunflowers at random locations in the specified area. # # We cannot simply just use utils.plant_grid here, because we need to also keep track -# of the number of petals on each sunflower, and return a dictionary mapping petal count +# of the number of petals on each sunflower and return a dictionary mapping petal count # to a list of sunflower coordinates containing that petal count. # # Parameters: @@ -19,23 +19,38 @@ import utils # Important: # utils.plant_grid uses very similar logic with this function, so any changes to this function should be reflected in utils.plant_grid as well. def place(width, height): - return utils.plant_grid_return_measurements(width, height, [Entities.Sunflower], 0.75, True) + results = {} + + def on_plant(x, y): + m = measure() + if m not in results: + results[m] = [] + + results[m].append((x, y)) + + utils.plant_grid(width, height, [Entities.Sunflower], 0.75, True, on_plant) + + return results # Harvests all sunflowers in the specified area. # -# The rules for sunflower harvesting is that we must harvest the flowers with the most petals first -# as doing so gives us an 8x bonus. +# The rules for sunflower harvesting are that we must harvest the flowers with the most petals first +# as doing so harvests eight times more power. Keep a tally of the total power harvested. # # Parameters: -# width (int): The number of columns in the grid. -# height (int): The number of rows in the grid. # flowers (dictionary): A dictionary mapping petal count to a list of sunflower coordinates containing that petal count. -def harvest_grid(width, height, flowers): - result = {} - +# +# Returns: +# int: an estimate of the total power harvested. If the game is ever out of sync somehow (e.g.: there's an erroneous +# sunflower on your map outside the provided flowers), this could be inaccurate. +def harvest_grid(flowers): + result = 0 # in reverse order of petals petals = [15, 14, 13, 12, 11, 10, 9, 8, 7] for count in petals: for coord in flowers[count]: utils.move_to(coord[0], coord[1]) harvest() + result += count * 8 + + return result \ No newline at end of file diff --git a/utils.py b/utils.py index 672086f..d35dfe1 100644 --- a/utils.py +++ b/utils.py @@ -28,131 +28,65 @@ def move_to(x, y): # plantWith (list): A list of entities to plant. # waterBelow (float): The water level below which the tile will be watered. # requireSoil (bool): If true, the tile will be tilled if it's not soil. +# onPlant (function): A function to call after each planting operation (optional). Parameters: x, y # # Returns: # None -# -# Important: -# plant_grid_returns_measurements uses identical logic but has added needed measurement calls. Any logic changes here -# Any changes to this function should be reflected in plant_grid_returns_measurements as well. -def plant_grid(width, height, plantWith, waterBelow, requireSoil): +def plant_grid(width, height, plant_with, water_below, require_soil, on_plant = None): res = {} x = get_pos_x() y = get_pos_y() - gridSize = get_world_size() + grid_size = get_world_size() - if (x + width) > gridSize: - width = gridSize - x + if (x + width) > grid_size: + width = grid_size - x - if (y + height) > gridSize: - height = gridSize - y + if (y + height) > grid_size: + height = grid_size - y tracker = 0 others = {East: West, West: East} - sideDir = East + side_dir = East # first pass over, checking if anything can be harvested. if so, harvest. - # then check what type of ground is down, if it's not soil then till. - # then if it's below 75% water and i have some water, give it some. + # then check what type of ground is down, if it's not soil, then till. + # then if it's below 75% water and I have some water, give it some. # then plant a pumpkin. for row in range(height): for col in range(width): if can_harvest(): harvest() - if requireSoil: + if require_soil: if get_ground_type() != Grounds.Soil: till() - while get_water() < waterBelow: + while get_water() < water_below: if not use_item(Items.Water): break - index = tracker % len(plantWith) + index = tracker % len(plant_with) tracker += 1 - plant(plantWith[index]) + plant(plant_with[index]) + + # if on_plant is not None: is giving me errors in the game, but this seems to be what they want + if on_plant: + on_plant(x, y) # if it's not the last pass, then move if col < width - 1: - move(sideDir) + if side_dir == East: + x = (x + 1) % grid_size + + elif side_dir == West: + x = (x - 1) % grid_size + + move(side_dir) if row < height - 1: - sideDir = others[sideDir] + side_dir = others[side_dir] move(North) + y = (y + 1) % grid_size return res - -# Plant a square of the given list of entities. -# -# If the water level is below waterBelow, -# it will water the tile. If requireSoil is true, it will till the tile if it's not soil. -# plantWith - list of entities to plant. The entities will alternate if repeated. -# -# Parameters: -# width (int): The number of columns in the grid. -# height (int): The number of rows in the grid. -# plantWith (list): A list of entities to plant. -# waterBelow (float): The water level below which the tile will be watered. -# requireSoil (bool): If true, the tile will be tilled if it's not soil. -# -# Returns: -# None -# -# Important: -# plant_grid uses identical logic but has added needed measurement calls. Any logic changes here -# Any changes to this function should be reflected in plant_grid as well. -def plant_grid_return_measurements(width, height, plantWith, waterBelow, requireSoil): - res = {} - x = get_pos_x() - y = get_pos_y() - - gridSize = get_world_size() - - if (x + width) > gridSize: - width = gridSize - x - - if (y + height) > gridSize: - height = gridSize - y - - tracker = 0 - - others = {East:West, West:East} - - sideDir = East - # first pass over, checking if anything can be harvested. if so, harvest. - # then check what type of ground is down, if it's not soil then till. - # then if it's below 75% water and i have some water, give it some. - # then plant a pumpkin. - for row in range(height): - for col in range(width): - if can_harvest(): - harvest() - if requireSoil: - if get_ground_type() != Grounds.Soil: - till() - - while get_water() < waterBelow: - if not use_item(Items.Water): - break - - index = tracker % len(plantWith) - tracker += 1 - plant(plantWith[index]) - - measurement = measure() - - if measurement not in res: - res[measurement] = [] - res[measurement].append((get_pos_x(), get_pos_y())) - - # if it's not the last pass, then move - if col < width - 1: - move(sideDir) - - - if row < height - 1: - sideDir = others[sideDir] - move(North) - - return res \ No newline at end of file