# Backwoods Brawl in Python - Error "isPathClear is not defined"

Ok . this is one of the few things stopping a win for Backwoods Brawl 4. The code doesn’t error out all of the time - just on some weird spots on the edge. I’m just going to include the relevant “run-away” code. It is one of those maddening sporadic errors which do not always occur. What I suspect is that self.isPathClear(s,t) produces an error when one of the coordinates for s or t is out of bounds … but I can’t prove it.

Separate point/possible backdoor solution - went looking for Python exception handling and it appears the “try:” method is not supported. Is there a way within the code to catch and handle the exception? (Do I need an item to use that method? … Currently, Programmaticon IV equiped.)

``````---
#This function tests 9 paths to make sure the path from tarA to self.pos are clear, checking 1m in each direction from the character's center and the destination center:
def SafePath(tarA):
vecA = Vector.subtract(tarA, self.pos)
# This creates a 90° rotated, 2 m long vector relative to vec.
normV = Vector.multiply(Vector.normalize(Vector.rotate(vecA, 1.5708)), 2)
targetL = [tarA,   Vector.add(tarA, normV),   Vector.subtract(tarA, normV)]
startL  = [self.pos, Vector.add(self.pos, normV), Vector.subtract(self.pos, normV)]
isFree = True
for s in startL:            #Testing the 3 positions around the self.pos
for t in targetL:        #Testing the 3 positions around the tarA
if s and t:
isFree = isFree and self.isPathClear(s, t)    #this is the line which gives errors sometimes
else:
isFree = False
return isFree

#Moves 1 step towards tarA.  If the path to tarA is obstructed, rotates around 28 degrees and tries again.
def SafeMove(tarA):
tarLoc = tarA
cAngle = 0
while (not( SafePath(tarLoc)) and (cAngle < 2*Math.PI)):
vecA = Vector.normalize(Vector.subtract(tarLoc, self.pos))
self.move(tarLoc)

loop:
break

loop:
enemies = self.findEnemies()
MoveVector = Vector(0,0)
#This next loop calculates the destination Vector based on the weighted sum of each enemy vector.  And yes, I do have an additional 28 degree turn added.
for enemy in enemies:
weight = enemy.health / (self.distanceTo(enemy)^2)
eVector = Vector.multiply(Vector.rotate(Vector.subtract(self.pos, enemy.pos),0.5),weight)
SafeMove(tarA)``````

I think it’s likely that try/catch in Python aren’t supported, given our transpiler. Sorry!

Can you look in the JavaScript console to see if there’s any more info as to why it thinks `isPathClear` is not defined? I recall some other weird error happening where it really meant that something else wasn’t defined, but it decided to say `isPathClear` was it, so you might be onto something with a problem with `s` or `t`.

1 Like

God.coffee:70 Anshar: Let there be light upon Backwoods Brawl! (preload: false)
Angel.coffee:55 |Anshar’s Cheryl| Generated random seed 1840587932 of type submissionCount from sessionIDs 560fe05d08aafaa724f3a114 submissionCount 9
Angel.coffee:55 |Anshar’s Cheryl| Assigned power 160 to wave initial with difficulty 5
Angel.coffee:55 |Anshar’s Cheryl| Assigned power 480 to wave throughout with difficulty 5
(program):7 |Anshar’s Cheryl| Assigned power 1600 to wave punishers with difficulty 5
(program):7 |Anshar’s Cheryl| Assigned power 30 to wave cosmicBackgroundMunchkinRadiation with difficulty 5
(program):7 |Anshar’s Cheryl| Loaded 27 of 900 (+1099ms)
(program):7 |Anshar’s Cheryl| Loaded 78 of 900 (+1006ms)
(program):7 |Anshar’s Cheryl| Loaded 181 of 900 (+1045ms)
(program):7 |Anshar’s Cheryl| Loaded 279 of 900 (+1083ms)
(program):7 |Anshar’s Cheryl| Hero Placeholder had new Programmable problem: plan Line 17: isPathClear is not defined 19.8
(program):7 |Anshar’s Cheryl| The world ended in lost on frame 404
(program):7 |Anshar’s Cheryl| Loaded 376 of 404 (+1054ms)
(program):7 |Anshar’s Cheryl| And it was so: (14.250ms per frame, 404 frames)
Simulation : 5757ms
Serialization: 51ms
Delivery : 80ms
(program):1381 No frames were changed out of all 404
https://analytics.codecombat.com/analytics Failed to load resource: net::ERR_CONNECTION_TIMED_OUT
app.js:517 Analytics post failed!(anonymous function) @ app.js:517u @ jquery.js:3099c.fireWith @ jquery.js:3211i @ jquery.js:8266(anonymous function) @ jquery.js:8599
https://analytics.codecombat.com/analytics Failed to load resource: net::ERR_CONNECTION_TIMED_OUT
app.js:517 Analytics post failed!

