Код поликультуры — The Farmer Was Replaced (гайд по get_companion)

Поликультура — механика, из‑за которой трава, кусты, деревья и морковь дают гораздо больше, если нужный компаньон растёт на нужной клетке. В этом гайде разобрано, что возвращает get_companion(), почему наивный подход ломается, и дан код поликультуры, который можно вставить в игру и доработать.

Если вы только собираете первую ферму, начните с готовых кодов и кода дерева. Поликультура опирается на оба.

Что делает поликультура

У каждой травы, куста, дерева и моркови может быть предпочтение компаньона. Если посадить нужное растение в точную позицию и затем собрать исходное — получите большой бонус к урожаю. До апгрейда множитель равен 5, каждый апгрейд его удваивает. Поэтому поликультура — один из сильнейших бустов сена, дерева и моркови в середине игры.

Правила, от которых зависит ваш код:

Как работает get_companion()

Встаньте дроном на растение и вызовите get_companion(). Это занимает один тик и возвращает либо None (нет предпочтения), либо кортеж: тип сущности и координаты (x, y).

companion = get_companion()
if companion != None:
    plant_type, (x, y) = companion
    print("Companion:", plant_type, "at", x, ",", y)

Например, куст может вернуть (Entities.Carrot, (3, 5)). Это значит: посадите морковь на (3, 5), затем соберите куст — получите больше дерева.

Всегда распаковывайте координаты. Не предполагайте, что компаньон стоит «рядом». API обещает только координату, не направление.

Почему простой подход не работает

Очевидная идея: прочитать компаньона, дойти, посадить, вернуться, собрать. На маленькой ферме это сработает, но съест много движения. Хуже: клетка, куда вы идёте, уже может держать растение со своим запросом — пересадка его уничтожит.

Лучший паттерн — запоминать запросы в словаре и выполнять их, когда обычный проход доходит до этой клетки. Дрон сохраняет рядный маршрут, а поликультура почти «бесплатна».

Код поликультуры (проход + словарь)

Эта версия обходит всё поле. На каждой клетке сначала проверяет, не просило ли другое растение компаньона сюда. Если да — сажает его. Иначе сажает основную культуру и записывает её собственный запрос.

companions = {}  # (x, y) -> entity that should be planted there

def plant_tile(main_crop):
    pos = (get_pos_x(), get_pos_y())
    if can_harvest():
        harvest()
    if pos in companions:
        want = companions.pop(pos)
        if want == Entities.Carrot:
            if get_ground_type() != Grounds.Soil:
                till()
        plant(want)
        return
    if main_crop == Entities.Carrot:
        if get_ground_type() != Grounds.Soil:
            till()
    plant(main_crop)
    result = get_companion()
    if result != None:
        want, target = result
        if target not in companions:
            companions[target] = want

def sweep(main_crop):
    size = get_world_size()
    for i in range(size):
        for j in range(size):
            plant_tile(main_crop)
            move(North)
        move(East)

while True:
    sweep(Entities.Tree)

Замените Entities.Tree на Entities.Bush, Entities.Carrot или Entities.Grass под вашу цель. Траве на лужайке часто не нужен plant() — для чистой фермы сена можно только читать компаньонов.

Заметки по коду

Поликультура и несколько дронов

После разблокировки дополнительных дронов тот же словарь работает. Каждый дрон обходит свои столбцы, а общий companions позволяет запросу одного дрона быть выполненным другим. Дайте каждому стартовый столбец и ту же логику plant_tile(). Подробности Megafarm, spawn_drone и паттерн по столбцам — в гайде несколько дронов.

Частые ошибки

FAQ

Какие растения используют поликультуру? Трава, кусты, деревья и морковь. Тыквы, кактусы и подсолнухи живут по своим правилам.

Должен ли компаньон полностью вырасти? Нет. Стадия роста не важна.

Насколько большой бонус? Стартует с множителя 5× до апгрейдов и удваивается с каждым апгрейдом поликультуры.

Что фармить дальше? После поликультуры переходите к коду тыквы и коду подсолнуха или смотрите все готовые коды.