Precision kicking help!

I need help on how I can move the peasant to kick the ball so it won’t hit the red skeleton.
But my code I use flags. Can you tell me how I can make my peasant move without flag to hit blue skeleton?

def commandPeasant():
    flag = self.findFlag()
    friends = self.findFriends()
    for friend in friends:
        enemy = self.findNearestEnemy()
        
        if friend.type == "skeleton":
            continue
            
            
        if flag:
            self.command(friend, "move", flag.pos)
            pass       
        
while True:
    commandPeasant()


2 Likes

Sorry Chaboi_300, We cannot give out the code. It makes it easier for you to just get the code, then beat the level. But, if you post your code, we can help you along and give you little tips and clues to assist you. Remember to post your code according to the FAQ.
Here’s the link:
https://discourse.codecombat.com/faq

I need help on how I can move the peasant to kick the ball so it won’t hit the red skeleton.
But my code I use flags. Can you tell me how I can make my peasant move without flag to hit blue skeleton?

def commandPeasant():
    flag = self.findFlag()
    friends = self.findFriends()
    for friend in friends:
        enemy = self.findNearestEnemy()
        
        if friend.type == "skeleton":
            continue
            
            
        if flag:
            self.command(friend, "move", flag.pos)
            pass       
        
while True:
    commandPeasant()


3 Likes

It’s better to use vectors. Make a vector from the skeleton to the ball, then extend it little further. That is your (peasant) point. Then send the peasant from there to the ball. repeat.

3 Likes

Is it also possible to find the angle of the vector, move the peasant behind the ball in that line and repeat that?

2 Likes

Yes if you are smart enough.:slightly_smiling_face:

2 Likes

This code won’t move the peasant to pos and only goes to ballPos:

# The blue skeletons can be found as enemies.
ball = hero.findNearest(hero.findByType("ball"))
    
ballPos = ball.pos
enemy = hero.findNearestEnemy()
friends = hero.findFriends()
friend = hero.findNearest(friends)
Vector = enemy.pos
distance = Vector.subtract(Vector, ballPos)

pos=Vector.add(distance,5)
while True:
    
    
    
    hero.command(friend, "move", pos)
    
    hero.command(friend, "move", ballPos)
    


3 Likes

@Chaboi_3000 Can you give us a screenshot of where Alianor moves?

1 Like

I told you only on the ball and no where else. @Bryukh is this a bug?

3 Likes

I don’t think it a bug but I could be wrong.

2 Likes

I think these two part of the code make the peasant move to the ball - ballPos = ball.pos hero.command(friend, "move", ballPos) I’m not aways accurate.

1 Like

Hi @Chaboi_3000,

I tried your code and saw the problem. I think “Vector” is a reserved word so trying to use it as a variable name causes problems. (unfortunately without any error or warning)

When I changed your code to use some other variable name it got un-stuck and then correctly gave a warning for the line

pos=Vector.add(distance,5)

The add function adds two vectors like this Vector.add(vector1,vector2), so you can add two vectors, but you can not add a scalar to a vector.

5 Likes

So can you tell me how to fix that?

1 Like

It was a pretty challenging level for me, I planned to just help you find your problem, but I’ll try to give you the idea I used.

When you subtract the ball position vector from the enemy position vector you are getting a direction not a distance . In your code I’m talking about this part.

distance = Vector.subtract(Vector, ballPos)

(The variable name Vector is a problem, use some other name.)
Your distance vector is the right direction you want to send your peasant (from the ball) but not the right distance. It is too long.

I think you picked 5 because you want to send your peasant 5 units away from the ball (in the correct direction, which you already have). To do that you need to make your vector have a length of 5 with out changing its direction.

To change a vector to a specific length without changing its direction you can Vector.normalize() it to give it a length of one, then Vector.multiply() it by 5 or whatever you like to give it that length.

