Play Home Contribute Github Join Us! Discourse Staff Members Github Contribution Guides Team

[Solved] The Trials - JavaScript help needed

I have passed the level because my inventory is good, but my code doesn’t work the way I expect. Can anyone please explain what’s wrong?

The game loop contains several fuctions:

  1. checks if hero needs healing
  2. checks if there is a green to pick up
  3. fights
  4. if a black flag is set, pick up mushrooms

The fight() function consists of the following steps:

  1. obtain array of enemies
  2. check if array is empty
    2.1) if array is empty - return
  3. if array is not empty, loop through array and attack oasis giardians, throwers and shamans if any
  4. update array of enemies
  5. if array is not empty and
    5.1) if enemy №1 is near - attack enemy
    5.2) call function fight() again
    5.3) if enemy №1 is far - attack enemy
    5.4) call function fight() again
  6. if array is empty - return

This way newly arrived ranged units should be attacked first. If there are any melee units left nearby, at step 5.1, the closest of them should be attacked. When the function fight() runs again and there are no ranged units, a closest melee enemy should be attacked from the updated array of enemies. When there is no enemy left near, the hero should go to a far enemy, attack and the function should run until the enemy array is empty.

Instead I see Senick attack far enemies while surrounded by near enemies.

The steps 5.1 and 5.2 seem to get skipped and I don’t see why.
If I remove steps 5.3 and 5.4 the array of enemies doesn’t get updated at all.

I’ve spent quite a while trying to spot what’s wrong, but had no luck so far. I will very very much appreciate some help!

This is my code:
function stayFit(){
    if(hero.health < hero.maxHealth - 200 && hero.isReady("heal") ){
        hero.heal(hero);
        hero.say("I heal");
    }
}

function goOnManual(){
    var flag=hero.findFlag("green");
    if (flag){
        hero.pickUpFlag(flag);
    }
}

function fight(){
    var enemies=hero.findEnemies();
    var enemyIndex=0;
    if (enemies.length === 0){
        return;
    } else {        
        while(enemyIndex < enemies.length){
            var enemy=enemies[enemyIndex];
            if ( enemy.type=="oasis-guardian" && hero.isReady("throw") && hero.distanceTo(enemy) < 30){
                hero.throw(enemy);
                while(enemy.health>0){
                    hero.attack(enemy);
                }
            } else if ( (enemy.type=="thrower" || enemy.type=="shaman") && hero.distanceTo(enemy) < 30){
                hero.attack(enemy);
            }
            enemyIndex++;
        }
        enemies=hero.findEnemies();
        if (enemies.length){
           if (hero.distanceTo(enemies[0]) < 30) {
                hero.attack(enemies[0]);
                hero.say("Near enemy");
                fight();
            } else {
                hero.move(enemies[0].pos);
                hero.attack(enemies[0]);
                hero.say("Far enemy");
                fight(); 
            }
        } else {
            return;
        }
    }
}

function collectMushrooms(){
    var mushroomFlag=hero.findFlag("black");
    if (mushroomFlag){
        var mushrooms=hero.findItems();
        var mushroomIndex=0;
        while(mushroomIndex < mushrooms.length){
            var mushroom=mushrooms[mushroomIndex];
            hero.moveXY(mushroom.pos.x, mushroom.pos.y);
            mushroomIndex++;
        }
        hero.pickUpFlag(mushroomFlag);
    }
    
}

while(true){
    stayFit();
    goOnManual();
    fight();
    collectMushrooms();
}
My inventory includes:

Fine Telephoto Glasses
Precision Rifle
Sparkbomb
Hardened Emerald Chainmail body piece

What do you return here?

Andrei

1 Like

Try to make this a different function than fight() because you might get an error because you do not stop from making the function fight() and you use it.

Andrei

1 Like

I figured it out! Sorry about bothering…

The array doesn’t always start with the nearest enemy, so enemies[0] may be further than the hero.attackRange. This way the condition in step 5.2 (if (hero.distanceTo(enemies[0]) < 30) ) is not always true and the function fight() may not get called again here. It gets called in step 5.3 for sure, fo removing steps 5.3/5.4 results in ending the function instead of re-running it.

Nothing. This is how I make the function stop and not go into infinite loop when there are no enemies in range. I wonder if this is a good practice, but it works.

Something else I discovered is that hero.findEnemies() returns defeated enemies as well. Hero doesn’t attack them, but enemies.length > 0 so the function doesn’t stop here. So I also have to check if enemies are alive before re-running the function.

I decided to do without attacking enemies beyond hero.attackRange. This way I first loop through the array of enemies to attack every ranged unit. If in an updated array only melee units are left, I loop through the array until I find a living enemy within attack range. A loop is needed because this will not necessarily be enemies[0]. After attacking one melee unit, I re-run the function to (firstly) check for new ranged enemies and (secondly) deal with one more living melee enemy. The function ends in two cases: 1) there are no enemies within range 2) all enemies within range are defeated .

2 Likes

Can you please delete the working code because posting solutions is not allowed by this forum’s rules?

Andrei

2 Likes

Thank you! I did not know that.

1 Like

No problem! Just do not do it again, ok? :wink:

Andrei

2 Likes

This topic was automatically closed 12 hours after the last reply. New replies are no longer allowed.