Summit's Gate Infinite Loop Help

Hi guys, I have ran into an infinite loop in my code

// Fight your way into the Inner Sanctum of the ogre chieftain, and defeat her.
var stage = 1;

var friends = hero.findFriends();
for (var i = 0; i < friends.length; ++i) {
    hero.command(friends[i], "move", Vector(0, 37));
}
 
function summonArcher() {
    if (hero.gold > hero.costOf("archer")) {
        hero.summon("archer");
    }
}

function specAttack(target) {
    if (hero.distanceTo(target) < 100) {
        while (target.health >= 0) {
            if (hero.isReady("slam")) {
                hero.slam(target);
            } else if (hero.isReady("bash")) {
                hero.bash(target);
            } else if (hero.canCast("chain-lightning")) {
                hero.cast("chain-lightning", target);
            } else if (hero.canCast("counter-blast")) {
                hero.cast("counter-blast", target);
            } else {
                hero.attack(enemy);
            }
        }
    }
}

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

function commandPaladin(paladin, stage) {
    var target = paladin.findNearestEnemy();
    if (target) {
        if (paladin.canCast("heal")) {
            if (hero.health <= 1000) {
                target = hero;
                if (target) {
                    hero.command(paladin, "cast", "heal", target);
                }
            } else  {
                target = lowestHealthPaladin();
                if (target) {
                    hero.command(paladin, "cast", "heal", target);
                }
            }
        } if (paladin.health < 100) {
            hero.command(paladin, "shield");
        } if (stage == 3) {
            var pos = {"x": hero.pos.x, "y": hero.pos.y};
            hero.command(paladin, "move", pos);
        } if (stage == 4) {
            if (warlock) {
                target = warlock;
            } if (target) {
                hero.command(paladin, "attack", target);
            } else {
                enemy = paladin.findNearestEnemy();
                if (enemy) {
                    hero.command(paladin, "attack", enemy);
                }
            }
        } if (stage == 5) {
            target = hero.findNearestEnemy();
            if (target) {
                hero.command(paladin, "attack", target);
            }
        }
    }
}

function commandSoldier(soldier, stage) {
    var target = soldier.findNearestEnemy();
    if (target) {
        if (stage == 3) {
            var pos = {"x": hero.pos.x, "y": hero.pos.y};
            hero.command(soldier, "move", pos);
        } if (stage == 4) {
            var warlock = archer.findNearest(hero.findByType("warlock"));
            if (warlock) {
                target = warlock;
            } if (target) {
                hero.command(soldier, "attack", target);
            } else {
                var enemy = soldier.findNearestEnemy();
                if (enemy) {
                    hero.command(soldier, "attack", enemy);
                }
            }
        } if (stage == 5) {
            target = hero.findNearestEnemy();
            if (target) {
                hero.command(soldier, "attack", target);
            }
        }
    }
}

function commandArcher(archer, stage) {
    var target = archer.findNearestEnemy();
    if (target) {
        if (stage == 1) {
            hero.command(archer, "move", Vector(0, 37));
        } if (stage == 3) {
            var pos = {"x": hero.pos.x, "y": hero.pos.y};
            hero.command(archer, "move", pos);
        } if (stage == 4) {
            var warlock = archer.findNearest(hero.findByType("warlock"));
            if (warlock) {
                target = warlock;
            } if (target) {
                hero.command(archer, "attack", target);
            } else {
                var enemy = archer.findNearestEnemy();
                if (enemy) {
                    hero.command(archer, "attack", enemy);
                }
            }
        } if (stage == 5) {
            target = hero.findNearestEnemy();
            if (target) {
                hero.command(archer, "attack", target);
            }
        }
    }
}

function commandFriends(stage) {
    var friends = hero.findFriends();
    for (var i = 0; i < friends.length; ++i) {
        if (friends[i].type == "paladin") {
            commandPaladin(friends[i], stage);
        } if (friends[i].type == "soldier") {
            commandSoldier(friends[i], stage);
        } if (friends[i].type == "archer") {
            commandArcher(friends[i], stage);
        }
    }
}

