[SOLVED] Library Tactician - Python Help

Heres my code:

# 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)
    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
    enemies = hero.findEnemies()
    
    # Figure out which enemy has the most health, and set bestTarget to be that enemy.
    enemyIndex = 0
    # While enemyIndex is less than the length of enemies:
    while enemyIndex < len(enemies):
        # Set an enemy variable to enemies[enemyIndex]
        enemy = enemies[enemyIndex]
        # If enemy.health is greater than strongestHealth
        if enemy.health > strongestHealth:
            # Set `strongest` to enemy
            # Set strongestHealth to enemy.health
            bestTarget = enemy
            mostHealth = enemy.health
        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.
    acherTarget = findStrongestTarget()
    for i in range(len(soldiers)):
        soldier = soldiers[i]
        commandSoldier(soldier, i, len(soldiers));
    # use commandArcher() to command your archers
    commandArcher()

For some reason I lose and it says Try hero.findNearestEnemy() on line 44. Can someone please help me?

Btw line 44 is nearest = archer.findNearestEnemy()

The problem is in your ‘while true’ block. You did identify and iterate your soldiers, but what about the archers? It is throwing that error because it does not know what ‘archer’ is, on line 44.

I identified my archers, but how do I itinerate through them? Heres my new code:

# 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)
    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
    enemies = hero.findEnemies()
    
    # Figure out which enemy has the most health, and set bestTarget to be that enemy.
    enemyIndex = 0
    # While enemyIndex is less than the length of enemies:
    while enemyIndex < len(enemies):
        # Set an enemy variable to enemies[enemyIndex]
        enemy = enemies[enemyIndex]
        # If enemy.health is greater than strongestHealth
        if enemy.health > strongestHealth:
            # Set `strongest` to enemy
            # Set strongestHealth to enemy.health
            bestTarget = enemy
            mostHealth = enemy.health
        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.health > 15:
        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")
    archers = hero.findByType("archer")
    # Create a variable containing your archers.
    acherTarget = findStrongestTarget()
    for i in range(len(soldiers)):
        soldier = soldiers[i]
        commandSoldier(soldier, i, len(soldiers));
    # use commandArcher() to command your archers
    commandArcher()

The same way you did your soldiers.

Ok, now I’m really confused because I did that but now it says Line 46: ReferenceError: bestTarget is not defined even though I literally just defined it in the function right above it.

# 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)
    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
    enemies = hero.findEnemies()
    
    # Figure out which enemy has the most health, and set bestTarget to be that enemy.
    enemyIndex = 0
    # While enemyIndex is less than the length of enemies:
    while enemyIndex < len(enemies):
        # Set an enemy variable to enemies[enemyIndex]
        enemy = enemies[enemyIndex]
        # If enemy.health is greater than strongestHealth
        if enemy.health > strongestHealth:
            # Set `strongest` to enemy
            # Set strongestHealth to enemy.health
            bestTarget = enemy
            mostHealth = enemy.health
        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()
    findStrongestTarget()
    if bestTarget and bestTarget.health > 15:
        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")
    archers = hero.findByType("archer")
    # Create a variable containing your archers.
    acherTarget = findStrongestTarget()
    for i in range(len(soldiers)):
        soldier = soldiers[i]
        commandSoldier(soldier, i, len(soldiers));
    # use commandArcher() to command your archers
    for i in range(len(archers)):
        archer = archers[i]
        commandArcher(archer, i, len(archers));

Ok, in your findStrongestHealth definition, where you have:

if enemy.health > strongestHealth:

where is strongestHealth declared, or defined?

Oh, I see what you mean now. Hmm…

I don’t know what to do, but in case someone can help me, here’s my code:

# 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)
    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
    enemies = hero.findEnemies()
    
    # Figure out which enemy has the most health, and set bestTarget to be that enemy.
    enemyIndex = 0
    # While enemyIndex is less than the length of enemies:
    while enemyIndex < len(enemies):
        # Set an enemy variable to enemies[enemyIndex]
        enemy = enemies[enemyIndex]
        # If enemy.health is greater than strongestHealth
        if enemy.health > strongestHealth:
            # Set `strongest` to enemy
            # Set strongestHealth to enemy.health
            bestTarget = enemy
            mostHealth = enemy.health
        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()
    findStrongestTarget()
    if bestTarget and bestTarget.health > 15:
        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")
    archers = hero.findByType("archer")
    # Create a variable containing your archers.
    acherTarget = findStrongestTarget()
    for i in range(len(soldiers)):
        soldier = soldiers[i]
        commandSoldier(soldier, i, len(soldiers));
    # use commandArcher() to command your archers
    for i in range(len(archers)):
        archer = archers[i]
        commandArcher(archer, i, len(archers));

If someone could just tell me the answer that would be great because I’ve been on this levelfor about two weeks and cannot get past it. It is really frustrating.

Sorry, that’s not what we’re here for. We will help, guide and teach, but we won’t just give a solution.

So, your previous problem still exists…you have ‘if enemy.health > strongestHealth:’. Even though the comments guide you to use ‘strongestHealth’, this is not defined anywhere in your code. Instead, you have defined the variable as ‘mostHealth’…try using this one instead.

Still doesn’t work. What else can I do?

Why is it not working?..any errors, or are soldiers dieing? If your soldiers get below a certain health, have them defend a spot close to Hushbaum…she will heal them and they can then move back in to position.

I’m not getting any errors but I will try to make them move back.

Well here is my new definition of commandSoldiers:

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": 41, "y": 40})

But it didn’t do anything different so is there something I did wrong?

Well, that looks almost perfect…the only difference is I have “x”: 42, rather than 41 and I don’t think that is a problem. Try it tho, just in case.

I used a different method to iterate, but otherwise your code looks pretty solid. If that change does not resolve, post your code again, and I’ll try running it to see if I can find the issue.

Do you press [RUN] buttom or [SUBMIT] button?

Both. It doesn’t work and I have resubmitted about 20 times.

Now it says Line 51: Reference Error: bestTarget is not defined

# 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": 42, "y": 40})

# 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
    enemies = hero.findEnemies()
    
    # Figure out which enemy has the most health, and set bestTarget to be that enemy.
    enemyIndex = 0
    mostHealth = 0
    # While enemyIndex is less than the length of enemies:
    while enemyIndex < len(enemies):
        # Set an enemy variable to enemies[enemyIndex]
        enemy = enemies[enemyIndex]
        
        # If enemy.health is greater than strongestHealth
        if enemy.health > mostHealth:
            # Set `strongest` to enemy
            # Set strongestHealth to enemy.health
            bestTarget = enemy
            mostHealth = enemy.health
        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()
    findStrongestTarget()
    if bestTarget and bestTarget.health > 15:
        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")
    archers = hero.findByType("archer")
    # Create a variable containing your archers.
    acherTarget = findStrongestTarget()
    for i in range(len(soldiers)):
        soldier = soldiers[i]
        commandSoldier(soldier, i, len(soldiers));
    # use commandArcher() to command your archers
    for i in range(len(archers)):
        archer = archers[i]
        commandArcher(archer, i, len(archers));

I changed this problem line and your code worked fine.

if bestTarget and bestTarget.health > 15:
        hero.command(archer, "attack", archerTarget)

archerTarget defined by function, as instructions says.

# Set archerTarget to be the target that is returned by findStrongestTarget()
        archerTarget = findStrongestTarget()

So, try to change line №51 with target your archer attacks in line №52.