Backwoods Treasure Code


#1

So, I’m fairly new to CodeCombat as well as Python, just started yesterday and am doing well, but I encountered a problem when trying to tackle the Backwoods Treasure level. Could you guys help me out by any chance?

here is my code:

loop:
    enemy = hero.findNearestEnemy()
    if enemy:
        if hero.isReady("cleave"):
            hero.cleave(enemy)
    else:
        hero.attack(enemy)


loop:
    item = hero.findNearestItem()
    if item.type == "coin":
        hero.moveXY(item.pos.x, item.pos.y)

#2

Be careful with indents. In your case your hero attack enemy if there is no enemy, because “else” is placed on the same level as the first “if”.


#3

Basically, im just trying to earn extra gems for better stuff, and i need help with some new code im trying out, anyone able to help me with it?

def findandpickupitems():
    loop:
        enemy = hero.findNearestEnemy()
        
        item = hero.findNearestItem()
        if item and not enemy:
            hero.moveXY(item.pos.x, item.pos.y)
        elif item and enemy:
            continue
        if item and nearestItemDistance() < nearestEnemyDistance():
            hero.moveXY(item.pos.x, item.pos.y)
        elif item and nearestItemDistance() > nearestEnemyDistance():
            attackandcontinue()


loop:
    
    def nearestEnemyDistance():
        enemy = hero.findNearestEnemy()
    result = 0
    if enemy:
        result = hero.distanceTo(enemy)
    return enemyResult

def nearestItemDistance():
    item = hero.findNearestItem()
    result = 0
    if item:
        result = hero.distanceTo(item)
    return itemResult

enemyResult = nearestEnemyDistance()
itemResult = nearestItemDistance()

def attackandcontinue():
    loop:
        enemy = hero.findNearestEnemy()
        if enemy and enemy.type == "headhunter" or "brawler" or "ogre" and enemy.health > 0:
            hero.attack(enemy)
            if enemy.health == 0:
                continue
            elif enemy.health != 0:
                ready = hero.isReady("chain-lightning")
                if ready:
                    hero.cast("chain-lightning", target)
                elif not ready:
                    ready = hero.isReady("bash")
                    if ready:
                        hero.bash(enemy)
                    elif not ready:
                        continue
        elif not enemy:
            break
    
    enemy = hero.findNearestEnemy()
        
    item = hero.findNearestItem()
    if item and not enemy:
        hero.moveXY(item.pos.x, item.pos.y)
    elif item and enemy:
        pass
    if item and nearestItemDistance() < nearestEnemyDistance():
        hero.moveXY(item.pos.x, item.pos.y)
    elif item and nearestItemDistance() > nearestEnemyDistance():
        attackandcontinue()

#4

It looks like you’ve defined a function inside a loop and put loops inside functions. I’ve never seen that before. I don’t believe you can do that.


#5

Have you passed the first level of Backwoods Treasure? Your code is too complicated and moveXY has also a hidden loop inside it. rewrote a simplified version of your idea :

startPos = {'x': hero.pos.x, 'y': hero.pos.y}        
def findAndPickUpItems():
    enemy = hero.findNearestEnemy()        
    item = hero.findNearestItem()
    if item:
        iDistance = hero.distanceTo(item)
    if enemy:
        eDistance = hero.distanceTo(enemy)
    if item and enemy:
        if iDistance - eDistance > hero.attackRange  :
            hero.move(item.pos)
        else:
            hero.attack(enemy)
    elif item:
        hero.move(item.pos)            
    elif enemy and eDistance <= hero.attackRange :
        hero.attack(enemy)
    else:
        hero.move(startPos)

@MunkeyShynes Is there a better way to implement this structure:

if item and enemy:
    #code1     
elif item:
    #code2
elif enemy:
    #code3
else:
    #code4

#6

You can put loops inside function though, as condition as there is a break somewhere in it. sometime I just make a function when I must repeat myself too much like that:

def move_attack(x, y):
    hero.moveXY(x, y)
    while True:
        enemy = hero.findNearestEnemy()
        if enemy: hero.attack(enemy)
        else: break

move_attack(71, 32), move_attack(50, 76), move_attack(106, 34), move_attack(130, 109), move_attack(21, 103)

#7

@Gabriel_Dupuis But if you use an explicit or hidden ( as moveXY ) loop inside the main loop all your other troops freeze ( soldiers, peasants …) , is that right?


#8

yes while loop will prevent any other code outside the loop to execute.
so for example if you want the minions to act, well you’ll have to put that inside the loop too.