TFWR. Simple pumpkin harvest

The goal of this post is not to give you a ready polished and optimized pumpkin harvester in the TFWR game. I want to show you the simplest possible harvester, as I know it and explain step-by-step how it works.

def best_move(d1, d2, n1, n2):
  d, n = ((d1, n1), (d2, n2))[n2 < n1]
  for _ in range(n):
    move(d)

def nav(x2, y2):
  x1, y1 = get_pos_x(), get_pos_y()
  n = get_world_size()
  best_move(East, West, (x2 - x1)%n, (x1 - x2)%n)
  best_move(North, South, (y2 - y1)%n, (y1 - y2)%n)

My favorite navigation. Why it works is written here.

n = 12
set_world_size(n)

Just for the sake of the video let our farm be 12 cells long. If you don't have this function yet, you can measure your farm with

n = get_world_size()

Let's start with tilling the whole farm.

for y in range(n):
  for x in range(n):
    nav(x,y)
    if get_ground_type() == Grounds.Grassland:
      till()

Two loops allow us to visit every cell on the farm. It's a good idea to check the ground type because without this check the script will always change the ground type to the opposite.

Now let's plan our pumpkin endeavor.

plan = []
for y in range(n):
  for x in range(n):
    plan.append((x, y))

We created an array of tuples with all cells in which we want to have mature pumpkins.

while plan:
  x, y = plan.pop(0)
  nav(x, y)
  if not can_harvest():
    plant(Entities.Pumpkin)
    plan.append((x, y))
while plan

is quite an interesting construction. It executes a piece of code while there is something in the list 'plan'. You can re-write this condition as len(plan) > 0, but while plan is more pythonic.

Then we get a pair of coordinates from the beginning of the list and go to the (x, y) place. Now the most tricky, at least for me, part starts.

A pumpkin can be grown up, in this case can_harvest() is True. But if it is not, there are two options: the pumpkin is OK, but it is growing and the pumpkin can be rotten. This code elegantly handles all these options. It tries to plant a pumpkin. If it is growing already, plant does nothing. If it is rotten, plant replaces it with a new one. In all these cases it makes sense to check the pumpkin again, so we append the tuple of coordinates to the end of our list.

If we are outside the loop, our plan is empty, it means that all pumpkins are grown up and we can harvest them.

Last but not least, we need to make an infinite loop to continue the harvest.

Code on github