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

[Solved] hero.IsPathClear() bug?

In the Boulder Woods hero moves ahead after IsPathClear() returns True but gets stuck up into boulders or woods quite a lot and says “I can’t get there”. Because of that it runs out of time and fails.
I ave came up with checking a wider corridor around target that solved the problem but it seems to me quite complicated for a kid so I thought it was not intended and likely a bug. Is that so?
That is, the question is whether hero supposed to stuck up and lose time if the path was clear?

  if hero.isPathClear(hero.pos, target):
      hero.moveXY(target.x, target.y)

Hi @vladin and welcome to the forum! :partying_face:

Can you show us your code formated as it is described here because maybe there is an issue in another part of your code that causes this one?

Andrei

1 Like

Try using (target.pos.x, target.pos.y) instead of (target.x, target.y).

2 Likes

For me this is a “hit and miss” level. It’s very complicated to be finished with moveXY().
because targetX and targetY are number, not coordinates

        targetX = hero.pos.x + coef * Math.cos(angle) # default coef = 5
        targetY = hero.pos.y + coef * Math.sin(angle

finding the path will be:

        if hero.isPathClear(hero.pos, {'x': targetX,'y': targetY})

then to succeed with moveXY(targetX, targetY) you need to play with coef
it’s easier with:

            hero.move({'x': targetX,'y': targetY})
1 Like

Here is the code w/o workaround below. It fails due to timeout. If I uncomment “beamPath()” in the middle, which is nothing but checking path of wider corridor or “beam” to the target then it works because hero gets stuck much less so it can finish on time, typically using more than half duration allowed.
May be something else is wrong, pls advise.

Try using (target.pos.x, target.pos.y) instead of (target.x, target.y)

I believe target here is a dictionary that expected to have x,y and not another dict pos (pos.x,pos.y). This is clear also from first arg “hero.pos” and not “hero”.

# Use isPathClear to move around the randomly positioned boulders.
# Automatic pathfinding doesn't work in Boulder Woods.
endTarget = {"x": 76, "y": 35}
angle = Math.PI / 2

while True:
    targetX = hero.pos.x + 6 * Math.cos(angle)
    targetY = hero.pos.y + 6 * Math.sin(angle)
    moveX = hero.pos.x + 2 * Math.cos(angle)
    moveY = hero.pos.y + 2 * Math.sin(angle)
    # Use isPathClear between your current `pos` and the target.
    target = {"x": targetX, "y": targetY}
    if hero.isPathClear(hero.pos, endTarget): 
        #first try to reach end Target 
        hero.moveXY(endTarget.x, endTarget.y)
    #elif beamPath(target,2):
    elif hero.isPathClear(hero.pos, target):
        # If the path is clear, move to the target.
        hero.moveXY(target.x, target.y)
        angle = -Math.PI / 8
    else:
        # Otherwise, sweep the `angle` clockwise a bit.
        angle += Math.PI / 16
1 Like

Your code works fine with this particular seed:

If you replace

        hero.moveXY(endTarget.x, endTarget.y) # with
        hero.move(endTarget) # and
        hero.moveXY(target.x, target.y) # with
        hero.move(target)        


Using the default code but with move() is even faster:

            hero.move({'x':targetX,'y':targetY});


“Whether hero supposed to stuck up and lose time if the path was clear?” -Yes
“it seems to me quite complicated for a kid” - too complicated, it can fail depending on the seed,
the hero speed, the boots even writing the correct code

The default code fails if using hero.moveXY - “hit and miss” level…

Thanks! This was the issue. Once changed to hero.move(target) it works like a charm :slight_smile:

Note: I would expect move() and moveXY() to do the same thing (based on name) but read help and they are different. move is actually one step towards the target and moveXY is moving until target reached or an obstacle encountered in which case hero slows down and makes 2 steps aside that results in another clash 2 steps later. It is easy to see from the trajectories. In case of move() the trajectory is parallel to the wall and in case of moveXY() it is zigzagging. Bottom line: I would change the name: hero.move() => hero.step()

1 Like