I need help to change this code so it could store enemy health predictions and command units to attack effectively


#1

I am new to Python, but have a considerable experience in programming. I want to create a code that stores enemy health predictions and decreases them when units attack so that other units could attack other targets. My code doesnt work and it is really difficult to debug in this game. I hope somebody has more experience than me and can easily help.

# Global variables
typesDamage = {"archer": 13, "soldier": 6, "paladin": 20, "griffin-rider": 20}
friends = None
friendsLength = None
friendHealthPredictions = None
enemies = None
enemiesLength = None
enemyHealthPredictions = None
# A function to get friend health predictions:
def getFriendHealthPredictions():
    friendHealthPredictions = []
    for friendIndex in range(friendsLength):
        friendHealthPredictions.append(friends[friendIndex].health)
# A function to get enemy health predictions
def getEnemyHealthPredictions():
    enemyHealthPredictions = []
    for enemyIndex in range(enemiesLength):
        enemyHealthPredictions.append(enemies[enemyIndex].health)
# A function to get global variables.
def getGlobalVariables():
    friends = self.findFriends()
    friendsLength = len(friends)
    getFriendHealthPredictions()
    enemies = self.findEnemies()
    enemiesLength = len(enemies)
    getEnemyHealthPredictions()
# A function to choose enemy with lowest health among four groups devided by in/out of friend range and in/out of enemy range. Gets object friend as input and returns index of targeted enemy or false.
def chooseEnemy(friend):
    friendRangeEnemyRangeIndex = None
    lowestHealthOne = 10000
    friendRangeNotEnemyRangeIndex = None
    lowestHealthTwo = 10000
    notFriendRangeEnemyRangeIndex = None
    lowestHealthThree = 10000
    notFriendRangeNotEnemyRangeIndex = None
    lowestHealthFour = 10000
    for enemyIndex in range(enemiesLength):
        enemy = enemies[enemyIndex]
        enemyHealthPrediction = enemyHealthPredictions[enemyIndex]
        if enemyHealthPrediction > 0:
            distanceToEnemy = friend.distanceTo(enemy)
            if not (distanceToEnemy > friend.attackRange):
                if not (distanceToEnemy > enemy.attackRange):
                    if enemyHealthPrediction < lowestHealthOne:
                        friendRangeEnemyRangeIndex = enemyIndex
                        lowestHealthOne = enemyHealthPrediction
                else:
                    if enemyHealthPrediction < lowestHealthTwo:
                        friendRangeNotEnemyRangeIndex = enemyIndex
                        lowestHealthTwo = enemyHealthPrediction
            else:
                if not (distanceToEnemy > enemy.attackRange):
                    if enemyHealthPrediction < lowestHealthThree:
                        notFriendRangeEnemyRangeIndex = enemyIndex
                        lowestHealthThree = enemyHealthPrediction
                else:
                    if enemyHealthPrediction < lowestHealthFour:
                        notFriendRangeNotEnemyRangeIndex = enemyIndex
                        lowestHealthFour = enemyHealthPrediction
    if friendRangeEnemyRangeIndex:
        return friendRangeEnemyRangeIndex
    elif friendRangeNotEnemyRangeIndex:
        return friendRangeNotEnemyRangeIndex
    elif notFriendRangeEnemyRangeIndex:
        return notFriendRangeEnemyRangeIndex
    elif notFriendRangeNotEnemyRangeIndex:
        return notFriendRangeNotEnemyRangeIndex
# A function to attack enemy and adjust enemy health predictions.
def controlUnit(friend):
    enemyIndex = chooseEnemy(friend)
    if enemyIndex:
        self.command(friend, "attack", enemies[enemyIndex])
        enemyHealthPredictions[enemyIndex] -= typesDamage[friend.type]
    else:
        self.command(friend, "defend", self.pos)
# A fuction to summon paladins.
def summonGriffins():
    while not (self.gold < self.costOf("griffin-rider")):
        self.summon("griffin-rider")
# A function to control hero.
def controlHero():
    if not (self.gold < self.costOf("griffin-rider")):
        self.summon("griffin-rider")
        summonGriffins()
    else:
        enemyIndex = chooseEnemy(self)
        if enemyIndex:
            self.attack(enemies[enemyIndex])
# Main loop
loop:
    getGlobalVariables()
    for friend in friends:
        controlUnit(friend)
    controlHero()

#2

Your def getGlobalVariables(): won’t work.

This code causes me to repeatedly say cat:

animal = 'cat'

def getGlobalVariables():
    animal = 'dog'

while True:
    getGlobalVariables()   
    self.say(animal)

In python all variables in functions are by default local regardless of where they were declared, so the variables you get in getGlobalVariables() will all be None. You would declare a variable to global with the global keyword. The compiler will not let you do this though, so you will have to do this without globals in functions.

Also watch out that the compiler regards empty lists or arrays as truthy. (Which is not the case for python)

self.say() can be used for debugging

Update
Made the language more precise.


#3

Thank you very much, Hinkle. It seems to be the case here. Unfortunately, the code combat parser doesnt support the global keyword yet (Python and global variables). Will do it in other language then.