Library-tactician:need help !!


#1

i stucked here …
i dont even pass the last level of growing flower 3d squears and bib…
then i stucked here ! o !G!!

// Hushbaum has been ambushed by ogres!
// She is busy healing her soldiers, you should command them to fight!
// The ogres will send more troops if they think they can get to Hushbaum or your archers, so keep them inside the circle!

// Soldiers spread out in a circle and defend.
var soldierIndex=0;
var numSoldiers=8;
var soldiers=this.findByType("soldier");
var soldier=soldiers[soldierIndex];

this.commandSoldier = function(soldier, soldierIndex, numSoldiers) {
    var angle = Math.PI * 2 * soldierIndex / numSoldiers;
    var defendPos = {x: 41, y: 40};
    defendPos.x += 10 * Math.cos(angle);
    defendPos.y += 10 * Math.sin(angle);
    this.command(soldier, "defend", defendPos);
};

// Find the strongest target (most health)
// This function returns something! When you call the function, you will get some value back.
this.findStrongestTarget = function() {
    var mostHealth = 0;
    var bestTarget = null;
    for(i=0;i<enemies.length;i++){
        if (enemies[i].health> mostHealth) {
             mostHealth = enemies[i].health;
             bestTarget = enemies[i];
         }
    }
          // Figure out which enemy has the most health, and set bestTarget to be that enemy.

    // Only focus archers' fire if there is a big ogre.
    if (bestTarget && bestTarget.health > 15) {
        this.command(archer, "attack", bestTarget);
        return bestTarget;
        }
    else {
        return null;
         }
};


// If the strongestTarget has more than 15 health, attack that target. Otherwise, attack the nearest target.
this.commandArcher = function(archer) {
    var nearest =this.findNearest(enemies);
    if(archerTarget) {
        this.command(archer, "attack", archerTarget);
    } else if(nearest) {
        this.command(archer,"attack", nearest);
    }
};

var archerTarget = null;
loop {
        var enemies = this.findEnemies();
        var enemyIndex=0;
        var enemy=enemies[enemyIndex];
        this.commandSoldier(soldier, soldierIndex, numSoldiers);
             // If archerTarget is dead or doesn't exist, find a new one.
        if(!archerTarget || archerTarget.health <= 0) {
            // Set archerTarget to be the target that is returned by findStrongestTarget()
            this.findStrongestTarget();
            archerTarget = this.findStrongestTarget();
            }
        var friends = this.findFriends();
    
        for(var i=0; i < soldiers.length; i++) {
            var soldier = soldiers[i];
            this.commandSoldier(soldier, i, soldiers.length);
             }
    // use commandArcher() to command your archers
             this.commandArcher();
    
}
...

i …i don’t know what’s the problem…
it’s like when i identify something, then …it begins to go wrong…
would anybody who knows how to do with it or anybody has passed this level tell me what’s my problem?


#2

Hello, coba.

Help us help you, what exactly is your problem? Is there an error in your code? Do you just keep dying?


#3

That could be root of the problem. Analyse commandSoldier function and it usage and they look at Ur commandArcher


#4

it’s really nice of you to help me !!!

the error is: Hero Placeholder needs something to command!
but ! i am wearing the necklace of commanding archer to attack…

this image is the error…

there is a warning sign like this

however, when i delete this “var soldier”…
those soldiers won’t be rightly doing the circle defend stuff…

i swear !! i am wearing the command necklace!!

really nice of you friends helping me with this !!!


#5

thanks ! does the “findStrongestTarget” function work?

and …though i know where is the root of the problem but i …
just dont have a clue to fix it… :sob:


#6

It means that function don’t get any “archer” to give him this command.

Soldiers example:

var soldiers=this.findByType("soldier");

by doing this U get array of soldiers to command

for(var i=0; i < soldiers.length; i++) {
        var soldier = soldiers[i];
        this.commandSoldier(soldier, i, soldiers.length);
         }

now U go through this array selecting soldiers one by one and issuing commands to them - U pass 3 parameters to function - soldier object, his number in array, and overall number of soldiers

And Ur archers lacks this things, there are no declared archers to command and no loop to select them and command them one by one also Ur commandArcher function need 1 parameter - archer object, U don’t pass this in Ur main loop.

There is a lot of bugs in this code, go back to first level with Boss Star, read all there is about commanding troops, google for some info about functions and “for” loops and then U can come back and try this lvl again.

Learn and conquer :wink:


#7

I always lose 1-2 soldiers thereby failing the mission. Is there anything I’m missing in my code, or a strategy I should consider?

// Hushbaum has been ambushed by ogres!
// She is busy healing her soldiers, you should command them to fight!
// The ogres will send more troops if they think they can get to Hushbaum or your archers, so keep them inside the circle!

// Soldiers spread out in a circle and defend.
this.commandSoldier = function(soldier, soldierIndex, numSoldiers) {
    var angle = Math.PI * 2 * soldierIndex / numSoldiers;
    var defendPos = {x: 41, y: 40};
    defendPos.x += 10 * Math.cos(angle);
    defendPos.y += 10 * Math.sin(angle);
    this.command(soldier, "defend", defendPos);
};

