Diamond Dozen Help Please

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)

# Return the item with the highest valueOverDistance(item)
def findBestItem(items):
    bestItem = None
    bestValue = 0
    itemsIndex = 0
    
    # Loop over the items array.
    # Find the item with the highest valueOverDistance()
    while itemsIndex < len(items):
        item = items[itemsIndex]
        if item.value / hero.distanceTo(item) > bestValue:
            bestValue = item
            bestItem = valueOverDistance(item)
        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(findBestItem.pos.x,findBestItem.pos.y)

I don’t know why but it says my “x” in “findBestItem.pos.x” is undefined. Thoughts?

Howdy and welcome to the forum!

I see two problems:

  1. Lines 28 and 29…you have your variables transposed. bestValue should call the valueOverDistance function; bestItem should equal item
  2. Your moveXY statement is not referencing coin.

I corrected these and the code runs properly.

1 Like
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)

# Return the item with the highest valueOverDistance(item)
def findBestItem(items):
    bestItem = None
    bestValue = 0
    itemsIndex = 0
    
    # Loop over the items array.
    # Find the item with the highest valueOverDistance()
    while itemsIndex < len(items):
        item = items[itemsIndex]
        if item.value / hero.distanceTo(item) > bestValue:
            bestValue = valueOverDistance
            bestItem = item
        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)

So I think I fixed it, but now my hero just gets the nearest coin.

You have definitely fixed the moveXY issue, but not quite there on line 28. You should be calling a function on this line and passing item as a variable.

def findBestItem(items):
    bestItem = None
    bestValue = 0
    itemsIndex = 0
    
    # Loop over the items array.
    # Find the item with the highest valueOverDistance()
    while itemsIndex < len(items):
        item = items[itemsIndex]
        if valueOverDistance > bestValue:
            bestValue = valueOverDistance
            bestItem = item
        itemsIndex += 1
    return bestItem

Sorry, but I don’t understand what you mean by “passing item as a variable”

This is from your first code posting:

            bestItem = valueOverDistance(item)

As discussed, bestItem is not the correct variable, so you fixed it with:

            bestValue = valueOverDistance

See the difference? valueOverDistance is the name of a function, which is expecting some object (vairable) to be passed to it when called:

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

item is the object being passed…when you ‘call’ valueOverDistance, you do so by assigning the function call to a new variable name, such as bestValue, however, since valueOverDistance is expecting to be given (passed) something, you need to do so. Something like:

bestValue = valueOverDistance(item)

OK, that makes more sense thank you so much!

1 Like