Python: Library Tactican

Don’t really know what’s going on.

# 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.
    bestTarget = findStrongestTarget()
    enemies = self.findEnemies()
    enemyIndex = 0
    for enemy in enemies:
        if enemy.health > mostHealth:
            bestTarget = enemy
            mostHealth = enemy.health
    # 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.
    
    for i in range(len(soldiers)):
        soldier = soldiers[i]
        commandSoldier(soldier, i, len(soldiers));
    # use commandArcher() to command your archers
    commandArcher()
1 Like

Hi CocoCharlie,

# Create a variable containing your archers.
Do this - look at the line above it if you’re not sure what it should look like.

# use commandArcher() to command your archers
Do this - it will look similar to the for loop that commands the soldiers. Remember that you need something inside the brackets when you call the commandArcher function.

Have a go at doing these things, post your code again if you need more help.

Jenny

3 Likes

Still saying infinite loop…

# 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.
    bestTarget = findStrongestTarget()
    enemies = self.findEnemies()
    enemyIndex = 0
    for enemy in enemies:
        if enemy.health > mostHealth:
            bestTarget = enemy
            mostHealth = enemy.health
    # 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.
    friendd = hero.findByType("archer")
    for i in range(len(soldiers)):
        soldier = soldiers[i]
        commandSoldier(soldier, i, len(soldiers));
    # use commandArcher() to command your archers
    commandArcher(friendd)

Well, that’s better, but the actual cause of the infinite loop is here:

Can you see how you’ve called the findStrongestTarget() function inside the findStrongestTarget() function. This is called recursion, where you call a function inside the function itself, but it causes infinite loops if you don’t stop it. (it comes up properly in the Glacier) Anyway, you don’t want to do it here. You should leave it as bestTarget = None, and get rid of the bestTarget = findStrongestTarget()
About the rest of your code, the friendd function is good: it stores the correct value: hero.findByType(“archer”). However, the commanding of the archers isn’t quite right.
You’ve done:

You’re trying to command an entire array of archers with a function which takes a single archer as input. So how do you separate the friendd array into individual archers? Use a for loop.
You can do the exact same thing as you did with the soldiers for loop, but replacing soldiers with friendd and soldier with whatever you want to call your individual archer which you’ll put into your commandArcher() function.
Danny

4 Likes

it's working much better now, thanks, but it still isn't done. it want's me to use an actual command instead of "q"

# 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.
    enemies = self.findEnemies()
    enemyIndex = 0
    for enemy in enemies:
        if enemy.health > mostHealth:
            bestTarget = enemy
            mostHealth = enemy.health
    # 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
    for q in range(len(archers)):
        archer = archers[q]
        hero.command(archer, q, len(archers));
        

Sometime I’m gonna need the len things and for loops explained, cuz i still don’t get 'em
I’m starting to get the for loops though i think…

problems:

  1. error about command
  2. a man dies

Replace your final line of code with a line calling your commandArchers(archer) function.

Jenny

1 Like

but what about this part??

Replace this line with the code to call your commandArcher function!

Jenny

1 Like

I have nothing for target. enemy is not defined.

hero.command(archer, "attack", enemy);
        

The thing is, they are attacking. but i have an error, and some of my guys die.

Delete this line altogether!

Put in:
commandArcher(archer)

You define the enemy inside the function.

Jenny

2 Likes

same. exact. thing. :weary: :weary:

Can you post your 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.
    enemies = self.findEnemies()
    enemyIndex = 0
    for enemy in enemies:
        if enemy.health > mostHealth:
            bestTarget = enemy
            mostHealth = enemy.health
    # 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
    for q in range(len(archers)):
        archer = archers[q]
        hero.command(archer)

That final line. Have a look at what I said to put in:

commandArcher(archer)

and what you have put in:

hero.command(archer)

Are these the same thing?

Jenny

4 Likes

It worked!!
Thank you!Thank you!Thank you!Thank you!Thank you!Thank you!Thank you!Thank you!Thank you!Thank you!Thank you!Thank you!Thank you!Thank you!Thank you!Thank you!Thank you!Thank you!Thank you!Thank you!Thank you!Thank you!

5 Likes

It’s really slow though…

This topic was automatically closed 12 hours after the last reply. New replies are no longer allowed.