Grim-determination stuck

Why is that code realy slow?


function lowestHealthPaladin() {
    var lowestHealth = Infinity;
    var lowestFriend = null;
    var friends = hero.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;
}

function commandPaladin(paladin) {
    var enemy = paladin.findNearestEnemy();
    var strongestEnemy = findStrongestEnemy();
    var warlock = hero.findByType("warlock")[0];
    // Полечи паладина с низким количеством здоровья используя lowestHealthPaladin()
    if (lowestHealthPaladin()){
        if (paladin.canCast("heal")) {
            hero.command(paladin, "cast",  "heal", lowestHealthPaladin());
        } 
    } 
   //if (warlock){
    //    hero.command(paladin, "attack", warlock);
   // } else 
    if (strongestEnemy && strongestEnemy.health>15) {
        hero.command(paladin, "attack", strongestEnemy);
    } else if (enemy) hero.command(paladin, "attack", enemy);
}
function findStrongestEnemy(){
var enemies = hero.findEnemies();
var maxHealth = -Infinity;
var strongestEnemy = null;
for (var i = 0; i< enemies.length; i++){
    var enemy = enemies[i];
    if (maxHealth<enemy.health) {
        maxHealth = enemy.health;
        strongestEnemy = enemy;
    }
}
return strongestEnemy;
}
function findBestItem(items){
    var bestItem = null;
    var bestItemValue = -Infinity;
    for (var i = 0; i<items.length; i++){
        var item = items[i];
        if (excludedItems.length === 0 || excludedItems.indexOf(item)>-1){continue;}
        if (item.value/peasant.distanceTo(item)>bestItemValue){
                bestItem = item;
                bestItemValue = item.value/peasant.distanceTo(item);
            }
        }
    return bestItem;
}

function commandPeasant(peasant){
    var items = hero.findItems();
   var bestItem = findBestItem(items);
    var item = peasant.findNearestItem();
    
    if (bestItem){
        excludedItems.push(bestItem);
        hero.command(peasant, "move", bestItem.pos);    
    } else
    if (item){
        excludedItems.push(item);
        hero.command(peasant, "move", item.pos); 
    }
         
}
function commandGriffin(griffin){
    var warlock = hero.findByType("warlock")[0];
    var enemy = griffin.findNearestEnemy();
    var strongestEnemy = findStrongestEnemy();
    // 
    if (strongestEnemy && strongestEnemy.health>15) {
        hero.command(griffin, "attack", strongestEnemy);
    } else if (warlock){
       hero.command(griffin, "attack", warlock);
        } 
    else if (enemy) hero.command(griffin, "attack", enemy);
}

function commandFriends() {
    // Командуй своими союзниками.
    var friends = hero.findFriends();
    for(var i=0; i < friends.length; i++) {
        var friend = friends[i];
        if(friend.type == "peasant") {
            commandPeasant(friend);
        } else if(friend.type == "griffin-rider") {
            commandGriffin(friend);
        } else if(friend.type == "paladin") {
            commandPaladin(friend);
        }
    }
}
var excludedItems = [];
var peasants = hero.findByType("peasant");
while(true) {
    excludedItems.length === 0;
    if (hero.gold >= hero.costOf("griffin-rider")) {
        hero.summon("griffin-rider");
    }
    commandFriends();
}

This is the most successful code but not winning.

  1. If i try to comment hero.say(bestItemValue); there was infinite loop. Why?
  2. If i try to summon one more peasant code became realy slow or stuck. Why?
  3. I cant save Reinaldo. Where is the right strategy?
  4. Heeelp
// Ваша цель - защитить Рейнальдо.

// Найти паладина с самым низким количеством здоровья.
function lowestHealthPaladin() {
    var lowestHealth = 9999;
    var lowestFriend = null;
    var friends = hero.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;
}

