Hunters and prey help please

# Ogres are trying to kill your reindeer!
# Keep your archers back while summoning soldiers to attack.

def pickUpCoin():
    coin = self.findNearest(self.findItems())
    if coin:
        self.move(coin.pos)
    pass

def summonTroops():
    if self.gold > self.costOf("soldier"):
        self.summon("soldier")
    # Summon soldiers if you have the gold.
    
    pass
    
# This function has an argument named soldier.
# Arguments are like variables.
# The value of an argument is determined when the function is called.
def commandSoldier(soldier):
    enemy = soldier.findNearestEnemy
   if enemy:
        self.command(soldier, "attack", enemy)
    # Soldiers should attack enemies.
    pass

# Write a commandArcher function to tell your archers what to do!
# It should take one argument that will represent the archer passed to the function when it's called.
# Archers should only attack enemies who are closer than 25 meters, otherwise, stay still.
def commandarcher(archer):
    enemy = archer.findNearest(archer.findenemies)
    if enemy and archer.distanceto(enemy) < 25:
        self.command(archer, "attack", enemy)
    else:
        self.command(archer, "move", archer.pos)
loop:
    pickUpCoin()
    summonTroops()
    friends = self.findFriends()
    for friend in friends:
        if friend.type == "soldier":
            # This friend will be assigned to the variable soldier in commandSoldier
            commandSoldier(friend)
        elif friend.type == "archer":
            commandarcher(friend)

apparently i need to find the distance to a target unit :

def commandarcher(archer):
    enemy = archer.findNearest(archer.findenemies)
    if enemy and archer.distanceto(enemy) < 25:
        self.command(archer, "attack", enemy)
    else:
        self.command(archer, "move", archer.pos)

1 Like

This should be archer.findNearest(self.findEnemies()) #Although I am not very sure.

This is because our hero (self) can findEnemies with goggles/matrix lens. Archer cannot. archer.findNearest is correct though. This is because this is again not the archerā€™s ability, it is our heroā€™s ability thanks to glasses/matrix lens to find the closest enemy to the archer. Hero sees it, not the archer.

1 Like

In this code, after the archer has attacked someone, its position may change (may go further from reindeer). Then it will not return to original position. So, I employ a little trick. I change the function for looping around friends to loop around self.findByType(ā€œarcherā€) with a for loop with index. It look like:
archers = self.findByType(ā€œarcherā€)
for index, archer in enumerate(archers):

same code as your except of for nearby enemy case, I ask them to defend fixed positions:
also; index, archer, archers are sent as arguments to the def commandarcher() ā€¦ i.e. commandarcher(index, archer, archers)

self.command(archer, ā€œdefendā€, {ā€œxā€: 21, ā€œyā€: 60*(index+1)/len(archers)})

^using this, when no nearby enemy, archers align in a vertical line near the reindeer and defending the region.

3 Likes

my archers just attack when enemies are on screen

1 Like

i completed it thanks for all the help

2 Likes

@ZadonX - I suppose in this code combat discourse, thanking for small but productive helps are done by clicking on the ā€˜likeā€™ button, heart shaped and not by replies. Thereby minimizing text and allowing others to quickly glance over to the actual solution. Also, keeping a track of helpful users in the forum. Happy to help anyway :slight_smile:

2 Likes

can you help me?
when I run the code, it says that please check code and highlights the ifs under def commandArcher

hereā€™s my code sorry if the formatting is bad I donā€™t know how to fix it.

def pickUpCoin():
# Collect coins.
coin = self.findNearest(self.findItems())
self.move(coin.pos)
pass

def summonTroops():
# Summon soldiers if you have the gold.
if gold > 30:
self.summon(ā€œarcherā€)
pass

archer = self.findByType(ā€œarcherā€)
def commandArcher(archer):