I did a few tests to see if I can reproduce the problem. Under normal circumstances there seems to be no issue: e.g. `self.isPathClear(self.pos, Vector(1234.567, -987.654))` returns `false` as expected, etc.

However, when I tested my escape algorithm (which worked flawlessly on Backwoods Brawl, because it’s perfect ) on a more crowded level: Backwoods Treasure, after a few seconds I received the same error message as @Msakr: isPathClear is not defined. In the console output I also found this:
`Hero Placeholder had new Programmable problem: plan Line 27: isPathClear is not defined 75.33333333333333`

So I tested this: `self.isPathClear(self.pos, 12345)`
Same error message, similar console output:
`Hero Placeholder had new Programmable problem: plan Line 1: isPathClear is not defined 0`

So it looks like that in the algorithm sometimes, somehow a vector is misinterpreted. The strange thing is that there are absolutely only vectors in it… My piece of code is:

``````    while not self.isPathClear(self.pos, newPos):
fleeVec = Vector.rotate(fleeVec, angle)
if angle > 0: angle *= -1
else: angle = angle * -1 + angleAdj
``````

How could we help to debug this?

update: I adjusted my code - but not the fleeing function! - and now I don’t get the error anymore. Poor slow Tharin tries to outrun the ogre hordes, and valiantly fails after about 30 seconds…

update 2: I suspect that the `while` function may be the source of the issue - in both of our examples the `isPathClear` is part of a `while` condition.

@Msakr: try to replace it with a `loop` and an `if ... break`

Output of `self.debug(self.now(), self.pos, newPos)` at the critical time:

``````34.333333333333336 {x: 30.72, y: 18.19, z: 1.00} {x: 38.81, y: 24.07, z: 1.00}
34.4 {x: 30.80, y: 18.72, z: 1.00} {x: 38.55, y: 25.04, z: 1.00}
34.46666666666667 {x: 31.02, y: 19.24, z: 1.00} {x: 38.68, y: 25.67, z: 1.00}
34.53333333333333 {x: 31.06, y: 19.77, z: 1.00} {x: NaN, y: NaN, z: 1.00}
Hero Placeholder had new Programmable problem: plan Line 33: isPathClear is not defined 34.53333333333333
``````

So suddenly my `newPos` vector becomes undefined. I’ll try to find more details…

update: OK, I found the source of my problem: while calculating my `newPos` I use weighting based on the enemy type. However, this weight is not calculated, but stored in a dictionary. At the critical moment a new enemy appears, which is not defined in my dictionary… thus, the weight will be `None` and so my `newPos` becomes undefined. So it turns out that it’s not a problem of `isPathClear` but a coding issue

@Msakr: I debugged your code. In your main loop, the weight becomes infinity at a certain time

``````        weight = enemy.health / (self.distanceTo(enemy)^2)
if self.now() > 9: self.debug(enemy.health, self.distanceTo(enemy), weight)
``````

The output of the above shows:

``````14 7.835243960629522 2.8
14 9.317114691760876 1.2727272727272727
14 10.250228335667611 1.75
250 10.525626666473913 31.25
14 2.641386929406519 Infinity
[health   distance    weight]
``````

At this moment your vector coordinates become infinity and you get the `isPathClear` error.

However, the strange thing is that if you do the math, it’s far from infinity:
`14 / (2.64..)^2 = 2.00..`

If the distance would be very small or zero, I could understand the issue. But this way it just doesn’t work out…

So started to strip down the code…

# …and found the real issue!

``````        weight = enemy.health / (self.distanceTo(enemy)^2)
``````

Now look closer:

# ^2

What’s wrong with it? In python the `^` operator is a bitwise `xor`!

What you need is the `**` operator (power):
#**2

But why would an `xor` operation result in “infinity” still escapes my mind… any idea, @nick?