Sir Robin Bravely Ran Away - looked for a more elegant answer and received a class in using Vector

# This has been achieved via a simple text comprehension with the sample text known as FAQ
# Now with syntax-highlighting
# Backticks (`) are you're friends
loop:
    enemies = self.findEnemies()
    if len(enemies) > 0:
         # Do something

TL:DR
# This will run away from the closest brawler, and if there is no brawler from the closest enemy
loop:
    enemies = self.findByTpye("brawler")
    enemy   = self.findNearest(enemies)
    if not(enemy):
        enemy = self.findNearest(self.findEnemies())
    if enemy:
        targetPos = Vector.subtract(enemy.pos, self.pos)
        
        self.move(targetPos)
    else:
        self.say("Phew, no enemies nearby. Let me take a break.")

Listen well, brothers and sisters, for I can teach you the power of the VECTOR (Nope, not the guy from Despicable Me…)

A Vector is an object to store the length and the direction of… a direction. You have already used them. A point can be described as the position (0, 0) plus a direction with a length. So whenever you used self.pos or enemy.pos you actually used a vector.

You may have noted I said adding. How do you add directions you may ask? Simply by adding them elementwise, so newX = firstX + secondX, newY = firstY + secondY and so on.

You can not only add a Vector to (0, 0) (getting a point), but also to a point (giving you another point). This may sound extremely confusing to those not knowing what I talk about, so here an example:

Move 10 units right - Oldschool
currentPos = self.pos
currentX   = currentPos.x
currentY   = currentPos.y

target = {'x': currentX + 10, 'y': currentY}
Move 10 units right - The AWESOME way
currentPos = self.pos
newDirection = Vector(10, 0)

target = Vector.add(currentPos, newDirection)

Ok, that wasn't that awesome.
But you can also subtract, rotate, scale, create and move to Vectors way more easily than ever before.

# For this we need to compute end-start (because Math!)
meToEnemy = Vector.subtract(enemy.pos, self.pos)

After this one-liner we want to convert this into a vector that points away from the enemy with a length of 1(You Sir Robin want’s to flee after all).

# vec*(-1) is
awayFromEnemy = Vector.multiply(meToEnemy, -1)

# has now length 1
awayShortened = Vector.normalize(awayFromEnemy)

Putting it all together

# This will run away from the closest brawler, and if there is no brawler from the closest enemy
loop:
    enemies = self.findByTpye("brawler")
    enemy   = self.findNearest(enemies)
    if not(enemy):
        enemy = self.findNearest(self.findEnemies())
    if enemy:
        targetPos = Vector.subtract(self.pos, enemy.pos)
        targetPos = Vector.multiply(targetPos, -1)
        
        # or shorter
        targetPos = Vector.subtract(enemy.pos, self.pos)
        
        self.move(targetPos)
    else:
        self.say("Phew, no enemies nearby. Let me take a break.")
7 Likes