Grim Determination (JavaScript)


#1

Having some problems successfully completing this level. I think I’ve done fair amount of optimization, including:

  1. Moving the paladins forward as to avoid the enemy missile strike blow-back into the mine field.
  2. Coin collection optimization of the two peasants to pump out griffin units as fast as possible.

But my units are continually overrun. Would someone please look over my code and let me know what could be the problem? TIA.

// Your goal is to protect Reynaldo

// Find the paladin with the lowest health.
this.lowestHealthPaladin = function() {
    var lowestHealth = 99999;
    var lowestFriend = null;
    var friends = this.findFriends();
    for(var f=0; f < friends.length; f++) {
        var friend = friends[f];
        if(friend.type != "paladin") { continue; }
        if(friend.health < lowestHealth && friend.health < friend.maxHealth) {
            lowestHealth = friend.health;
            lowestFriend = friend;
        }
    }
    return lowestFriend;
};

this.commandPaladin = function(paladin) {
    // Heal the paladin with the lowest health using lowestHealthPaladin()
    // You can use paladin.canCast("heal") and command(paladin, "cast", "heal", target)
    // Paladins can also shield: command(paladin, "shield")
    
    if (paladin) {
        var lowPal = this.lowestHealthPaladin();
        if (lowPal) {
            if (paladin.canCast("heal")) {
                this.command(paladin, "cast", "heal", lowPal);
            }
        }
        else {
            this.command(paladin, "shield");
        }
    }
};

this.commandPeasant = function(peasant) {
    peasants = this.findByType("peasant");
    for (var i =0 ; i < peasants.length ; i ++) {
        peasant = peasants[i];
        coins = this.findItems();
        nearestCoin = peasant.findNearest(coins);
        
        if (i === 0 && nearestCoin.pos.y < 41){
           this.command(peasant, "move", nearestCoin.pos);
        }
        else if (i === 1 && nearestCoin.pos.y >= 41){
            this.command(peasant, "move", nearestCoin.pos);
        }
    }
};

this.commandGriffin = function(griffin) {
    var enemy = griffin.findNearestEnemy();
    if (enemy) {
        this.command(griffin, "attack", enemy);
    }
};

this.commandFriends = function() {
    // Command your friends.
    var friends = this.findFriends();
    for(var i=0; i < friends.length; i++) {
        var friend = friends[i];
        if(friend.type == "peasant") {
            this.commandPeasant(friend);
        } else if(friend.type == "griffin-rider") {
            this.commandGriffin(friend);
        } else if(friend.type == "paladin") {
            this.commandPaladin(friend);
        }
    }
};

loop {
    this.commandFriends();
    
    // Summon griffin riders!
    if (this.gold > this.costOf("griffin-rider")){
        this.summon("griffin-rider");
    }
    
    // Move Paladins forward to avoid the enemy missle blowback into mine field
    var friends = this.findFriends();
    for (var i = 0; i < friends.length; i++) {
        var friend = friends[i];
        if (friend.type == "paladin"){
            var friendPOSx = 70;
            var friendPOSy = friend.pos.y;
            var friendPOS = {'x':friendPOSx,'y':friendPOSy};
            this.command(friend, "move", friendPOS );
        }
    }
}

#2

You only command your paladins to shield if there is no lowPal, that is, if all the paladins are at max health. Move that block one level forward. That way they will shield if they can not cast heal.


#3

Chronist,

Thanks for the suggestion. I made the change you suggested, unfortunately the end result is pretty much the same. Shortly into running the code the skeletons begin at the bottom of the paladin column and kill the paladins one at a time moving upwards, following that the mine field is breached, killing Reynaldo. :confused:

Revised Code
// Your goal is to protect Reynaldo

// Find the paladin with the lowest health.
this.lowestHealthPaladin = function() {
    var lowestHealth = 99999;
    var lowestFriend = null;
    var friends = this.findFriends();
    for(var f=0; f < friends.length; f++) {
        var friend = friends[f];
        if(friend.type != "paladin") { continue; }
        if(friend.health < lowestHealth && friend.health < friend.maxHealth) {
            lowestHealth = friend.health;
            lowestFriend = friend;
        }
    }
    return lowestFriend;
};

