Play Home Contribute Github Join Us! Discourse Staff Members Github Contribution Guides Team

[SOLVED] Need help in Kelvintaph Crusader

# You can find friends through walls, but not enemies.
# Watch out for smooth, frictionless ice patches!
def re():
    for enemy in hero.findEnemies():
        c = hero.findNearest(hero.findByType("catapult"))
        y = hero.pos.y
        if c:
            hero.buildXY("decoy", hero.pos.x + 1, y)
        else:
            hero.moveXY(78, 14)

def commandfriend():
    for friend in hero.findFriends():
        enemy = friend.findNearestEnemy()
        w = friend.findNearest(hero.findByType("witch"))
        a = hero.findNearest(hero.findByType("archer"))
        p = hero.findNearest(hero.findByType("paladin"))
        s = hero.findNearest(hero.findByType("soldier"))
        if w and a:
            hero.command(a, "attack", w)
        if w and p:
            hero.command(p, "attack", w)
        if p and p.canCast("heal"):
            hero.command(p, "cast", "heal", p)
        if s and enemy:
            hero.command(s, "attack", enemy)

while True:
    re()
    friends = hero.findFriends()
    f = hero.findNearest(friends)
    commandfriend(f)

I didn’t command friend and it isn’t error can someone help me :frowning:?

1 Like

Your first function “re()” is finding the three catapults and building decoys for each one. You run out of money before the third decoy is built and get stuck waiting for more money. No other code is followed other than building decoys at this point.

Your friends just attack by default.

I have no idea how to fix this :frowning:

Since you have to buy the decoys before you can build them, you can add a check to see if you have enough gold.

 if c and : # add the check if enough gold for the cost of "decoy"

Now if you don’t have enough gold, it will jump to the else. And I see you are using a hero.moveXY which will prevent you from running any other code until your hero reaches that location which will cause some problems. You will want to switch that to hero.move({'x':78, 'y':14}) so you can command your friends while moving.

1 Like
# You can find friends through walls, but not enemies.
# Watch out for smooth, frictionless ice patches!
def re():
    for enemy in hero.findEnemies():
        c = hero.findNearest(hero.findByType("catapult"))
        y = hero.pos.y
        if c and hero.gold > hero.costOf("decoy"):
            hero.buildXY("decoy", hero.pos.x + 1, y)
        else:
            hero.move({'x':78, 'y':14})

def commandfriend(friend):
    for friend in hero.findFriends():
        enemy = friend.findNearestEnemy()
        w = friend.findNearest(hero.findByType("witch"))
        a = hero.findNearest(hero.findByType("archer"))
        p = hero.findNearest(hero.findByType("paladin"))
        s = hero.findNearest(hero.findByType("soldier"))
        if w and a:
            hero.command(a, "attack", w)
        if w and p:
            hero.command(p, "attack", w)
        if p and p.canCast("heal"):
            hero.command(p, "cast", "heal", p)
        if s and enemy:
            hero.command(s, "attack", enemy)

while True:
    enemy = hero.findNearestEnemy()
    friends = hero.findFriends()
    f = hero.findNearest(friends)
    m = hero.findEnemyMissiles()
    re()
    commandfriend(f)

I fixed but I can’t command friends I think the wrong thing is at the “commandfriend(friend)”

I see you are calling the hero.findFriends() twice when you only need it once. Either you want to call it before the function and use the friends variable in the function, or call it in the function. In this case, I’d remove the two lines in the while True loop and the variable in the function, def commandfriend()

    friends = hero.findFriends() # in the while true loop
    f = hero.findNearest(friends) # variable currently used in the commandfriend function
for friend in hero.findFriends(): # set up the loop for the friend array again 

When you have the friends array, you can circle through it like you have it set up. A quick check of the friend.type == "type of friend" would help you get through the friends quicker. With this option you can remove

        a = hero.findNearest(hero.findByType("archer"))
        p = hero.findNearest(hero.findByType("paladin"))
        s = hero.findNearest(hero.findByType("soldier"))

and add the friend.type check into the if statements.

if w and friend.type == "type of friend":
    hero.command(friend, "attack", w)

This way you circle through all the friends. With the findNearest, you will only find the nearest one of those type, not all of them.

But my archer didn’t attack the witch idk why but this is my code :

# You can find friends through walls, but not enemies.
# Watch out for smooth, frictionless ice patches!
def re():
    for enemy in hero.findEnemies():
        c = hero.findNearest(hero.findByType("catapult"))
        y = hero.pos.y
        if c and hero.gold > hero.costOf("decoy"):
            hero.buildXY("decoy", hero.pos.x + 1, y)
        else:
            hero.move({'x':78, 'y':14})

def commandfriend():
    for friend in hero.findFriends():
        enemy = friend.findNearestEnemy()
        w = friend.findNearest(hero.findByType("witch"))
        s = friend.findNearest(hero.findByType("skeleton"))
        if w and friend.type == "archer":
            hero.command(friend, "attack", w)
        elif enemy:
            hero.command(friend, "attack", enemy)
        if w and friend.type == "paladin":
            hero.command(friend, "attack", w)
        elif enemy:
            hero.command(friend, "attack", enemy)
        if friend.type == "paladin" and friend.canCast("heal"):
            hero.command(friend, "cast", "heal", friend)
        if friend.type == "soldier" and enemy:
            hero.command(friend, "attack", enemy)

while True:
    re()
    commandfriend()

Found it. You have the elif statements that aren’t checking for any friend.type. Once your friend, any type of friend, runs that line of code, they switch to fighting “enemy” instead of the specified target you identified earlier. You will also want to switch all of the friend checks to all elif since the friend will only be one of these. You can add a final elif enemy at the end to redirect the attack if the witch is dead.

        if w and friend.type == "archer":
            hero.command(friend, "attack", w)
        elif w and friend.type == "paladin":
            hero.command(friend, "attack", w)
        elif friend.type == "paladin" and friend.canCast("heal"):
            hero.command(friend, "cast", "heal", friend)
        elif friend.type == "soldier" and enemy:
            hero.command(friend, "attack", enemy)
        elif enemy:
            hero.command(friend, "attack", enemy)

Two other details, you don’t need to run the the enemy array in your re() function. That slows down the code and you don’t command your allies as quickly. Oh, and your paladin will only heal herself with this code. If you want her to heal someone else, you will want to create another function to find the friend you want to heal.

def re():
    for enemy in hero.findEnemies():
        c = hero.findNearest(hero.findByType("catapult"))
        y = hero.pos.y
        if c and hero.gold > hero.costOf("decoy"):
            hero.buildXY("decoy", hero.pos.x + 1, y)
        else:
            hero.move({'x':78, 'y':14})

def commandfriend():
    for friend in hero.findFriends():
        enemy = friend.findNearestEnemy()
        w = friend.findNearest(hero.findByType("witch"))
        if w and friend.type == "archer":
            hero.command(friend, "attack", w)
        elif w and friend.type == "paladin":
            hero.command(friend, "attack", w)
        elif friend.type == "paladin" and friend.canCast("heal"):
            hero.command(friend, "cast", "heal", friend)
        elif friend.type == "soldier" and enemy:
            hero.command(friend, "attack", enemy)
        elif enemy:
            hero.command(friend, "attack", enemy)
        

while True:
    re()
    commandfriend()

Here is my code, I think it’s ok now all thing I just need to know is HOW to properly command the troops like can you give me the list what do I need to command? Thanks! :slight_smile:

I passed! I forgot to delete the for enemy in hero.findEnemies():
And I decided to command the archer that left from the fight with flag so I won!

3 Likes