Diamond Dozen always non optimal

Hi,
I’m trying to complete the Diamond Dozen level.

I believe my code is working in that it is going for the item with the best value/distance ratio but I never pass the level, message says ‘Didn’t collect the optimal amount of coins’

if it’s a question of which weapon or other item to use then I’ve no idea which combination should be used (and that doesn’t seem fair as it’s a totally random choice)

If it is however my rubbish coding then can someone give me a clue please as I think the value optimisation part of the code is correct.

Many thanks,

Below is the code I am currently trying

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):
    if items[itemsIndex].value>bestValue:
        bestItem=items[itemsIndex]
        bestValue=bestItem.value
    itemsIndex += 1
return bestItem

def bestAtt(enemy):
while enemy.health>0:
#if hero.isReady(“jump”):
#hero.jumpTo(enemy)
if hero.canCast(“chain-lightning”, enemy):
hero.cast(“chain-lightning”, enemy)
elif hero.isReady(“cleave”) and hero.distanceTo(enemy)<5:
hero.cleave(enemy)
else:
hero.attack(enemy)

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

1 Like

At the moment your code is not formatted properly, so you can’t see your indentation. To format your code, press this button33 Then this should appear.
37
put all your code where it says "type or paste code here’. Then we will be able to see your indentation, and be able to help you.

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):
        if items[itemsIndex].value>bestValue:
            bestItem=items[itemsIndex]
            bestValue=bestItem.value
        itemsIndex += 1
    return bestItem

def bestAtt(enemy):
    while enemy.health>0:
        #if hero.isReady("jump"):
           #hero.jumpTo(enemy)
        if hero.canCast("chain-lightning", enemy):
            hero.cast("chain-lightning", enemy)
        elif hero.isReady("cleave") and hero.distanceTo(enemy)<5:
            hero.cleave(enemy)
        else:
            hero.attack(enemy)

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

Thanks Brenin sorry about that

2 Likes

Just to let you know I’m using boots of jumping, long sword and emperors gloves

1 Like

Your code runs successfully with my equipment after replacing the last row

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

I always replace moveXY with move when possible. MoveXY has a hidden loop inside it and it’s blocking or slowing some actions

3 Likes

Hello, everything is right except for the findBestCoin() function, you should define item in that function like you defined enemy in the first one, also the

if items[itemsIndex].value > bestValue:
    bestItem = items[itemsIndex]
    bestValue = bestItem.value

the .value part of that is wrong, it’s using distance as well, not just value, but you made a function for that earlier and you just put your item variable in the brackets of the function that you made. (it’s the one your not using)
hope this helps :grin:

1 Like

I emulated the function findBestItem(items) and it seems right to me.
Edit: @Deadpool198 yes, the function "valueOverDistance() " is never used.
So, if you want to follow the predefined logic in the while loop you put findBestItem(items) function:

    while itemsIndex < len(items):
        item = items[itemsIndex]
        valOverDistance = valueOverDistance(item)
        if valOverDistance  > bestValue:
            bestItem = item
            bestValue = valOverDistance
        itemsIndex += 1
3 Likes

I changed it to move but the hero still does not reach the coin in time I have the fine boots and no ring

1 Like

Still?

Because i have same problem:/

@yigit please don’t revive dead topics this was from two or three years back.

1 Like

And if you need help please post your code

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

# Return the item with the highest valueOverDistance(item)
def findBestItem(items):
    bestItem = None
    bestValue = 0
    itemsIndex = 0
    
    while itemsIndex < len(items):
        item = items[itemsIndex]
        valOverDistance = valueOverDistance(item)
        if valOverDistance > bestValue:
            bestItem = item
            bestValue = valOverDistance
        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.move(coin.pos)

I am using the compound boots for the move function.

Nevermind. I solved it on my own.