I have tried several different versions of this, but I cant crack the code. When I write nested if statements for each enemy.type, the loop stops after first attack. When I write it like this, the code runs 1 time and then I get the error that type property is null and the hero just stands there. Im loosing my mind on this level
What do I need to write for this code to work?
I want to attack throwers first, then munchkins and use cleave when ready.
while (true) {
var munchkin = hero.findByType("munchkin", hero.findEnemies());
var thrower = hero.findByType("thrower", hero.findEnemies());
var enemy = hero.findNearestEnemy();
if (enemy.type === thrower) {
hero.attack(enemy);
} else if (enemy) {
if (hero.isReady("cleave")) {
hero.attack(enemy);
} else {
hero.attack(enemy);
}
}
Hello and welcome to codecombat discourse! This is a cozy forum where you can share ideas, share fan art, get assistance for code, etc! Before you proceed, we hope that you review this topic, which shows all essentials of this board! Thanks!
If enemy does not exist, then you cannot check enemy.type; hero.findNearestEnemy() returns null if no enemy is found, which has no .type property. You need to first check for existence of enemy before accessing any of it’s properties:
if (enemy && enemy.type === "thrower") {...}
&& is short-circuiting, which means that if the first check (the truthiness of enemy) fails, then the second check (enemy.type === "thrower") will never be evaluated, avoiding trying to read .type on null.
I want to attack throwers first, then munchkins and use cleave when ready.
// Untested code
// Attack throwers, then attack and cleave everyone else
while (true) {
let thrower = hero.findNearest(hero.findByType("thrower", hero.findEnemies()));
let enemy = hero.findNearestEnemy();
if (thrower)
hero.attack(thrower);
else if (enemy) {
if (hero.isReady("cleave")) hero.cleave(enemy);
else hero.attack(enemy);
}
}
Alternatively, with clever use of ||:
// Untested code
// Attack and cleave throwers first, then everyone else
while (true) {
let enemy = hero.findNearest(hero.findByType("thrower", hero.findEnemies()))
|| hero.findNearestEnemy();
if (enemy) {
if (hero.isReady("cleave")) hero.cleave(enemy);
else hero.attack(enemy);
}
}
This is very interesting.
When I read the code you presented, I understand it perfectly.
You have defined what thrower is, used hero.findenemies to establish where it is and thus hero.attack(thrower) should work.
But I still get an error I have struggled with trying different things.
“Argument error: Target a unit”
When you use hero.findByType(), it’s returning an entire array of all "throwers", not just once, so the code doesn’t know which one to target, hence why it’s telling you to specify an object. That means you need to specify one of the throwers to choose. If you’ve unlocked hero.findNearest(), which returns the nearest unit of that array, you can use hero.findNearest(hero.findByType("thrower")) to return the closest thrower. Otherwise, you can choose the first unit in that thrower array, by adding [0] to specify the first item in the array. (hero.findByType("thrower")[0]) However, that’s introduced in the mid-mountain levels and not in the forest, so it shouldn’t be required. Just adding an if statement should work for forest levels:
var enemy = hero.findNearestEnemy();
if (enemy){
if (enemy.type == "thrower"){
// Insert attack code
}
}