Library Tactician Help (Aug '17)

I suspect this is a bug, but don’t want to jump to conclusions. Just running the premade script for the commandArcher function is giving me an error:

I mean, archer is already defined by the function itself, right? Why wouldn’t the function recognize the archer and use its findNearestEnemy?

1 Like

I think it meant to be nearest = archer.findNearest(archer.findEnemies()) not
nearest = archer.findNearestEnemy().

Can you post me your full code please.

Whoops, responded to the wrong post. Gimme a minute, I’ll fetch the code.

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.
    for e in enemies:
        if e.health > mostHealth:
            mostHealth = e.health
            bestTarget = e
    # 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(a):
    nearest = a.findNearest(a.findEnemies())
    if archerTarget:
        hero.command(a, "attack", archerTarget)
    elif nearest:
        hero.command(a, "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 a in range(len(archers)):
        archer = archers[i]
        commandArcher(archer)
    
    if archerTarget:
        hero.attack(archerTarget)
    else:
        z = hero.findNearestEnemy()
        if z:
            hero.attack(z)

It’s fine.
20 characters

Try changing it to if not archerTarget or archerTarget.health < 1:

I don’t think you need that.

Wouldn’t that have my hero attack the nearest enemy if there’s no archerTarget then? Otherwise, (s)he’d just sit idle.

Your hero is not oppose to attack and also you already command the archers to attack.

But if my hero has long-range capabilities, why shouldn’t I be throwing them in? Also, why should that be making the code crash in a separate part of the code?

You are not meant to use your hero because that is cheating.

I don’t get what you mean.

In your while True: loop:

Rename the variable a in for a in range(len(archers)): to i so it matches up with i in archer = archers[i]


If the target is out of the hero’s attack range and line of sight, then the while True: loop will be stuck on hero.attack(archerTarget) or hero.attack(z) as your hero tries to move to a position so it can attack the target. Either skip the code for your hero attacking enemies entirely or try implementing a check for enemies within your hero’s attack range and line of sight (I don’t have ranged heroes available, so I can’t check if this works).

2 Likes

@byobcello That did the trick. Thanks.