[SOLVED] Stuck in "Library Tactician" (Mountain)

Hey guys, I need help with this one, the problem I have is that a unique soldier always dies almost in the end of the battle and I really don’t know what to change…
So here’s the code, if anyone can help…

# 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!

def summonSoldier():
    if hero.gold > hero.costOf("soldier"):
        hero.summon("soldier")

# 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.
    # 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, soldier in enumerate(soldiers):
        commandSoldier(soldier, i, len(soldiers));
    summonSoldier()
    # use commandArcher() to command your archers
    for i, archer in enumerate(archers):
        commandArcher(archer);
1 Like

Without knowing the level - I notice that the function findStrongestTarget() does not loop over enemies at all. It seems to always return None. Is that intended?

Regards!

4 Likes

OK --> (code below).
But I still have the same problem, please somebody help!
Or Maybe the level needs some rebalancing?

def findStrongestTarget():
    strongest = None
    strongestHealth = 0
    enemyIndex = 0
    enemies = hero.findEnemies()
    while enemyIndex < len(enemies):
        enemy = enemies[enemyIndex]
        if enemy.health > strongestHealth:
            strongest = enemy
            strongestHealth = enemy.health
        enemy.Index += 1
        return strongest
1 Like

Might be just a format issue, but the return statement is executed directly in the while loop.

Plus, in the original function, there was some kind of check, wether your strongest target is worthwhile targeting: “if strongest/bestTarget and strongest.health > x:”

You might try to use hero.say(strongest) in order to check, wether the unit you are targeting is really worthwhile (i. e. very strong).

2 Likes

Finally!!! I solved it!!!
In def commandSoldier I was missing this:

if (soldier.health > 60):
     hero.command(soldier, "defend", defendPos)
else:
     hero.command(soldier, "defend", {'x': 42, 'y': 40})
2 Likes

Thank you! I’ve been stuck on this level for well over a day now, and I wasn’t able to find a single (working) solution anywhere online (even solutions that have supposedly worked for people in the past). I think this level should definitely be tweaked, whether it be the amount of ogres spawned or a better tutorial/comments in the code. As far as I know this solution isn’t the intended way to complete the level. Thanks again!

1 Like

I’m still stuck on library tactician here is my code: <def summonSoldier():
if hero.gold > hero.costOf(“soldier”):
hero.summon(“soldier”)

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():
strongest = None
strongestHealth = 0
enemyIndex = 0
enemies = hero.findEnemies()
while enemyIndex < len(enemies):
enemy = enemies[enemyIndex]
if enemy.health > strongestHealth:
strongest = enemy
strongestHealth = enemy.health

    enemy.Index += 1
    return strongest

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, soldier in enumerate(soldiers):
commandSoldier(soldier, i, len(soldiers));
summonSoldier()
# use commandArcher() to command your archers
for i, archer in enumerate(archers):
commandArcher(archer)>

1 Like

Hello and welcome to codecombat discourse! This is a cozy forum where you can share ideas, share fan art, get assistance for code, etc! Before you proceed, we hope that you review this topic, which shows all essentials of this board! Thanks!

1 Like

Can you please format your code

Shouldn’t that be enemyIndex +=1?

do you need this >

1 Like

Thank u I didn’t know how to format the code then

So I’m stuck on this and I don’t know if this is a code error or something else but the arrows just keep on missing and I lose, can anyone help me?image

1 Like

Can you please post your code so we can help you.

# 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!

def summonSoldier():
    if hero.gold > hero.costOf("soldier"):
        hero.summon("soldier")

# 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():
    strongest = None
    strongestHealth = 0
    enemyIndex = 0
    enemies = hero.findEnemies()
    while enemyIndex < len(enemies):
        enemy = enemies[enemyIndex]
        if enemy.health > strongestHealth:
            strongest = enemy
            strongestHealth = enemy.health
        enemy.Index += 1
        return strongest
# 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, soldier in enumerate(soldiers):
        commandSoldier(soldier, i, len(soldiers));
        summonSoldier()
    # use commandArcher() to command your archers
    for i, archer in enumerate(archers):
        commandArcher(archer);

Welcome back to the discourse, @ScienceBoi! :partying_face:

Hi @ScienceBoi. The problem isn’t that you’re missing exactly. The problem is your findStrongestTarget function.
Firstly this:

does not match the variable you created just above it:

There should be no .
Secondly, you’ve put the return strongest inside the while loop, meaning you will return the strongest variable every loop, which is bad, because you want to loop through all the enemies first, then return the strongest. This means you have to put the return strongest outside the while loop.
Finally, for the commandArcher(archer) function the comments say:

# If the strongestTarget has more than 15 health, attack that target. Otherwise, attack the nearest target.

You’ve only checked if the archerTarget exists. You also need to check it has more than 15 health:

If it doesn’t, then the code will attack the nearest enemy (once you’ve completed the change).
This will give you success.
Danny

1 Like

I am having trouble in my code. I have read all of the solutions above, and none have worked for me.

# 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!

def summonSoldier():
    if hero.gold > hero.costOf("soldier"):
        hero.summon("soldier")

# 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():
    if (soldier.health > 60):
        hero.command(soldier, "defend", defendPos)
    else:
        hero.command(soldier, "defend", {'x': 42, 'y': 40})
    strongest = None
    strongestHealth = 0
    enemyIndex = 0
    enemies = hero.findEnemies()
    while enemyIndex < len(enemies):
        enemy = enemies[enemyIndex]
        if enemy.health > strongestHealth:
            strongest = enemy
            strongestHealth = enemy.health
        enemy.Index += 1
        return strongest
# 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, soldier in enumerate(soldiers):
        commandSoldier(soldier, i, len(soldiers));
    summonSoldier()
    # use commandArcher() to command your archers
    for i, archer in enumerate(archers):
        commandArcher(archer);

you accidentally put a dot

if archerTarget and archerTarget.health > 15:

1 Like

it doesn’t work, my soldier start running all over, and a ton of thrower spawn and kill my archers…