function commandPaladin(paladin) {
    var enemy = paladin.findNearestEnemy();
    var strongestEnemy = findStrongestEnemy();
    var warlock = hero.findByType("warlock")[0];
    // Полечи паладина с низким количеством здоровья используя lowestHealthPaladin()
    hero.command(paladin, "move", {x:88, y:63});
    if (lowestHealthPaladin()){
        if (paladin.canCast("heal")) {
            hero.command(paladin, "cast",  "heal", lowestHealthPaladin());
        } 
    } 
   //if (warlock){
    //    hero.command(paladin, "attack", warlock);
   //} else 
    if (strongestEnemy && strongestEnemy.health>15) {
        hero.command(paladin, "attack", strongestEnemy);
   } else 
    if (enemy) hero.command(paladin, "attack", enemy);
}
function findStrongestEnemy(){
var enemies = hero.findEnemies();
var maxHealth = -999;
var strongestEnemy = null;
for (var i = 0; i< enemies.length; i++){
    var enemy = enemies[i];
    if (maxHealth<enemy.health) {
        maxHealth = enemy.health;
        strongestEnemy = enemy;
    }
}
return strongestEnemy;
}
function findBestItem(items){
    var bestItem = null;
    var bestItemValue = -99;
    for (var i = 0; i<items.length; i++){
        var item = items[i];
        if (excludedItems.indexOf(item)>-1 || item.pos.x > 42){continue;}
        if (item.value/peasant.distanceTo(item)>bestItemValue){
                bestItem = item;
                bestItemValue = item.value/peasant.distanceTo(item);
        }
        hero.say(bestItemValue);
        return bestItem;
    }
}

function commandPeasant(peasants){
    
    for (var i = 0; i<peasants.length; i++){
        var items = hero.findItems();
        var peasant = peasants[i];
        var bestItem = findBestItem(items);
        if (bestItem) {
            excludedItems.push(bestItem);
            hero.command(peasant, "move", bestItem.pos);
        }
    }         
}
function commandGriffin(griffin){
    var warlock = hero.findByType("warlock")[0];
    var enemy = griffin.findNearestEnemy();
    var strongestEnemy = findStrongestEnemy();
    
    
   // if (warlock){
  //     hero.command(griffin, "attack", warlock);
   //     } else
    if (strongestEnemy && strongestEnemy.health>15) {
        hero.command(griffin, "attack", strongestEnemy);
    } else
    if (enemy) hero.command(griffin, "attack", enemy);
}

function commandFriends() {
    // Командуй своими союзниками.
    var friends = hero.findFriends();
    for(var i=0; i < friends.length; i++) {
        var friend = friends[i];
        if(friend.type == "peasant") {
            continue;
        }  
        if(friend.type == "griffin-rider") {
            commandGriffin(friend);
        } else if(friend.type == "paladin") {
            commandPaladin(friend);
        }
    }
}

//hero.summon('peasant');
var peasants = hero.findByType("peasant");
while(true) {
    var excludedItems = [];
    if (hero.gold >= hero.costOf("griffin-rider")) {
        hero.summon("griffin-rider");
    }
    commandFriends();
    if (hero.canCast('goldstorm')) {
        hero.cast("goldstorm");
    }
    commandPeasant(peasants);
    
}

The slowness is caused by an infinite loop that doesn’t have much going on inside of it. hero.say() has a one second delay that is helping to slow down each loop iteration.

I’m sure this isn’t the only problem that your code has, but here’s one for you. Your code is:

if(friend.type == "peasant") {
    continue;
}  
if(friend.type == "griffin-rider") {
    commandGriffin(friend);
}

However, instead of continuing when your friend is a peasant, you need to use commandPeasant(friend). The if statement that comes after it needs to be an else if, not an if. This line in your main code: ‘commandPeasant(peasants);’ can be taken out. Additionally, your commandPeasant(peasants) function should instead be commandPeasant(peasant) and should not include a for loop. The idea is to send ONE peasant to the function, not all of them, and just handle that one peasant. As it stands now, your program is iterating through all the peasants when it shouldn’t need to, which might be contributing to the lag.

If you still have trouble and really need to finish this level, I would suggest resetting the code and following the directions even more carefully than before.