archer = self.findByType("archer")
enemy = self.findNearest(archer.findEnemies()

**if** archer:
    **if** enemy:    
        **if** self.distanceTo(enemy) < 25:
            self.command(archer, "attack", enemy)
        **else**:
            self.command(archer, "move", self.pos)
pass

loop:
pickUpCoin()
summonTroops()
friends = self.findFriends()
for friend in friends:
if friend.type == ā€œsoldierā€:
# This friend will be assigned to the variable soldier in commandSoldier
commandSoldier(friend)
elif friend.type == ā€œarcherā€:
commandArcher(friend)
pass

1 Like

Format your code by putting 3 backquotes (left-top button on the keyboard) around your code
Inside the backquotes you can indent your code using spaces.
Backquotes must be on a line by themselves without spaces or tabs

#code goes here

2 Likes

How do I show my code

1 Like

Here is my code.It says commandArcher isnā€™t identified.

Ogres are trying to kill your reindeer!

Keep your archers back while summoning soldiers to attack.

def pickUpCoin():
# Collect coins.
items = self.findItems()
nearestCoin = self.findNearest(items)
if nearestCoin:
self.move(nearestCoin.pos)
pass
def summonTroops():
# Summon soldiers if you have the gold.
if self.costOf(ā€œsoldierā€)<self.gold:
self.summon(ā€œsoldierā€)
pass

This function has an argument named soldier.

Arguments are like variables.

The value of an argument is determined when the function is called.

def commandSoldier(soldier):
# Soldiers should attack enemies.
for soldier in self.findFriends():
enemy = soldier.findNearestEnemy()
if enemy:
self.command(soldier, ā€œattackā€, enemy)
pass

Write a commandArcher function to tell your archers what to do!

It should take one argument that will represent the archer passed to the function when itā€™s called.

Archers should only attack enemies who are closer than 25 meters, otherwise, stay still.

def commandarcher(archer):
enemy = archer.findNearest(archer.findenemies)
if enemy and archer.distanceto(enemy) < 25:
self.command(archer, ā€œattackā€, enemy)
else:
self.command(archer, ā€œmoveā€, archer.pos)
loop:
pickUpCoin()
summonTroops()
friends = self.findFriends()
for friend in friends:
if friend.type == ā€œsoldierā€:
# This friend will be assigned to the variable soldier in commandSoldier
commandSoldier(friend)
elif friend.type == ā€œarcherā€:
#commandArcher(friend)
commandArcher(friend)
pass

1 Like

Case matter.
When you declared the commandArcher you used small case. Error here:

def commandarcher(archer):
1 Like

how do i fix that error please

1 Like

Also, for every level that if I lose I have to wait a day yo submit, it says wait a month before I can submit and I waited 4

1 Like

I think You have to uppercase the in
def commandarcher(archer):
so its
def commandArcher(archer):

1 Like

Thank you SO much. My archers kept moving, but now they donā€™t, and I achieved the bonus objective in addition to the main objective. That is a great code!

1 Like

May I have some help please? The archers that are there always move about despite the code I have written. Here is my code:

// Ogres are trying to kill your reindeer!
// Keep your archers back while summoning soldiers to attack.

hero.pickUpCoin = function() {
    // Collect coins.
    var coin = hero.findNearest(hero.findItems());
    if (coin) {
        hero.move(coin.pos);
    }
};

hero.summonTroops = function() {
    // Summon soldiers if you have the gold.
    if (hero.gold >= hero.costOf("soldier")) {
        hero.summon("soldier");
    }
};

// This function has an argument named soldier.
// Arguments are like variables.
// The value of an argument is determined when the function is called.
hero.commandSoldier = function(soldier) {
    // Soldiers should attack enemies.
        for(var j = 0; j < friends.length; j++) {
            var friend = friends[i];
            var enemy = friend.findNearestEnemy();
            if (enemy) {
                hero.command(friend, "attack", enemy);
            }
        }
};

// Write a commandArcher function to tell your archers what to do!
// It should take one argument that will represent the archer passed to the function when it's called.
// Archers should only attack enemies who are closer than 25 meters, otherwise, stay still.
hero.commandArcher = function(friend) {
    var archerEnemy = friend.findNearestEnemy();
    if (archerEnemy && friend.distanceTo(archerEnemy) < 10) {
        hero.command(friend, "attack", enemy);
    } else {
    }
};
while(true) {
    hero.pickUpCoin();
    hero.summonTroops();
    var friends = hero.findFriends();
    for(var i = 0; i < friends.length; i++) {
        var friend = friends[i];
        if(friend.type == "soldier") {
            // This friend will be assigned to the variable soldier in commandSoldier
            hero.commandSoldier(friend);
        } else if(friend.type == "archer") {
            // Be sure to command your archers.
            hero.commandArcher(friend);
        }
    }
}

I kinda feel like itā€™s a bug but it probably isnā€™t.

Can anyone help me !! @UltCombo @AdrianCgw , anyone?!

The problem is, before you issue the first command to an unit, it will act on its own using a basic AI which usually just walks towards to and attacks the nearest enemy.

You are only commanding the archers when they are 10m away from an enemy, so while that doesnā€™t happen you donā€™t send any commands to them, which results in the archers doing whatever they want until you start commanding them.

To fix this, you can add a command in the else block inside the commandArcher function telling them to retreat or hold their positions (command them to "move" to a safe place, or to where they are already standing).