Stuck: Library Tactician

Hi! This is my first time posting so please forgive me if I do anything wrong :smile:
So I’ve been playing on the level Library Tactician and I’ve been stuck. I have looked at the stimulation and the only thing wrong is that my archers won’t target the strongest target.
Here is my 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)
    self.command(soldier, "defend", defendPos);

def findStrongestTarget():
    mostHealth = 0
    bestTarget = None
    enemies = self.findEnemies()
    enemyIndex = 0
    while len(enemies) > enemyIndex:
        enemy = enemies[enemyIndex]
        if enemy:
            enemyIndex += 1
            if enemy.health > mostHealth:
                mostHealth = enemy.health
                bestTarget = enemy
    .
    if bestTarget and bestTarget.health > 15:
        return bestTarget
    else:
        return None



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

loop:
    if self.gold > self.costOf("soldier"):
        self.summon("soldier")
    

    if not archerTarget or archerTarget.health <= 0:
   
        archerTarget = findStrongestTarget()

    friends = self.findFriends()
    soldiers = self.findByType("soldier")
    archers = self.findByType("archers")
    for i, soldier in enumerate(soldiers):
        commandSoldier(soldier, i, len(soldiers));


    for i in range(len(archers)):
        archer = archers[i]
        commandArcher(archer) 

Sorry about the indents, I can’f find a way to indent so i would appreciate if you help me in that too. But my main problem is that I can’t find anything wrong with the code so I would be really (really really really) thankful if you pointed out the mistake. Thanks! :smile:

2 Likes

Click in the Edit button (the pencil icon below your post), select the code and press Ctrl+K (or click in the </> button). :smile_cat:

1 Like

Thanks <3 I really appreciate it! :smile:

You have a stray

.

in there.

I tried your code with and without it and it works if you get rid of that.

Also, are you actually calling findStrongestTarget in the commandArcher method, and calling the commandArcher method on each archer? I think there’s some parts at the bottom where you have to set that up, too.

1 Like

Thanks Nick, I changed my code a bit and now its working fine! :smile:

what is a stray because it is bothering me on the level

Icy magnus do you mind helping me.please because im stuck!thank you

Hello, Dinesh, and welcome.

Phrases like “I need help!” or “This code doesn’t work!” do not help us do anything about your problem. Give us more information. What happens when you run your code? Is there an error? If so, what does it say? Post your code and a description of what happened. Don’t forget to read the FAQ before you post. Format your code properly!

1 Like

thank you! i finished the level just now but i still have no idea what a stray is in general.
p.s it would be nice if you could call me sanjjith because that is my name

i just changed my username

hey chronistgilver, can you you help me if possible , on the level steelclaw gap.
thanks

Create a new topic for it. This is not the place to discuss Steelclaw Gap.

I am having trouble after the board is about 3/4 of the way complete. All the sudden my archers just quit targeting anyone after targeting them flawlessly up to that point…

# 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)
    self.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 = self.findEnemies()
    enemyIndex = 0
    # Figure out which enemy has the most health, and set bestTarget to be that enemy.
    while len(enemies) > enemyIndex:
        enemy = enemies[enemyIndex]
        if enemy:
            enemyIndex += 1
            if enemy.health > mostHealth:
                mostHealth = enemy.health
                bestTarget = enemy
    # Only focus archers' fire if there is a big ogre.
    if bestTarget and bestTarget.health > 15:
        return bestTarget
    else:
        return None

def penderAttack():
    enemy = self.findNearest(self.findByType("ogre"))
    if enemy:
        if self.canCast("drain-life", enemy):
            self.cast("drain-life", enemy)
        elif self.canCast("shockwave", enemy):
            self.cast("shockwave", enemy)
        elif self.canCast("slow", enemy):
            self.cast("slow", enemy)

def summonFriend():
    if self.gold > self.costOf("soldier"):
        self.summon("soldier")

def weakestFriend():
    soldiers = self.findByType("soldier")
    weakestFriend = None
    leastHealth = 100
    for soldier in soldiers:
        if soldier.health < leastHealth:
            weakestFriend = soldier
            soldier += 1
     if weakestFriend:
        if self.canCast("flame-armor", weakestFriend):
            self.cast("flame-armor", weakestFriend)

# If the strongestTarget has more than 15 health, attack that target. Otherwise, attack the nearest target.
def commandArcher(archers):
    enemies = archer.findEnemies()
    enemy = archer.findNearest(enemies)
    if archerTarget:
        self.command(archer, "attack", archerTarget)
    elif enemy:
        self.command(archer, "attack", enemy)

archerTarget = None

loop:
    # If archerTarget is dead 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 = self.findFriends()
    soldiers = self.findByType("soldier")
    archers = self.findByType("archer")
    for i, soldier in enumerate(soldiers):
        commandSoldier(soldier, i, len(soldiers));
    for i, archer in enumerate(archers):
        commandArcher(archer, i, len(archers));
    commandArcher() 
    weakestFriend()
    penderAttack()
    summonFriend()

Well, commenting out the pender attack function seemed to fix the issue with the archers randomly stopping their attack…

yo hice todo bien pero, nearest = archer.findNearestEnemy() no funciona

nearest = archer.findNearestEnemy()
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);

def findStrongestTarget():
mostHealth = 0
bestTarget = None
enemies = hero.findEnemies()
index=0
while index < len(enemies):
ene=enemies[index]
if ene.health>mostHealth:
bestTarget = ene
mostHealt = ene.health
index +=1

if bestTarget and bestTarget.health > 15:
    return bestTarget
else:
    return None

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 not archerTarget or archerTarget.health <= 0:
archerTarget = findStrongestTarget()

friends = hero.findFriends()
soldiers = hero.findByType("soldier")
archer=hero.findByType("archer")
for i in range(len(soldiers)):
    soldier = soldiers[i]
    commandSoldier(soldier, i, len(soldiers));
commandArcher(archer)

Hi, I’m not sure whether the rest of your code works or not, but the source of your error is in these two lines:

archer = hero.findByType("archer")
commandArcher(archer)

Go to the documentation for hero.findByType(“archer”) (it’s on the item bar in the level under your glasses), what does it return? An array or an object? (a singular thing like enemy when you write enemy = hero.findNearestEnemy().
Now think about this line:

If the variable archer is indeed an array how is this going to work?
I hope this helps
Danny

entoses que ba aqui
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")

emphasized text # 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(archers)

Sorry, maybe I didn’t phrase that right. The function commandArcher() takes a single parameter, and that parameter needs to be a single thing, not an array.
What you need to do is copy this code:

And do the exact same for the archers.
Danny

1 Like