Help with Diamond Dozen

My code can’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

Make a function named findOptimalCoin which returns the coin with the best value.

Coins rapidly appear and disappear, so pick the best coin.

Optimize your path by going for the coin with the largest value over distance.

def findOptimalCoin(coins):
coin = None
V=0
D=1
coinIndex=0
while coinIndex < len(coins):
coin=coins[coinIndex]
if coin.value/hero.distanceTo(coin)>V/D:
coin=coin
V=coin.value
D=hero.distanceTo(coin)
coinIndex += 1
return coin
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 = findOptimalCoin(coins)
if coin:
hero.moveXY(coin.pos.x, coin.pos.y)

1 Like

It’s hard to tell what your exact problem is due to the fact you didn’t format your code correctly

(select it and use this )

I do see a problem your findOptmialCoin function. You use the same variable name twice, so when it will always return the last coin in the array. Use a separately named variable like bestCoin to avoid this:

while coinIndex < len(coins):
    coin = coins[coinIndex]
    if coin.value/hero.distanceTo(coin)>V/D:
       bestCoin = coin
       #put the rest of the function here
return bestCoin

1 Like

There are some problems with this level, but I passed it.
First - you need the fast sword. The best swords are to slow, so coins are disappear before hero can move. So use some of the weak swords.
Second - you need not only move. Hero to slow. Jump on the coin.
https://github.com/vadim-job-hg/CodeCombat/blob/master/Desert/DiamondDozen.py

1 Like

I do have time issues on Diamond Dozen. I’m not fast enough in about a third of all coin appearances. Even moving the the closest coin would not help me.
The problem might be, that I don’t have a clue how to jump or use a faster sword.

1 Like

Thank you all so much.
I already passed it by changing a lighter sword.
and I have question on"prime pathing" now.
here is the link:

1 Like

Does your code work? it seems does not work in my computer.

1 Like
// Claim the coins while defeating the marauding ogres.
// If you defeat the ogre with the most health, the rest of the ogres will run!
// Coins vanish quickly after appearing, so be sure to find the best value!

function findMostHealth(enemies) {
    var target = null;
    var targetHealth = 0;
    var enemyIndex = 0;
    while(enemyIndex < enemies.length) {
        var enemy = enemies[enemyIndex];
        if(enemy.health > targetHealth) {
            target = enemy;
            targetHealth = enemy.health;
        }
        enemyIndex += 1;
    }
    return target;
}

// Make a function named findOptimalCoin which returns the coin with the best value.
// Coins rapidly appear and disappear, so pick the best coin.
// Optimize your path by going for the coin with the largest value over distance.
function findOptimalCoin(coins){
    var coinIndex = 0;
    var optimal = 0;
    var best;
    while(coinIndex < coins.length) {
        var distance = hero.distanceTo(coins[coinIndex]);
        var value = coins[coinIndex].value;
        if((value / distance) > optimal){
            optimal = value / distance;
            best = coins[coinIndex];
        }
        coinIndex++;
    }
    return best;
}

while(true) {
    var enemies = hero.findEnemies();
    var enemy = findMostHealth(enemies);
    if(enemy && enemy.health > 15) {
        while(enemy.health > 0) {
            hero.attack(enemy);
        }
    } else {
        var coins = hero.findItems();
        var coin = null;
        coin = findOptimalCoin(coins); // ∆ Uncomment this once you've written the function.
        if(coin) {
            var ready = hero.isReady("jump");
            ready? hero.jumpTo(coin) : hero.moveXY(coin.pos.x, coin.pos.y);
        }
    }
}

I noticed that the methods that worked didn’t really make sense to me and I had to spend a lot of time just trying to figure out what the methods were doing. For future reference, you should never name your variables things like a, b, and c. Additionally, I did notice that if you have an ability like jump in your equipment then the algorithm will count that. So, even if it isn’t equipped and just in your equipment it will still be part of the equation. Therefore you need to add the conditional to utilize jump if it is ready.

2 Likes

I am having trouble with this level as well. I used the suggestions here already (it seems to come now with some guidance on choosing the enemy with most health to attack and finding the optimal coin to go to), but the coins are disappearing before I can get to them most of the time. If I don’t use the powerful Runesword (even with the long cooldown) it is even worse.

I tried using boots with jump or dash abilities, but these abilities seem broken and do not reach the coin either.

I tried using a different hero to see if it would make a speed difference, but that didn’t help.

Any ideas?

–Zack

1 Like

I can beat this level with the Reinforced Boots (very slow movement speed,) or Softened Leather Boots + Ring of Speed (super duper fast).

Link your code with 3x ( ` ) before and after your code so it is properly formatted.

1 Like

Hi Serg,

My Ring of Speed doesn’t seem to speed up much. Also, can you please be more specific about the comment about linking? I’m not sure what you mean.

Thanks–
Zack

1 Like

Copy and paste your code but use 3x backticks ( ` ) before and after your code so your code formats properly.

1 Like

You can only jump if you have “Boots of Jumping” or “Boots of Leaping”.
Second, you can find how fast a sword is comparing the DPS in the item description to damage per hit. For example, if a sword does 10 damage per hit, and 50 per second, that means you can attack 5 times with the sword.

1 Like

my coin in coin.pos.x and coin.pos.y are null for some reason hears my code

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 findOptimalCoin(coins):
    coinIndex = 0
    coinValue = 0
    coinDistance = 0
    Optimalcoin = 0
    while len(coins) > coinIndex:
        coin = coins[coinIndex]
        if coin.value/hero.distanceTo(coin) > Optimalcoin:
            coinDistance = hero.distanceTo(coin)
            coinValue = coin.value 
            Optimalcoin = coinValue/coinDistance
        coinIndex += 1
    return Optimalcoin

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 = findOptimalCoin(coins)
        if coin:
            hero.moveXY(item.pos.x, item.pos.y)

1 Like

I tried changing the item.pos.x and item.pos.y to coin.pos.x and coin.pos.y but it didn’t work…

1 Like

you mix 2 functions into one
read instructions:

// Return the item with the highest valueOverDistance(item)

so first write a function to work with value and distance

then

 // Loop over the items array.
    // Find the item with the highest valueOverDistance()

use your function to compare all items and choose one you need

sorry I can’t give you my code, it’s really challenging level

also this code is looks weird

        coins = hero.findItems()
        coin = None //why you need this one?
        coin = findOptimalCoin(coins)

and this

if coin:
            hero.moveXY(item.pos.x, item.pos.y)

need to be coin.pos.x, coin.pos.y

1 Like

also


 Optimalcoin = coinValue/coinDistance
        coinIndex += 1
    return Optimalcoin

so Optimalcoin is : value 10 and distance 5, it’s 10/5.

you return 5;
how it’s help you to find your coin? you need return coin (it’s object), not number

so you need new variable

if coin.value/hero.distanceTo(coin) > Optimalcoin:
            coinDistance = hero.distanceTo(coin)
            coinValue = coin.value 
            Optimalcoin = coinValue/coinDistance
             BestCoin = coin
        coinIndex += 1
    return BestCoin 
1 Like

thanks it works now!

2 Likes

So I’m still lost on this level. I tried using hero.jumpTo(coin) but that has a weird lag time after the jump so that’s a no-go. Here’s my code, formatted. Can someone maybe tell me what I’m not getting?

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
    while itemsIndex < len(items):
        item = items[itemsIndex]
        if valueOverDistance(item) > bestValue:
            bestItem = item
        itemsIndex += 1
    # Loop over the items array.
    # Find the item with the highest valueOverDistance()
    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)

Nevermind. Found the problem. I needed to add (marked with asterisks):

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