while(true) {
    summonArcher();
    var catapults = hero.findByType("catapult");
    if (stage == 1) {
        var enemy = hero.findNearestEnemy();
        if (enemy && enemy.type != "door") {
            specAttack(enemy);
            commandFriends();
        } else if (catapults.length) {
            specAttack(hero.findNearest(catapults));
        }
    } else if (!catapults.length){
        stage++;
        break;
    }
}

when I change this line:

} else {
    hero.attack(enemy);
}

to this:

} else {
    hero.attack(target);
}

My hero attacks the top catapult but then when she goes for the bottom one, it just stops. This doesn’t happen when the argument for attack is enemy and not target. However, when it is enemy, it hits the gate once, slams the catapult, hits the gate again and finishes the catapult which results in getting hit twice by the catapult. Could someone please help? Thanks

I think the++i should be i++

It works either way. (20chars)

Ok, having solved that other infinite loop, I’ve ran into another one (I must be getting good at this):

// Fight your way into the Inner Sanctum of the ogre chieftain, and defeat her.
var stage = 1;

// Command friends to hide
var friends = hero.findFriends();
for (var i = 0; i < friends.length; ++i) {
    hero.command(friends[i], "move", Vector(0, 37));
}

function summonArcher() {
    if (hero.gold > hero.costOf("archer")) {
        hero.summon("archer");
    }
}

function lowestHealthPaladin() {
    var lowestHealth = 99999;
    var lowestFriend = null;
    var friends = hero.findFriends();
    for (var i = 0; i < friends.length; ++i) {
        if (friends[i].health < lowestHealth && friends[i].health < friends[i].maxHealth) {
            lowestHealth = friends[i].health;
            lowestFriend = friends[i];
        }
    }
    return lowestFriend;
}


function commandPaladin(paladin) {
    if (paladin.health < 100) {
        hero.command(paladin, "shield");
    }
    if (stage == 2) {
        hero.command(paladin, "move", {"x": 67, "y": 33});
    }
    if (stage == 3) {
        hero.command(paladin, "move", {"x": 264, "y": 33});
        if (paladin.canCast("heal")) {
            if (hero.health <= 3500) {
                target = hero;
                if (target) {
                    hero.command(paladin, "cast", "heal", target);
                }
            } else {
                var target = lowestHealthPaladin();
                if (target) {
                    hero.command(paladin, "cast", "heal", target);
                }
            }
        } 
    }
}

function commandArcher(archer) {
    if (stage == 1) {
        hero.command(archer, "move", Vector(0, 37));
    }
    if (stage == 2) {
        var enemy = archer.findNearestEnemy();
        if (enemy) {
            hero.command(archer, "attack", enemy);
        }
    }
    if (stage == 3) {
        hero.command(archer, "move", {"x": 259, "y": 33});
    }
    if (stage == 4) {
        // hero.command(archer, "move", {"x": 259, "y": 33});
    }
}

function commandSoldier(soldier) {
    if (stage == 2) {
        hero.command(soldier, "move", {"x": 67, "y": 33});
    }
    if (stage == 3) {
        hero.command(soldier, "move", {"x": 249, "y": 33});
    }
    if (stage == 4) {
        // hero.command(soldier, "move", {"x": 249, "y": 33});
    }
}

function commandFriends() {
    var friends = hero.findFriends();
    for (var i = 0; i < friends.length; ++i) {
        if (friends[i].type == "soldier") {
            commandSoldier(friends[i]);
        }
        if (friends[i].type == "archer") {
            commandArcher(friends[i]);
        }
        if (friends[i].type == "paladin") {
            commandPaladin(friends[i]);
        }
    }
}

function specAttack(target) {
    if (target && target.type != "door") {
        if (hero.distanceTo(target) < 100) {
            while (target.health >= 0) {
                if (hero.isReady("slam")) {
                    hero.slam(target);
                } else if (hero.isReady("bash")) {
                    hero.bash(target);
                } else if (hero.canCast("chain-lightning")) {
                    hero.cast("chain-lightning", target);
                } else if (hero.canCast("counter-blast")) {
                    hero.cast("counter-blast", target);
                } else {
                    hero.attack(target);
                }
            }
        }
    }
}