Once you have done all of that, the direction and length will be correct, but the starting place is not. (You will still have to Vector.add() your vector to the ball position vector to get the spot to send your peasant.

Once I did all of that I still had the problem of the peasant sometimes walking into the ball on its way to that spot. That is another part of the problem to solve.

3 Likes

I need help on this level. I am extremely confused and I need help. Alianor (the peasant) moves in directions I don’t want her to.
Thanks!

# Push the ball to knock over all the blue skeletons without hitting any red ones.
# The blue skeletons can be found as enemies.
loop:
    ball = hero.findNearest(hero.findByType("ball"))
    ballPos = ball.pos
    enemy = hero.findNearestEnemy()
    friends = hero.findFriends()
    friend = hero.findNearest(friends)
    heroPos = hero.pos
    Vector = enemy.pos
    newVector = Vector.add(Vector, ballPos)
    newVector1 = Vector.limit(newVector, 1)
    #pVector = Vector.copy(newVector)
    #pVector = Vector.rotate(pVector, Math.PI)
    #hero.debug(x)
    #hero.debug(m)
    #hero.debug(x1)
    #hero.debug(m1)
    #hero.debug(newVector)
    #hero.debug(newVector1)
    hero.command(friend, "move", newVector)
    flag = hero.findFlag(flag)
    if flag:
        target = {"x": ballPos.x, "y": ballPos.y}
        hero.command(friend, "move", target)

Later:

I edited my code using @Mr-Borges suggestion as well since I did almost the same thing as @Chaboi_3000

Here it is:

# Push the ball to knock over all the blue skeletons without hitting any red ones.
# The blue skeletons can be found as enemies.
loop:
    ball = hero.findNearest(hero.findByType("ball"))
    ballPos = ball.pos
    enemy = hero.findNearestEnemy()
    friends = hero.findFriends()
    friend = hero.findNearest(friends)
    heroPos = hero.pos
    Vector = enemy.pos
    newVector = Vector.subtract(Vector, ballPos)
    direction = Vector.normalize(newVector)
    dm = Vector.multiply(direction, 3)
    finalVector = Vector.add(ballPos, dm)
    hero.command(friend, "move", finalVector)
    flag = hero.findFlag(flag)
    if flag:
        target = {"x": ballPos.x, "y": ballPos.y}
        hero.command(friend, "move", target)

It still doesn’t work. Can I have some other help?

2 Likes

I did practically the same thing as Chaboi_3000 except my thing works kinda odd. I think that the problem is with the normalizing.

2 Likes

Hi @Neel_Sharma, I tried your program and it is pretty close to working.

Your peasant is moving a distance of 3 units from the ball towards the skeleton. Instead of +3 I think you want to move the opposite direction. (hint hint)

I think you are just using the flag just for timing, so the peasant finishes moving to finalVector before she moves towards the ball. You can do it that way, but you’ll need to pick up the flag after you use it and then have another way to control the timing of her moving away from the ball.

4 Likes

@Mr-Borges I tried it. It almost worked, but I believe that it is trying to hit a friendly skeleton. :smile:

Here is my code:

# Push the ball to knock over all the blue skeletons without hitting any red ones.
# The blue skeletons can be found as enemies.
loop:
    ball = hero.findNearest(hero.findByType("ball"))
    ballPos = ball.pos
    enemy = hero.findNearestEnemy()
    friends = hero.findFriends()
    friend = hero.findNearest(friends)
    heroPos = hero.pos
    Vector = enemy.pos
    newVector = Vector.subtract(Vector, ballPos)
    direction = Vector.normalize(newVector)
    dm = Vector.multiply(direction, -3)
    finalVector = Vector.add(ballPos, dm)
    hero.command(friend, "move", finalVector)
    flag = hero.findFlag("black")
    if flag:
        target = {"x": ballPos.x, "y": ballPos.y}
        hero.command(friend, "move", target)
        if friend.pos == flag.pos:
            hero.removeFlag(flag)
1 Like

I’ll point you to something I said about this earlier.

The name “Vector” is already in use, as a class I think. The problem lines are these.

Vector = enemy.pos

and

newVector = Vector.subtract(Vector, ballPos)

These lines are not doing what you would think because the name “Vector” already belongs to a special thing that you can’t mess with. I used hero.say(newVector) to see what was actually getting saved here and newVector was always 0,0

Then I changed the variable name “Vector” to some other name and then newVector wasn’t zero anymore and the program started to work.

3 Likes

Okay, I almost have it, but I can’t seem to get it to do the right thing. Can I have some help @Mr-Borges?

Here is my code:

# Push the ball to knock over all the blue skeletons without hitting any red ones.
# The blue skeletons can be found as enemies.
loop:
    ball = hero.findNearest(hero.findByType("ball"))
    ballPos = ball.pos
    enemy = hero.findNearestEnemy()
    friends = hero.findFriends()
    friend = hero.findNearest(friends)
    heroPos = hero.pos
    nubPos = enemy.pos
    newVector = Vector.subtract(nubPos, ballPos)
    direction = Vector.normalize(newVector)
    dm = Vector.multiply(direction, -3)
    finalVector = Vector.add(ballPos, dm)
    flag = hero.findFlag("black")
    if flag:
        point1 = {"x": 40, "y": 25}
        hero.command(friend, "move", point1)
        if friend.distanceTo(finalVector) < 2:
            hero.command(friend, "move", finalVector)
        else:
            point2 = {"x": 34, "y": 35}
            hero.command(friend, "move", point2)
            if friend.distanceTo(finalVector) < 2:
                hero.command(friend, "move", finalVector)
            else:
                point3 = {"x": 40, "y": 45}
                hero.command(friend, "move", point3)
                if friend.distanceTo(finalVector) < 2:
                    hero.command(friend, "move", finalVector)
                else:
                    point4 = {"x": 48, "y": 37}
                    hero.command(friend, "move", point4)
                    if friend.distanceTo(finalVector) < 2:
                        hero.command(friend, "move", finalVector)
1 Like