refactor: unify planting logic with on_plant callback and improve variable naming

This commit is contained in:
2026-01-10 16:39:00 -05:00
parent 5a16e7a8a3
commit 70caea1243
2 changed files with 51 additions and 102 deletions

View File

@@ -6,7 +6,7 @@ import utils
# Places sunflowers at random locations in the specified area. # 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 # 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. # to a list of sunflower coordinates containing that petal count.
# #
# Parameters: # Parameters:
@@ -19,23 +19,38 @@ import utils
# Important: # 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. # 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): 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. # Harvests all sunflowers in the specified area.
# #
# The rules for sunflower harvesting is that we must harvest the flowers with the most petals first # The rules for sunflower harvesting are that we must harvest the flowers with the most petals first
# as doing so gives us an 8x bonus. # as doing so harvests eight times more power. Keep a tally of the total power harvested.
# #
# Parameters: # 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. # 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 # in reverse order of petals
petals = [15, 14, 13, 12, 11, 10, 9, 8, 7] petals = [15, 14, 13, 12, 11, 10, 9, 8, 7]
for count in petals: for count in petals:
for coord in flowers[count]: for coord in flowers[count]:
utils.move_to(coord[0], coord[1]) utils.move_to(coord[0], coord[1])
harvest() harvest()
result += count * 8
return result

120
utils.py
View File

@@ -28,131 +28,65 @@ def move_to(x, y):
# plantWith (list): A list of entities to plant. # plantWith (list): A list of entities to plant.
# waterBelow (float): The water level below which the tile will be watered. # 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. # 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: # Returns:
# None # None
# def plant_grid(width, height, plant_with, water_below, require_soil, on_plant = 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):
res = {} res = {}
x = get_pos_x() x = get_pos_x()
y = get_pos_y() y = get_pos_y()
gridSize = get_world_size() grid_size = get_world_size()
if (x + width) > gridSize: if (x + width) > grid_size:
width = gridSize - x width = grid_size - x
if (y + height) > gridSize: if (y + height) > grid_size:
height = gridSize - y height = grid_size - y
tracker = 0 tracker = 0
others = {East: West, West: East} others = {East: West, West: East}
sideDir = East side_dir = East
# first pass over, checking if anything can be harvested. if so, harvest. # 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 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 if it's below 75% water and I have some water, give it some.
# then plant a pumpkin. # then plant a pumpkin.
for row in range(height): for row in range(height):
for col in range(width): for col in range(width):
if can_harvest(): if can_harvest():
harvest() harvest()
if requireSoil: if require_soil:
if get_ground_type() != Grounds.Soil: if get_ground_type() != Grounds.Soil:
till() till()
while get_water() < waterBelow: while get_water() < water_below:
if not use_item(Items.Water): if not use_item(Items.Water):
break break
index = tracker % len(plantWith) index = tracker % len(plant_with)
tracker += 1 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 it's not the last pass, then move
if col < width - 1: 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: if row < height - 1:
sideDir = others[sideDir] side_dir = others[side_dir]
move(North) move(North)
y = (y + 1) % grid_size
return res 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