Help Me please on Kelvintaph Crusader

I am stuck on Kelvintaph Crusader

here is my code:

loop:
enemy = self.findEnemies()
        friend = self.findFriends()
        for friend in friend:
        self.command(friend, "attack", enemy)
self.moveXY(42, 16)
self.moveXY(25, 18)
self.attack("Muul")
self.attack("Muul")
self.moveXY(69, 16)
self.moveXY(53, 14)
self.moveXY(79, 15)

i can’t seem to get the soldiers to attack the witch

Hello, Coreyl, and welcome. Please read the FAQ before you post again, so that you can learn how to format your code properly. I’ve done it for you this time, but do so yourself in the future.

Your indentations are a little mixed up. What part of your code do you want to be inside the loop? However, here’s what I can see:

You define enemy as a lit of all enemies. You then try to command your friends to attack that list. This does not work. What did you want your friends to do?

i would like them to attack the witch so then they can defeat the rest of the enemies

P.S. How do i read the F.A.Q???

Search for “FAQ”:

1 Like

thanks Ant

i have modified my code and it still won’t work here it is:

loop:
    enemy = self.findByType("Witch", self.findEnemies())
    friend = self.findFriends()
    for friend in friend:
        for enemy in enemy:
            self.command(friend, "attack", enemy)
    self.moveXY(42, 16)
    self.moveXY(25, 18)
    self.attack("Muul")
    self.attack("Muul")
    self.moveXY(69, 16)
    self.moveXY(53, 14)
    self.moveXY(79, 15) 
1 Like

Well, your code doesn’t have any indentation. (edit: you seem to have indentation, you just didn’t read the FAQ about how to insert your code here)

Python requires that you properly indent your code, because that’s how you mark code blocks. In other languages you use curly braces, end tags, etc and don’t have to care much about indenting (although it still helps to maintain readabillity). But in python it’s essential. So your code should look something like:

loop:
    friends = ...
    # your code here

    for friend in friends:
        # this is your 'for' block
        self.command(friend, "attack", enemy)
        # your code here
    # end of 'for' block

# end of 'loop' block

Furthermore, you need to get a better understanding of lists and objects:

self.findByType() and self.findEnemies() always returns a list, even if that list has only one element. To get a single object (e.g. your target) you need to pick an item (element, whatever) of that list. You can do it by using an index (e.g. list[x]), or by using a function that returns a single value (e.g. self.findNearest(list)):

enemies = self.findEnemies()            # enemies = ['Ganju', 'Freesa', ...]
enemy   = enemies[0]                    # enemy = 'Ganju'
nearest = self.findNearest(enemies)     # nearest = 'Freesa'

Another issue is that for the for loop you need a list to go through: for item in list for example:

for enemy in enemies:          # 'enemies' is a list of enemies
    self.say(enemy)            # say the current item (=enemy)

for coin in coins:             # 'coins' is a list of coins
    # do something with the current coin

I believe that these concepts are properly explained in some of the earlier levels. Amirite, @nick?


Please :heart: this post if you found it useful. Thanks!

7 Likes

i still don’t get it. It Just doesnt work and i dont know how to target the witch an deven if i do i will get killed by the catapults

1 Like

It is a frustrating level, I agree, but it can be done. Wait until you see the Kelvintaph Defiler level! :wink:

In the meantime, see some other threads for tips and hints:
http://discourse.codecombat.com/t/kelvintaph-crusader-help/4269
http://discourse.codecombat.com/t/kelvintaph-crusader-feedback/4256

2 Likes

here is my new code:
loop: archer = self.findByType("Archer") enemy = self.findNearestEnemy() friend = self.findFriends() for friend in friend: self.command(friend, "move", {"x": 25, "y": 58}) self.command(friend, "attack", "Yzzrith") self.moveXY(42, 16) self.moveXY(25, 18) self.wait(1) self.attack("Muul") self.attack("Muul") self.moveXY(69, 16) self.moveXY(53, 14) self.wait(3) self.moveXY(79, 15)
The kill the witch but then die from the other enemies and i can’t seem to get them to attack the other enemies am i doing something wrong??

Yes. You only command them to attack "Yzzrith", the witch. Once the witch is dead, they won’t attack.

1 Like

loop: archer = self.findByType("Archer") enemy = self.findNearestEnemy() friend = self.findFriends() for friend in friend: self.command(friend, "move", {"x": 25, "y": 58}) self.command(friend, "attack", "Yzzrith") self.command(friend, "attack", enemy) self.command(friend, "attack", "Yzzrith") self.moveXY(42, 16) self.moveXY(25, 18) self.wait(1) self.attack("Muul") self.attack("Muul") self.moveXY(69, 16) self.moveXY(53, 14) self.wait(3) self.moveXY(79, 15)
now they won’t attack the witch!!

