Помогите пройти "Деревенский защитник" (Python)


#1

Постоянно выдаёт ошибку image, но я не понимаю, что мне надо сделать, что бы код нормально запустился.

# Манчкины наступают! Защити поселение!

# Определи собственную функцию, чтобы сразиться с врагом!
def cleaveOrAttack():
    # Внутри функции найди врага, затем руби или атакуй его.
    while True:
        enemy = hero.findNearestEnemy()
        if enemy:
            if hero.isReady("cleave"):
                hero.cleave()
        else:
            hero.attack(enemy)      #ошибка вот в этой строке
        pass

# Двигайся между патрульными точками и вызывай функцию.
while True:
    hero.moveXY(35, 34)
    # Используй функцию `cleaveOrAttack`, которая определена выше.
    cleaveOrAttack()
    hero.moveXY(47, 27)
    # Повторно вызови функцию.
    cleaveOrAttack()
    hero.moveXY(60, 31)
    # Повторно вызови функцию.
    cleaveOrAttack()

#2

Попробуйте так:

            if hero.isReady("cleave"):
                hero.cleave()
            else:
                hero.attack(enemy)      #ошибка вот в этой строке```

#3

Неа, мимо :sleepy:
Там проблема именно в строке hero.attack(enemy). Наверное, нужно сделать так, чтоб герой, не найдя врага, шёл дальше и код не останавливался на этой строке. Только я не знаю как.

Уже несколько часов бьюсь над этой проблемой. Уже и прохождения гуглил, и советы перечитывал раз 5, и на английском пытался найти прохождение. Всё мимо.


#4

Эмм, а можно прямой линк на уровень?


#5

Попробуйте так:

def cleaveOrAttack():
    while True:
        enemy = hero.findNearestEnemy()
        if enemy:
            if hero.isReady("cleave"):
                hero.cleave(enemy)  # <--- это была проблема
            else:
                hero.attack(enemy)

#6

https://codecombat.com/play/level/village-champion?


#7

Вау, сработало. Правда всё равно не так, как должно было. Герой должен был бегать по маркерам, но в итоге он просто метался от противника к противнику. Но всё равно спасибо.


#8
def cleaveOrAttack():
    enemy = hero.findNearestEnemy()
    if enemy:
        hero.attack(enemy)
        if hero.isReady("cleave"):
            hero.cleave()

В таком варианте бегает по маркерам)
Переписал только функцию, петля без изменений.


#9

Вау. Это работает, как и должно работать. А я ведь думал сначала атаку поставить, а потом клив, но так и не реализовал. А если бы и реализовал, то там бы надо было убирать цикл.

Спасибо Вам. Оставлю ваше решение.


#10

Не за что)
Изначальная проблема была даже не в последовательности атак, а в структуре кода.
В Вашей функции:

получается следующая логическая неувязка с условиями:

если есть враг:
    если готова способность рубить:
        рубить врага
иначе: # =если врага нет
    атаковать врага     

Герой не может атаковать врага, которого нету согласно самому условию) Об этом красное предупреждение и сообщало) В целом, дальше на уровнях это была одна из самых частых моих ошибок - перед тем, как что-то делать с врагом/предметом/союзником, нужно проверять, существует ли он.
Поэтому исправляем табуляцию в условиях функции:

если есть враг:
    если готова способность рубить:
        рубить врага
    иначе: # =если способность рубить НЕ готова
        атаковать врага

В таком варианте красных предупреждений нет и герой уже как-то нападает на врагов. Но он не ходит по меткам и может проиграть из-за применения “рубить” перед атакой == некоторые враги выживают на расстоянии и убивают крестьян. Делаем тактический бантик и меняем атаку и “рубить” местами - чтобы враги подошли на расстояние первого удара мечом и потом точно доставались рубкой. Ну, или можно чуть усложнить и поиграть с дистанцией, не меняя атаку и “рубить” местами.

def cleaveOrAttack():
    while True:
        enemy = hero.findNearestEnemy()
        if enemy:
            distance = self.distanceTo(enemy)
            if self.isReady("cleave") and distance < 10:
                hero.cleave()
            hero.attack(enemy)

Тогда герой уже выполняет задания и проходит уровень, но всё ещё не ходит по меткам)
А здесь собака порылась в “while True” в функции. Тут моих знаний недостаточно, чтобы адекватно объяснить проблематику циклов в цикле, но если убрать “while True” из функции - всё становится совсем красиво)