Алмазная дюжина. Пустыня Сарвен

Бодрого времени суток. Покурил весь форум на данную тему, так и не получается решить задачку. Вроде и одел боты + кольцо скорости, герой бегает подбирает монетки золотые и даже “джемы”, но цель “НЕ ЗАВЕРШАЕТСЯ”. Максимум удается набрать ценность около 58 золота.

Пишу код только тот что нужно было решить:

# Собирай монеты, разгоняя мародёрствующих огров.
# Возврати предмет с наибольшим значением `valueOverDistance(item)`.
def findBestItem(items):
    bestItem = None
    bestValue = 0
    itemsIndex = 0
    
    # Перебери массив предметов.
    # Найди предмет с наибольшим значением `valueOverDistance()`.
    while itemsIndex < len(items):
        item = items[itemsIndex]
        if item.value > bestValue:
            bestItem = item
            bestValue = item.value
        itemsIndex += 1

    return bestItem

Не пойму, где ошибка?

Как насчет функции valueOverDistance? Для моего решения я объединил две функции в одну. Я использовал цикл for, а не какое-то время, но это, скорее всего, вопрос предпочтений … в противном случае ваш код выглядит хорошо, за исключением того, что не используется другая функция.

English

How about the valueOverDistance function? For my solution, I combined the two functions in to a single one. I used a for loop, rather than a while, but that is likely a matter of preference…otherwise, your code looks good, except for not using the other function.

К сожалению, цикл for еще не проходится… не умею я его пользовать в питоне.
Вот весь код:

# Собирай монеты, разгоняя мародёрствующих огров.

def findMostHealth(enemies):
    target = None
    targetHealth = 0
    enemyIndex = 0
    while enemyIndex < len(enemies):
        enemy = enemies[enemyIndex]
        if enemy.health > targetHealth:
            target = enemy
            targetHealth = enemy.health
        enemyIndex += 1
    return target

def valueOverDistance(item):
    return item.value / hero.distanceTo(item)

# Возврати предмет с наибольшим значением `valueOverDistance(item)`.
def findBestItem(items):
    bestItem = None
    bestValue = 0
    itemsIndex = 0
    
    # Перебери массив предметов.
    # Найди предмет с наибольшим значением `valueOverDistance()`.
    while itemsIndex < len(items):
        item = items[itemsIndex]
        if item.value > bestValue:
            bestItem = item
            bestValue = item.value
        itemsIndex += 1

    return bestItem

while True:
    enemies = hero.findEnemies()
    enemy = findMostHealth(enemies)
    if enemy and enemy.health > 15:
        while enemy.health > 0:
            hero.attack(enemy)
    else:
        coins = hero.findItems()
        coin = None
        coin = findBestItem(coins)
        if coin:
            hero.moveXY(coin.pos.x, coin.pos.y)

Честно говоря, не совсем понятно зачем тут (в функции valueOverDistance) нахождение среднего оптимального соотношения ценности предмета к его дистанции:

**return item.value / hero.distanceTo(item)**

Нужно же собирать максимальную монету а не “усредненную”…

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

Я напишу вам мой код функции, чтобы вы могли сравнить.

English

It prevents the hero from chasing all over the map, grabbing the highest value item only. With the formula in the function, it weighs the value against how far away it is, allowing the hero to pick something closer, even though it might be of lesser value. Eventually, he should be close enough to the original item to make it worthwhile to grab it.

I will PM you my function code, so you can compare.

Спасибо за ваш код. Я подставил его в свой - и все получилось. Действительно цикл for - более читаемый и простой.
Но, что странно: в вашем случае герой собрал 58 value и в моем коде, тоже - 58.
Короче, я так и не разобрался в чем ошибка?

Когда я запускаю свой код, он собирает около 68 или около того. Я предполагаю, что движок фоновой игры проверяет, выбираете ли вы оптимальную монету или просто выбираете самую высокую. Таким образом, сумма сбора может варьироваться, но пока вы получаете оптимальную монету, у вас все получится.

English

When I run my code, he collects around 68 or so. I’m guessing that the background game engine is testing to see if you pick the optimal coin, or just go for the highest value one. So, the collection amount might vary, but so long as you get the optimal coin, you succeed.

Без этой функции цели прохождения не засчитываются успешными.
А засчитывается так:

bestItem = hero.findNearestItem()

if valueOverDistance(item) > valueOverDistance(bestItem):

(ну и дальше по шаблону)