function collect() {
    var item = hero.findNearestItem();
    if (item) {
        hero.move(item.pos);
    }
}

// Stage 1 - attack fangriders and catapults. The catapults will kill the others
while(true) {
    if (stage == 1) {
        summonArcher();
        commandFriends();
        var fangs = hero.findByType("fangrider");
        var catapults = hero.findByType("catapult");
        var enemy = hero.findNearestEnemy();
        if (fangs.length) {
            specAttack(hero.findNearest(fangs));
        } if (catapults.length) {
            specAttack(hero.findNearest(catapults));
        } else if (enemy.type != "door") {
            specAttack(enemy);
        } else {
            stage = 2;
            hero.wait(1);
            hero.moveXY(93, 34);
        }
    } else if (stage != 1) {
        break;
    }
}

// Stage 2 - Command archers to breach the outer gate, go inbetween the towers and shield while the archersdestroy the towers.
while(true) {
    if (stage == 2) {
        summonArcher();
        commandFriends();
        var enemy = hero.findNearestEnemy();
        if (enemy && enemy.type != "door") {
            hero.moveXY(130, 32.5);
        }
        hero.shieldBubble();
        if (hero.time >= 49.5) {
            stage = 3;
        }
    } else {
        break;
    }
}

// Destroy the inner gate
var enemy = hero.findNearestEnemy();
if (enemy && enemy.type == "door") {
    while (enemy.health > 0) {
        hero.attack(enemy);
    }
}
hero.wait(5);

// Stage 3 - move all units close to the inner sanctum, but out of sight of the warlocks. Heal all units
while(true) {
    if (stage == 3) {
        summonArcher();
        commandFriends();
        hero.moveXY(266, 34);
        if (hero.time >= 100) {
            stage = 4;
        }
    } else {
        break;
    }
}

// Stage 4 - attack warlocks FIRST, deal with the skeletons and heal hero.
while(true) {
    if (stage == 4) {
        var enemy = hero.findNearestEnemy();
        var warlocks = hero.findByType("warlock");
        if (warlocks.length) {
            specAttack(hero.findNearest(warlocks));
        } else if (enemy.type != "door"){
            specAttack(enemy);
        } else if (hero.time >= 140){
            stage = 5;
        }
    } else {
        break;
    }
}

I have noticed that the infinite loop appears if I try to kill the skeletons after the warlocks are dead - otherwise, warlocks are dead and my hero gets mutilated by the skeletons. I don’t want to risk bringing in any allies or I might lose too many to the skeletons.@Deadpool198, @xython, anybody, thanks for any help.

Please, could anybody help??

I don’t know exactly why you have an endless loop but I think it’s because
your code is unnecessarily complicated with stages, timeouts, and too general functions. ( you command paladins in too many places and I’m not sure they always obey you)

i think this code would do the job:

// stage 4
// command the archers to defend a point. (265, 33)? (can be done outside the loop)
// then:
while (true){
  let warlocks = hero.findByType("warlock"),
      skeletons = hero.findByType("skeleton");
  if (warlocks.length > 0){
      hero.attack(hero.findNearest(warlocks));
  } else if (skeletons.length > 0){
      hero.attack (hero.findNearest(skeletons));
  } else { // only the door is standing
       break;
  } 
}

you can add chain lightning and other skills specific to your hero. Shield the paladins while fighting and heal your hero and paladins or do the healing after.

Well, you don’t know. I tried that but if I try to attack the warlocks and then attack the skeletons, that’s where the infinite loop comes in.

I think I found the problem.
For each stage you have, you are making a “while true” loop. So that means you are constantly repeating this loop, I think what you should do is put all the conditions of stages in one while true loop, for example:

while true:
if stage equals to 1:
"code" 
else if stage equals to 2:
"code"

etc.