Mixed Unit tactics help


#1

When I run this code

// Practice using modulo to loop over an array

// Choose the mix and order of units you want to summon by populating this array:
var summonTypes = ["soldier","soldier","soldier","archer","griffin-rider"];
var i = 0;
this.summonTroops = function() {
    // Use % to wrap around the summonTypes array based on this.built.length
    
    while (i < summonTypes.length) {
        var type = summonTypes[i];
        if(this.costOf(type) >= this.gold){
            this.summon(type);
            i++;
        }
    }
};



this.commadToops = function(){
    var enemy = this.findNearest(this.findEnemies());
    var friends = this.findFriends();
    var i = 0;
    while(i > friend.length){
        var soldie = friends[i];
        if(enemy && soldie){
            this.command(soldie, "attack", enemy);
        }
    }
};
this.collectCoins = function() {
    var item = this.findNearest(this.findItems());
    var x = item.pos.x;
    var y = item.pos.y;
    if(item){
        this.moveXY(x, y);    
    }
    
    
    
};

loop{
    this.collectCoins();    
    this.summonTroops();
    this.commandTroops();
}




It says that the hard execution loop of 3000000 exceeded I think this a failure in the API protection


#2

It is nice of you to think that, but it is more likely errors in your code…

such as:

    while (i < summonTypes.length) {
        var type = summonTypes[i];
        if(this.costOf(type) >= this.gold){
            this.summon(type);
            i++;
        }
    }

Which seems like it will loop forever, since ‘i’ only changes when you summon something…
What is the value of ‘i’ anyway? it is not set to zero inside the function. Does javascript auto zero things? or is it an ever increasing global variable? (there is a “global” var i= 0;)

There is also this function:

    var i = 0;
    while(i > friend.length){
        var soldie = friends[i];
        if(enemy && soldie){
            this.command(soldie, "attack", enemy);
        }
    }

No change in ‘i’ here at all, but that is OK, in the sense that, it (i=0) should never be ‘>’ than friends.length therefore it never goes into the loop.


#3

I’m sorry but I can’t tell what you mean


#4

Which part:

the you have errors?

the only i++ in the if statement?

or the no i++ in the while loop at all?

or the never goes into the loop because 0 is never greater than length of friends?


#5

In this part I mean I only increment when I actually do the summon
Shouldn’t the function just pass without doing anything if the if condition is not met


#6

Lets say you have 5 gold when you enter the summon function…

while i < number of summonables
    If not enough gold to summon first type
        never increment i
        i always and forever less number of summonables
        while-loop never ends

#7

Sooooooooo how would I fix this?


#8

The while-loop, loops so long as the condition is met.
The if, only fires if the condition is met.

You need to change it so it does what ever you trying to accomplish…?

What are you trying to accomplish?

If you want to check and summon all things on the list that you have gold to summon, then just move the increment out of the loop. and DONE, it will check each item in turn summoning what you have the money for starting with your prefered units (the order checked) and when it has checked and summoned one of each (that you can afford) it will exit the while loop.

    while (i < summonTypes.length) {
        var type = summonTypes[i];
        if(this.costOf(type) >= this.gold){
            this.summon(type);
        }
        i++;
    }

That is what I’d guess you had in mind. Your comment about it passing if the condition is not met almost makes me think you only want it to check the first thing in the summon list, which doesn’t really make sense as then you wouldn’t have bothered to make a list.

(another possibility) If you want it to only summon one unit, the first thing on the list that you can afford then you have to add some sort of success variable to the while.

    notSummoned = true;
    while (i < summonTypes.length && notSummoned) {
        var type = summonTypes[i];
        if(this.costOf(type) >= this.gold){
            this.summon(type);
            notSummoned = false;
        }
        i++;
    }

I’d have used the variable as “summoned” but I couldn’t remember if javascript’s not was “!summoned” or “not summoned”, so if you prefer “positive logic” then feel free to switch all the assignments and fix the name and condition.) :smile:


#9

JS’s not is !

(twenty chars happy now!)


#10

What I and trying to accomplish is to summon all the units in the array in the order that they are listed

Okay I copy pasted the code you provided but it’s saying I need a string to check the cost of the thing


#11

Hmm, you still have the “i=0”?
hmm, it shouldn’t say that unless “var type = summonTypes[i]” is somehow pointing to something that is not “unit”.

To summon one of each unit in order you either need to have enough money FIRST, before you run the function or you need to “remember” where you left off last time you ran out of money, so when you come back you start there instead of starting over at the top of the list…

hint

self.built() is an array of what you built…


#12

This is the code I have at this point

// Practice using modulo to loop over an array

// Choose the mix and order of units you want to summon by populating this array:
this.summonTroops = function() {
    // Use % to wrap around the summonTypes array based on this.built.length
    summonTypes = ["soldier","soldier","soldier","archer","griffin    -rider"];
    i = 0;

    notSummoned = true;
    while (i < summonTypes.length && notSummoned) {
        var type = summonTypes[i];
        if(this.costOf(type) >= this.gold){
            this.summon(type);
            notSummoned = false;
        }
        i++;
    }
};



this.commadToops = function(){
    var enemy = this.findNearest(this.findEnemies());
    var friends = this.findFriends();
    var i = 0;
    while(i > friend.length){
        var soldie = friends[i];
        if(enemy && soldie){
            this.command(soldie, "attack", enemy);
        }
    }
};
this.collectCoins = function() {
    var item = this.findNearest(this.findItems());
    var x = item.pos.x;
    var y = item.pos.y;
    if(item){
        this.moveXY(x, y);    
    }
    
    
    
};

loop{
    this.collectCoins();    
    this.summonTroops();
    this.commandTroops();
}






#13

Shouldn’t the gold check work?


#14

Do you have the boss-star 3? otherwise you cant summon griffin riders

Need to fix the spacing “griffin -rider” if so

You were supposed to use the % operator to loop around the array
you are looping i back to 0, so my guess from reading it is you will only get soldiers unless you have gold for 3 soldiers and an archer

this.commadToops = function() should be this,commandTroops

and you have solie instead of solider but it should still work anyways


#15

Hi there! I’m sorry to bother but I’m having a few errors with this piece of code

var friends = this.findFriends();

My issue seems to lie here

    this.command(friend, "move", ({x:43, y:37}));
    var enemy = this.findNearest(this.findEnemies());
    if (enemy){
    this.command(friend, "attack", enemy);
    }

It says that I am trying to control the accompanying palisades as if they were movable units. If someone could help explain to me how to correct this it would be much appreciated :smile:


#16

Please read the FAQ and properly format your code so it is readable.

You have to do something like:

if friend.type != "palisade":
    # Do stuff

#17

My apologies about the legibility of my code, it was my first time posting on the forums.
But thank you for putting up with it because you’ve really helped me out :smile: . I’ll be sure that the next time I post everything is in order


#18

My code works, but doesnt command the ‘friends’

def summonTroops():
    type=summonTypes[len(self.built) % len(summonTypes)]
    if self.gold >= self.costOf('archer'):
        self.summon('archer')
    elif self.gold >= self.costOf('soldier'):
        self.summon('soldier')
def commandTroops():
    friends=self.findFriends()
    for friend in friends != 'palisade':
        enemies=self.findEnemies()
        for enemy in enemies:
            self.command(friend, "attack", enemy)
def collectCoins():
    coin=self.findNearest(self.findItems())
    self.move(coin.pos)
loop:
    summonTroops()
    commandTroops()
    collectCoins()

#19

In commandTroops, you have an unconventional for-loop that doesn’t work. You should loop over all friends, then check if the friend type is not a palisade.


#20

did that and i works now, thanks