correction they kill the witch but than die

First, please read at least the relevant section of the FAQ to learn how to insert your code here properly.

(Hint: use 3 backticks before and after)


Now about your code:

  • archer = self.findByType("Archer") is unnecessary, as you don’t use it later
    (and you should use lowarcase for the types, e.g: "archer")

  • for friend in friend: is a wrong statement (see my first reply)

  • you want to do too many things with your friends at the same time:

  • move to a location

  • attack the witch

  • attack your(!) nearest enemy

  • attack the witch (again!)

  • you then move around, attack, wait, but don’t order your friends to do anything

  • then the loop restarts…


Here is a pseudo-code outline of what you probably want to do:

  • command your friends:

  • if the witch is alive: attack the witch

  • if there is any other enemy: attack the nearest one
    (note: the one nearest to your friend, not you!)

  • otherwise: move to the exit

  • in the meantime, move the hero around to get rid of the brawlers


Unfortunately, I have to tell you that it’s not going to be this simple: it takes a lot of trial and error to get it done correctly.

Probably it’s better to redo some earlier levels to get more practice with loops, targeting, etc.

I suggest once again to read the relevant topics already existing on the forum to get more hints.

Cheers

What about your code? It’s not formatted properly, if that’s what you mean.

1 Like

Your code includes the line

for friend in friend:

when i assume you want

for friend in friends:

Try renaming your array of friends, ‘friends’ instead of ‘friend’. it may get your soldiers moving

Can you plz help???
here’s my code:
loop:
friends = self.findFriends()
for friend in friends:
enemy = friend.findNearest(friend.findEnemies())
witch = self.findByType(“witch”)
if enemy:
self.command(friend, “attack”, enemy)
self.command(friend, “attack”, enemy)
else:
exit = {‘x’:78, ‘y’:40}
self.command(friend, “move”, exit)
break
self.moveXY(51, 15)
self.say(“hi”)
self.moveXY(1, 13)
self.moveXY(69, 16)
self.say(“bye”)
self.say(“catapult”)
self.moveXY(2, 15)
self.moveXY(78, 14)
the problem is the soldiers.i make it fine but my soldiers die.
ant help would be appreciated

loop:
    friends = self.findFriends()
    for friend in friends:
        enemy = friend.findNearest(friend.findEnemies())
        witch = self.findByType("witch")
        if enemy:
            self.command(friend, "attack", enemy)
            self.command(friend, "attack", enemy)
        else:
            exit = {'x':78, 'y':40}
            self.command(friend, "move", exit)
    break
self.moveXY(51, 15)
self.say("hi")
self.moveXY(1, 13)
self.moveXY(69, 16)
self.say("bye")
self.say("catapult")
self.moveXY(2, 15)
self.moveXY(78, 14)

The bonus objective (no friends killed) is very demanding. To win you must literally use every RTS tactic:

  1. Attack most dangerous enemy first: paladin and archers must focus on the witch

  2. Concentrated attack: both archers must attack the same target to bring down the rest of the ogres, skeletons

  3. Tank: the paladin must tank (shield). No sure when he has to switch from attack to tank, but check the next point also

  4. Avoid AOE. The which’es attacks are AOE. The paladin must move towards her or the soldiers and archers will be caught in AOE

  5. Heal: dudh

  6. Kite: when low on health the soldiers must run towards the paladin/ away from the target so their attacker switches target to the tanking paladin

=======================

Replace your loop with

while (1==1):
   ......
   if hero_had_not_done_anything then:  
        self.wait(0.001)

That is because loop always adds an wait to skip a frame behind your back. This is done to prevent 0 time loops which will brake your code.

Also get rid of all moveXY, say : they take too mach time and your hero cannot command its troops while doing them.

Replace everything with move, attack, wait(0.001)

Ty for the help! i will try

while (1==1):
    friends = self.findFriends()
    for friend in friends:
        enemy = friend.findNearest(friend.findEnemies())
        witch = self.findByType("witch")
        if enemy:
            self.command(friend, "attack", enemy)
            self.command(friend, "attack", enemy)
        else:
             exit = {'x':78, 'y':40}
             self.command(friend, "move", exit)
        break
self.move({'x':36, 'y':16})
self.say("hi")
self.move({'x':1, 'y':13})
self.move({'x':69, 'y':16})
self.say("bye")
self.say("catapult")
self.move({'x':2,'y':15})
self.move({'x':78, 'y':14})

it doesn’t work. i don’t know how to target the witch and my charecter freezed anfd it said i have infinite loop