Misty Island Mine - peasants die before they can bulid 2-d decoy


#1

Hi, there!
Cannot completed “Misty Island Mine”: my pesants can build only 1-st decoy and after that they die.
The is my code:

# Командуй крестьянами мудро, чтобы эффективно собирать золото.
# Крестьяне должны собирать монеты и строить приманки.

# Функция должна вернуть лучший предмет для прицеливания
# Используй массив из `id`, чтобы 2 крестьянина не шли за одним предметом.
def findBestItem(friend, excludedItems):
    items = friend.findItems()
    bestItem = None
    bestItemValue = 0
    for item in items:
        # Используй `in` для проверки вхождения элемента в массив `excludedItems`.
        # В этом случае пропусти предмет, другой крестьянин уже нацелился на него.
        if item in excludedItems:
            continue
        # Закончи функцию!
        # Помни, что `bestItemValue` должно вычисляться как максимальное `item.value / distanceTo`
        if item.value / friend.distanceTo(item) > bestItemValue:
            bestItem = item
            bestItemValue = item.value/friend.distanceTo(item)
    return bestItem

# This function checks if you have enough gold for a decoy.
def enoughGoldForDecoy():
    return hero.gold >= 25

while True:
    peasants = hero.findByType("peasant")
    # Создавай новый массив в каждом цикле.
    claimedItems = []
    for peasant in peasants:
        enemy = peasant.findNearestEnemy()
        if enemy:
            # If the peasant is the target of the enemy
            # И у героя достаточно золота на приманку
            if enoughGoldForDecoy() and peasant.distanceTo(enemy) < 15 and enemy.target == peasant:
                # Прикажи крестьянину строить приманку:
                hero.command(peasant, "buildXY", "decoy", peasant.pos.x-2, peasant.pos.y)
                # Добавь `continue`, чтобы крестьянин не собирал монеты во время стройки.
                continue
            pass
        item = findBestItem(peasant, claimedItems)
        if item:
            # После получение предмета помести его в массив `claimedItems`.
            claimedItems.append(item)
            # Прикажи крестьянину собрать монету:
            hero.command(peasant, "move", item.pos)

#2

The problem is in this line:

if enoughGoldForDecoy() and peasant.distanceTo(enemy) < 15 and enemy.target == peasant:

The order of these three conditions is the problem. You need to check if a peasant is an enemy target first, then check if there’s enough gold to build a decoy, then check distance. When these conditions are ordered properly, the code works fine.