[Solved] Diamond Dozen Python help

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(coin):
    return coin.value / hero.distanceTo(coin)

# 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()
    valueOverDistance(coin)
    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)

Is there anything wrong with my code? Is it just the varibles?

findBestItem part is incorrect.

valueOverDistance(coin) just gives the value / distance

Do that.

1 Like
# Claim the coins while defeating the marauding ogres.

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[itemIndex]
        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(coin.pos.x, coin.pos.y)

My guy only attacks the first wave of ogres and nothing else.

A couple of things:

        item = items[itemIndex]

The itemsIndex starts at 0. itemsIndex. Not itemIndex. You forgot the “S”.

Next, you have the assignments of bestItem and bestValue reversed.

this isn’t working

# Claim the coins while defeating the marauding ogres.

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:
            bestItem = item
            bestValue = 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(coin.pos.x, coin.pos.y)

Works for me. Try upgrading your equipment

If you want I can give a screenshot of the hero’s equipment

using movXY you command your hero to move at the exact coin position.

hero.moveXY(coin.pos.x, coin.pos.y)

replace the action with

hero.move(coin.pos) 

and you will grab the coins at arm’s length , so more quickly.
And your boots are really slow, I had made the same mistake buying them. If you insist using moveXY replace them with 2m/s speed boots.

Please explain how it isn’t working. I grabbed the same hero/gear and was able to pass the level. Oddly enough, even when I improved the gear to boots with 2m/s and even the speed ring, the level still took as long.

@xython The hero.moveXY() is part of the starter code. While it can be changed, I don’t know how much it would help on this level. There is a delay between the coin spawn events that makes faster gear minimally more beneficial.

Try and see if there’s a difference :slight_smile:
/Edit - test with slower free hero/

I see what you mean. The hero picks up the item before you actually reach the XY position and the move method will switch to the next item as soon as the original item is picked up while the moveXY will still continue to move to the exact XY. I was able to pick up two items on some of the spawn groups even with the slowest boots and slower free hero. I’m wondering if the moveXY has a slight delay to move to the next item because the hero never even hinted that there was a second item.

Hero: Lady Ida Justheart
boots: Boots of Jumping speed 1.5m/s
no speed ring

Two images below show the move option is quite better. The hero grabbed the gem and did pick up the Gold coin too. While the moveXY only goes to the gem.

two%20for%20one%201 two%20for%20one%202

I tested the level with same boots ( 1.5m/s) and an ordinary hero, but with speed ring, no Boss Star. Used also the function moveToXY from Grab coins with moveXY almost as with move boots . So the gold collected results are:

hero.moveXY(coin.pos.x, coin.pos.y)| hero.move(coin.pos)| moveToXY(coin.pos)
             55 gold               |    63 gold         |       65 gold

The coins seem to have too much randomness in the time that they can despawn. Sometimes the coins stay long enough to collect two in the same group. Sometimes they seem to disappear before I can touch them.

My code also doesn’t work…


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(coin.pos.x, coin.pos.y)


never mind, it works now.