// Find the strongest target (most health)
// This function returns something! When you call the function, you will get some value back.
this.findStrongestTarget = function() {
    var mostHealth = 0;
    var bestTarget = null;
    var enemyIndex = 0;
    var enemies = this.findEnemies();
    // Figure out which enemy has the most health, and set bestTarget to be that enemy.
    while (enemyIndex < enemies.length) {
        var target = enemies[enemyIndex];
        var hpLeft = target.health;
        if (hpLeft > mostHealth) {
            mostHealth = hpLeft;
            bestTarget = mostHealth;
        }
        enemyIndex++;
    }
        
    // Only focus archers' fire if there is a big ogre.
    if (bestTarget && bestTarget.health > 15) {
        return bestTarget;
    } else {
        return null;
    }
};


// If the strongestTarget has more than 15 health, attack that target. Otherwise, attack the nearest target.
this.commandArcher = function(archer) {
    
    var nearest = archer.findNearest(archer.findEnemies());
    if(archerTarget) {
        this.command(archer, "attack", archerTarget);
    } else if(nearest) {
        this.command(archer, "attack", nearest);
    }
};

var archerTarget = null;
loop {
    // If archerTarget is dead or doesn't exist, find a new one.
    if(!archerTarget || archerTarget.health <= 0) {
        // Set archerTarget to be the target that is returned by findStrongestTarget()
        archerTarget = this.findStrongestTarget();
    }
    var friends = this.findFriends();
    var soldiers = this.findByType("soldier");
    for(var i=0; i < soldiers.length; i++) {
        var soldier = soldiers[i];
        this.commandSoldier(soldier, i, soldiers.length);
    }
    var archers = this.findByType("archer");
    for(var a=0; a < archers.length; a++){
        var archer = archers[a];
        // use commandArcher() to command your archers
        this.commandArcher(archer, a, archers.length);
    }    
}

#8

There doesn’t appear to be anything missing. Just keep submitting.


#9

Check this. bestTarget should be a target, not a number (of hit points).


#10

Thanks Catsync, that’s what I overlooked. After updating the code I passed on the first submit.


#11

Still not workin RIP me


#12

Telling us this helps nothing. What code are you using? What is your problem?


#13

The thing is. I had no problem (also I am one of “us” but k) I just had to resubmit 67 times. It’s a weird level.


#14

Sorry, I thought you were asking for help with the level. Best wishes!


#15

Well, I thought I had a problem but as it turns out you have to submit until you get the perfect seed. @nick fix this.


#16

I’m still having trouble with this level too. Everything seems to work until multiple ogres appear. The archers aren’t switching targets fast enough, and focus on one ogre while another one beats a soldier to death. Here is my code, thanks for any suggestions!

this.commandSoldier = function(soldier, soldierIndex, numSoldiers) {
    var angle = Math.PI * 2 * soldierIndex / numSoldiers;
    var defendPos = {x: 41, y: 40};
    defendPos.x += 10 * Math.cos(angle);
    defendPos.y += 10 * Math.sin(angle);
    this.command(soldier, "defend", defendPos);
};

// START OF FINDSTRONGESTTARGET FX
this.findStrongestTarget = function() {
    var mostHealth = 0;
    var bestTarget = null;
    var enemies = this.findEnemies();
    for (var i=0; i < enemies.length; i++) {
        if (enemies[i].health > mostHealth) {
            mostHealth = enemies[i].health;
            bestTarget = enemies[i];
        }
    }    

    if (bestTarget && bestTarget.health > 15) {
        return archerTarget;
    } else {
        return null;
    }
}; //END OF FINDSTRONGESTTARGET FX

//COMMAND ARCHER FUNCTION
this.commandArcher = function(archer, archerIndex, numArchers) {
    var nearest = archer.findNearest(archer.findEnemies());
    if(archerTarget) {
        this.command(archer, "attack", archerTarget);
    } else if(nearest) {
        this.command(archer, "attack", nearest);
    }
}; //END COMMAND ARCHER FX

var archerTarget = null;
loop {
     this.findStrongestTarget();
        
    if(!archerTarget || archerTarget.health <= 0) {
        archerTarget = this.findStrongestTarget();
    }
    
    var friends = this.findFriends();
    var soldiers = this.findByType("soldier");
    for(var k=0; k < soldiers.length; k++) {
        var soldier = soldiers[k];
        this.commandSoldier(soldier, k, soldiers.length);
    }

    var archers = this.findByType("archer");
    for(var j=0; j < archers.length; j++) {
          var archer = archers[j];
          this.commandArcher(archer, j, archers.length);
       }
}

#17

Your function: this.findStrongestTarget returns archerTarget instead of the correct bestTarget

As a result

archerTarget = this.findStrongestTarget();

is equivalent to archerTarget=archerTarget :slightly_smiling:


#18

Thanks!!! That fixed it! :smile:


#19

Hi all!
About strategy - I found a couple steps, that could rise chances of victory a little bit. First, “chain-lightning” spell is quite useful if you have emperor’s gloves. So, you could include it in the loop. Also, I changed defendPos x from 41 to 48 in order to move more ogres closer to hero’s “chain-lightning”. Third, I added two lines in my Python function: commandSoldier(soldier, soldierIndex, numSoldiers):
> if soldier.health < 50:

        self.command(soldier, "move", {"x": 50, "y": 41})

Hope, if your whole code is ok, it will help you to save some time. Thanks for attention)


#20

So what do we change it to?