this.commandPaladin = function(paladin) {
    // Heal the paladin with the lowest health using lowestHealthPaladin()
    // You can use paladin.canCast("heal") and command(paladin, "cast", "heal", target)
    // Paladins can also shield: command(paladin, "shield")
    var lowPal = this.lowestHealthPaladin();
    if (lowPal) {
        if (paladin.canCast("heal")) {
            this.command(paladin, "cast", "heal", lowPal);
        }
        else {
            this.command(paladin, "shield");
        }
    }
    else {
        this.command(paladin, "shield");
    }
};

this.commandPeasant = function(peasant) {
    peasants = this.findByType("peasant");
    for (var i =0 ; i < peasants.length ; i ++) {
        peasant = peasants[i];
        coins = this.findItems();
        nearestCoin = peasant.findNearest(coins);
        
        if (i === 0 && nearestCoin.pos.y < 41){
           this.command(peasant, "move", nearestCoin.pos);
        }
        else if (i === 1 && nearestCoin.pos.y >= 41){
            this.command(peasant, "move", nearestCoin.pos);
        }
    }
};

this.commandGriffin = function(griffin) {
    var enemy = griffin.findNearestEnemy();
    if (enemy) {
        this.command(griffin, "attack", enemy);
    }
};

this.commandFriends = function() {
    // Command your friends.
    var friends = this.findFriends();
    for(var i=0; i < friends.length; i++) {
        var friend = friends[i];
        if(friend.type == "peasant") {
            this.commandPeasant(friend);
        } else if(friend.type == "griffin-rider") {
            this.commandGriffin(friend);
        } else if(friend.type == "paladin") {
            this.commandPaladin(friend);
        }
    }
};

loop {
    this.commandFriends();
    
    // Summon griffin riders!
    if (this.gold > this.costOf("griffin-rider")){
        this.summon("griffin-rider");
    }
    
    // Move Paladins forward to avoid the enemy missle blowback into mine field
    var friends = this.findFriends();
    for (var i = 0; i < friends.length; i++) {
        var friend = friends[i];
        if (friend.type == "paladin"){
            var friendPOSx = 70;
            var friendPOSy = friend.pos.y;
            var friendPOS = {'x':friendPOSx,'y':friendPOSy};
            this.command(friend, "move", friendPOS );
        }
    }
}



#4

Out of curiosity, why don’t you have your paladins attack?

It occurs to me that maybe it’s unclear that they can attack. :confused:


#5

Oh My Gerd. :angry:

That was the problem Catsync. The level instructions did not mention to command the paladins attack, nor that they had that ability for that matter. I had assumed the paladins’ roles were to draw the oncoming enemies to them and they would hunker down shielding and healing while the griffin riders were amassed and picked the enemies off. Added an else if to command paladin attack and instant level success. Did not even end up needing the code segment to move the paladins away from the minefield to avoid the enemy missile blow-back. Epic levels of frustration achieved and time wasted. Thanks so much for the suggestion!


#6

LOL!!! I completed the mission by doing just that. I never had them attack, I just sent out griffin-riders to attack, while they shielded. the problem I kept running into was that they would get hit and knocked back into the mines, blowing up Reynaldo. It never even occurred to me that they could attack, with the instructions for shield command and all. Well, whatever. I passed the mission anyway, I just did it the hard way!


#7

Heheh, ok, it should be more obvious now :smile_cat:


#9

When I tried to make them attack they still get pushed into the mines???
How am I supposed to fix this?
Am I supposed to move them forward a bit first or what?


#10

You can move the forward at the start of the level an then let them fight normally

while( this.now() < LETS_FIGHT_NOW)
       // move forward a bit
       // summon griffins or let some time pass
loop {    //main loop

#11

One other thing I noticed reading through that hasn’t been mentioned.
Your collection routine, says collect nearest if it is in the sector you designated for that peasant. (Topside/bottom side)

But you don’t have it step through to the next furthest coin, or move to a default location or in some other way have that peasant do something meaningful if the peasant is detecting a nearest coin on the other side.


#12

Strange, your code only creates the error “Line 59: ReferenceError: peasants is not defined”…
:head_bandage: