[SOLVED ] Library Tactician

Why is commandArcher(archer) showing error? what else I should do cross this level?

# Hushbaum has been ambushed by ogres!
# She is busy healing her soldiers, you should command them to fight!
# The ogres will send more troops if they think they can get to Hushbaum or your archers, so keep them inside the circle!

# Soldiers spread out in a circle and defend.
def commandSoldier(soldier, soldierIndex, numSoldiers):
    angle = Math.PI * 2 * soldierIndex / numSoldiers
    defendPos = {"x": 41, "y": 40}
    defendPos.x += 10 * Math.cos(angle)
    defendPos.y += 10 * Math.sin(angle)
    if (soldier.health > 60):
        hero.command(soldier, "defend", defendPos)
    else:
        hero.command(soldier, "defend", {'x': 45, 'y': 42})
        #hero.command(soldier, "defend", defendPos);

# Find the strongest target (most health)
# This function returns something! When you call the function, you will get some value back.
def findStrongestTarget():
    mostHealth = 0
    bestTarget = None
    enemyIndex = 0
    enemies = hero.findEnemies()
    # Figure out which enemy has the most health, and set bestTarget to be that enemy.
    while enemyIndex < len(enemies):
        if enemies[enemyIndex].health < bestHealth:
            bestHealth = enemies[index].health
            bestTarget= enemies[enemyIndex]
            enemyIndex += 1
    # Only focus archers' fire if there is a big ogre.
    if bestTarget and bestTarget.health > 15:
        return bestTarget
    else:
        return None


# If the strongestTarget has more than 15 health, attack that target. Otherwise, attack the nearest target.
def commandArcher(archer):
    nearest = archer.findNearestEnemy()
    if archerTarget:
        hero.command(archer, "attack", archerTarget)
    elif nearest:
        hero.command(archer, "attack", nearest)

archerTarget = None

while True:
    # If archerTarget is defeated or doesn't exist, find a new one.
    if not archerTarget or archerTarget.health <= 0:
        # Set archerTarget to be the target that is returned by findStrongestTarget()
        archerTarget = findStrongestTarget()
    
    friends = hero.findFriends()
    soldiers = hero.findByType("soldier")
    # Create a variable containing your archers.
    archers= hero.findByType("archer")
    for i in range(len(soldiers)):
        soldier = soldiers[i]
        commandSoldier(soldier, i, len(soldiers))
    # use commandArcher() to command your archers
    commandArcher(archer)

To focus on that code block:

def commandArcher(archer):
    nearest = archer.findNearestEnemy()
    if archerTarget:
        hero.command(archer, "attack", archerTarget)
    elif nearest:
        hero.command(archer, "attack", nearest)

What is archerTarget equal to?

hi Thanks for your reply.

I tried both findStrongestTarget() and best target separately but still does not work.

def commandArcher(archer):
    nearest = archer.findNearestEnemy()
    archerTarget = bestTarget
    if archerTarget:
        hero.command(archer, "attack", archerTarget)
    elif nearest:
        hero.command(archer, "attack", nearest)

I tried this too

def commandArcher(archer):
    nearest = archer.findNearestEnemy()
    archerTarget = findStrongestTarget()
    if archerTarget:
        hero.command(archer, "attack", archerTarget)
    elif nearest:
        hero.command(archer, "attack", nearest)

Oh, sorry about that, I didn’t notice the second part. Yes, the first part should be archerTarget = findStrongestTarget()

Notice how you coded for the soldiers? You need to do the same for the archers. Define the array of archers and iterate through it.

It leads to an infinite loop

for j in range(len(archers)):
        archer= archers[j]
        # use commandArcher() to command your archers
        commandArcher(archer, j, len(archers))

I’m thinking it has to do with indentation or placement…post your entire code again please, so I can take a closer look.

let me check and comeback pls


# Hushbaum has been ambushed by ogres!
# She is busy healing her soldiers, you should command them to fight!
# The ogres will send more troops if they think they can get to Hushbaum or your archers, so keep them inside the circle!

# Soldiers spread out in a circle and defend.
def commandSoldier(soldier, soldierIndex, numSoldiers):
    angle = Math.PI * 2 * soldierIndex / numSoldiers
    defendPos = {"x": 41, "y": 40}
    defendPos.x += 10 * Math.cos(angle)
    defendPos.y += 10 * Math.sin(angle)
    if (soldier.health > 60):
        hero.command(soldier, "defend", defendPos)
    else:
        hero.command(soldier, "defend", {'x': 40, 'y': 42})
        

# Find the strongest target (most health)
# This function returns something! When you call the function, you will get some value back.
def findStrongestTarget():
    mostHealth = 0
    bestTarget = None
    enemyIndex = 0
    enemies = hero.findEnemies()
    # Figure out which enemy has the most health, and set bestTarget to be that enemy.
    while enemyIndex < len(enemies):
        if enemies[enemyIndex].health < bestHealth:
            bestHealth = enemies[index].health
            bestTarget= enemies[enemyIndex]
            enemyIndex += 1
    # Only focus archers' fire if there is a big ogre.
        if bestTarget and bestTarget.health > 15:
            return bestTarget
        else:
            return None


# If the strongestTarget has more than 15 health, attack that target. Otherwise, attack the nearest target.
def commandArcher(archer):
    nearest = archer.findNearestEnemy()
    archerTarget = findStrongestTarget()
    if archerTarget:
        hero.command(archer, "attack", archerTarget)
    elif nearest:
        hero.command(archer, "attack", nearest)



while True:
    # If archerTarget is defeated or doesn't exist, find a new one.
    if not archerTarget or archerTarget.health <= 0:
        # Set archerTarget to be the target that is returned by findStrongestTarget()
        archerTarget = findStrongestTarget()
    
    friends = hero.findFriends()
    soldiers = hero.findByType("soldier")
    # Create a variable containing your archers.
    archers= hero.findByType("archer")
    for i in range(len(soldiers)):
        soldier = soldiers[i]
        commandSoldier(soldier, i, len(soldiers))
    for j in range(len(archers)):
        archer= archers[j]
        # use commandArcher() to command your archers
        commandArcher(archer, j, len(archers))
    

I just ran that and it works! Have you tried Submitting yet? If it failed, keep trying…some times you get an unlucky seed.

ok, lemme check. Really appreciate the help.

Oh, I just noticed one other oddity…you are passing three arguments to the commandSoldier function, this is proper. You are also passing three to the commandArcher function, which is not…it is written to only accept one.

it worked!

regarding the 3 arguments: so I should only call commandArcher(archer). But I thought as I have put an array there too so I do the same as the soldier. So i shall call only the commandArcher() function to make it right. Correct?

Correct. I’m not positive on this, but I think because commandArcher is only expecting one, it ignored the other two. But yes, the proper coding would be to send only ‘archer’ as the single argument.

Good job too! :smiley:

Thank you very much! :smile:

1 Like

“Correct. commandArcher is only expecting one, it ignored the other two” - correct only for CoCo Python Grim determination help 2

2 Likes