Java: Salted Earth

I get error on line 7: TypeError. Cannot read property ‘type’ of null.
The Objective of this level are:

// Ogres are attacking a nearby settlement!
// Be careful, though, for the ogres have sown the ground with poison.
// Gather coins and defeat the ogres, but avoid the burls and poison!

This was the code given to you.

while(true) {
    var enemy = hero.findNearestEnemy();
    if(enemy.type == "munchkin" || enemy.type == "thrower") {
        hero.attack(enemy);
    }

This was the code I wrote to have my character check to see if the item was coin or a gem.

    var item = hero.findNearestItem();
    var pos = item.pos;
    var x = pos.x;
    var y = pos.y;
// Check the item type to make sure the hero doesn't pick up poison!
// Look for types: 'gem' and 'coin'
    if (item == "coin" || "gem") {
        hero.moveXY(x, y);
        
    }

The full code looks like this:

while(true) {
    var enemy = hero.findNearestEnemy();
    if(enemy.type == "munchkin" || enemy.type == "thrower") {
        hero.attack(enemy);
    }
    var item = hero.findNearestItem();
    var pos = item.pos;
    var x = pos.x;
    var y = pos.y;

    if (item == "coin" || "gem") {
        hero.moveXY(x, y);
        
    }
}

I also noticed a few things with this level. No throwers or gem’s spawn throughout the level while running. And the directions never mention picking up gems or killing throwers, but before you start the level it does and the hints say it as well.

Update: Also tried this

while(true) {
    var enemy = hero.findNearestEnemy();
    if(enemy.type == "munchkin" || enemy.type == "thrower") {
        hero.attack(enemy);
    }
    var item = hero.findNearestItem();
    var pos = item.pos;
    var x = pos.x;
    var y = pos.y;

    if (item.type == "coin" || item.type == "gem") {
        hero.moveXY(x, y);
        
    }
}

as well as this

while(true) {
    var enemy = hero.findNearestEnemy();
    if(enemy.type == "munchkin" || enemy.type != "burl") {
        hero.attack(enemy);
    }
    var item = hero.findNearestItem();
    var pos = item.pos;
    var x = pos.x;
    var y = pos.y;

    if (item.type == "coin" || item.type != "poison") {
        hero.moveXY(x, y);
        
    }
}

Your saying this code was given to you?

var enemy = hero.findNearestEnemy();
    if(enemy.type == "munchkin" || enemy.type != "burl") {
        hero.attack(enemy);

This is where your error is coming from.
I get error on line 7: TypeError. Cannot read property 'type' of null.

Sometime during runtime theirs a point where theirs no enemy and it cant read the ‘Type’ of an enemy that doesnt exist yet. You need to add enemy such as. enemy && (enemy.type == "munchkin" || enemy.type != "burl")
.
.
.
Edit: Actually it might be from (item.type == "coin" || item.type != "poison") also. You need to see if thiers an item before trying to get the type of the item.

Actually you shouldnt even use variable item untill you know it exists. You could just enclose all the code dealing with the variable item inside an if(item) statement.

I’m not sure I follow. I tried these 3 things

Solution 1: Returned Error on line 7: TypeError. Cannot read property ‘type’ of null.

while(true) {
    var enemy = hero.findNearestEnemy();
    if(enemy.type == "munchkin" || enemy.type == "thrower") {
        hero.attack(enemy);
    }
    var item = hero.findNearestItem();
    var pos = item.pos;
    var x = pos.x;
    var y = pos.y;

    if (item == "coin" || "gem") {
        hero.moveXY(x, y);
        
    }
}

Solution 2: First attempt: Died, walked into Burl and attacked it as well as collected poison.

Solution 2 on Reloaded Page: Worked, Stood still till an enemy came out attacked it then collected the coin once it spawned.

while(true) {
    var enemy = hero.findNearestEnemy();
    if(enemy.type == "munchkin" || enemy.type == "thrower") {
        hero.attack(enemy);
    }
    var item = hero.findNearestItem();
    var pos = item.pos;
    var x = pos.x;
    var y = pos.y;

    if (item.type == "coin" || item.type == "gem") {
        hero.moveXY(x, y);
        
    }
}

Solution 3: Original try I would kill first enemy walk to coin collect it run down to the burl hit it once run and collect all the poison then die.

Solution 3 Reloaded Page: Hero kills first enemy then collects coin stops moving and kills enemies as they approach collecting coins as they spawn. (this solution seems to work now but I am unsure why as it did not work the previous times I tried it.

while(true) {
    var enemy = hero.findNearestEnemy();
    if(enemy.type == "munchkin" || enemy.type != "burl") {
        hero.attack(enemy);
    }
    var item = hero.findNearestItem();
    var pos = item.pos;
    var x = pos.x;
    var y = pos.y;

    if (item.type == "coin" || item.type != "poison") {
        hero.moveXY(x, y);
        
    }
}

I am getting beyond confused now. Because the code I wrote for all 3 solutions previously did not work but having gone back and repasting in code I have already written it seems to work. Is the source code just buggy? Can you go to the level and paste in my code and see if you can recreate the errors?

Also by code given to me I meant this is what you start with when you first open the level.

No its just how the levels are set up. Everytime you press submit you will get a new set of events. If you press submit again you might fail again or you might pass. Your code does get the job done but its not dynamic enough so it only works if the right events happen at the right time.

Can you explain it to me on how to make the code work dynamically so it will always work not just sometimes?

Yes ill explain but in the furture when you have a line error please post a picture. I was counting 7 lines down from the code you posted but with the picture you just posted its very helpful to see where line 7 was.

I believe I explained the problems in my 1st post but ill break it down. You said you dont follow. Is that for the entire post or are their some things in my post you did understand? I can reword what ever you didnt get.

The pre written code is not finished yet. Or better yet I think you could even replace all the code inside the if to say attack everything but the burls. You just need to make sure theirs an enemy before looking for the type of enemy.

With the items if statement you could say pick up everything except poison and also make sure theirs an item before looking at the type. I also think you should look to see if theirs an item before creating the variables pos, x, and y.

I dont know if you know how to look to see if theirs an enemy or item but the code would look like if(item) or if(enemy)

Hope this helps.:smiley:

Alright I reread everything you said and went back to the level and started from scratch and wrote this code. Everything worked and I passed.

while(true) {
    var enemy = hero.findNearestEnemy();
    if(enemy.type == "munchkin" || enemy.type != "burl") {
        hero.attack(enemy);
    }

    var item = hero.findNearestItem();

    if (item && item.type == "coin" || item.type != "poison") {
        hero.moveXY(item.pos.x, item.pos.y);
    }
}

I’m going to break it down on how I understand it and then if you can tell me if I understand it right and if not explain why its wrong.


First off you set the var enemy = hero.findNearestEnemy(); this will look for the nearest enemy.

Then you create an if statement where if an enemy is present and the enemy is a munchkin or not a burl your hero will attack the enemy.

    if(enemy && enemy.type == "munchkin" || enemy.type != "burl") {
        hero.attack(enemy);
    }

The next thing to do is define a variable that looks for an item. var item = hero.findNearestItem();

Then you must make and if statement that looks for the item and then checks to see if the item is a coin or not poison. If the item exists and is a coin and not poison the hero will move to the items X and Y position if it is poison the hero will remain still and wait till something that is true within the while loop happens

    if (item && item.type == "coin" || item.type != "poison") {
        hero.moveXY(item.pos.x, item.pos.y);
    }

Now you said that the code could be completely rewritten if the objective of the level was to just pick up coins and kill ogres and I didn’t have to use or the code could be simplified and written this way correct?

while(true) {
    var enemy = hero.findNearestEnemy();
    if(enemy && enemy.type != "burl") {
        hero.attack(enemy);
    }

    var item = hero.findNearestItem();

    if(item && item.type == "coin") {
        hero.moveXY(item.pos.x, item.pos.y);
    }
}

This code looks for any enemy as long as it isn’t a burl and attacks that enemy then it looks for any item as long as the item is a coin the hero will walk to the item’s( the coin in this case) X and Y position and pick it up correct?

Yes this code looks very nice but I dont know if you will pass.

while(true) {
    var enemy = hero.findNearestEnemy();
    if(enemy && enemy.type != "burl") {
        hero.attack(enemy);
    }

    var item = hero.findNearestItem();

    if(item && item.type == "coin") {
        hero.moveXY(item.pos.x, item.pos.y);
    }
}

Since their may also be gems it should maybe say item.type != "poison" Instead of == "coin" That should pick up eveything except the poison. The way the code is written now I dont think you will get the ‘type’ error any more. Did you run this? It looks like it would pass.

Yes I ran this code and it worked just fine

while(true) {
    var enemy = hero.findNearestEnemy();
    if(enemy && enemy.type != "burl") {
        hero.attack(enemy);
    }

    var item = hero.findNearestItem();

    if(item && item.type == "coin") {
        hero.moveXY(item.pos.x, item.pos.y);
    }
}

I also ran the code with your suggestion just now as well, and it worked fine also

while(true) {
    var enemy = hero.findNearestEnemy();
    if(enemy && enemy.type != "burl") {
        hero.attack(enemy);
    }

    var item = hero.findNearestItem();

    if(item && item.type != "poison") {
        hero.moveXY(item.pos.x, item.pos.y);
    }
}

How ever both of these solutions aren’t how the actual level wants you to solve it.
Here’s the screen it presents to you before starting the level.

So if I had to use an || to compare the two types of data to solve it like the level wants then this solution I stated above will be fine correct? It did pass but will it pass all random generated scenarios?

This is the solution previously stated above:

while(true) {
    var enemy = hero.findNearestEnemy();
    if(enemy.type == "munchkin" || enemy.type != "burl") {
        hero.attack(enemy);
    }

    var item = hero.findNearestItem();

    if (item && item.type == "coin" || item.type != "poison") {
        hero.moveXY(item.pos.x, item.pos.y);
    }
}

Ok so the level is trying to teach you about booleans. In that case you dont have to change if(enemy.type == "munchkin" || enemy.type == "thrower") You dont need to add in != "burl" because you will only attack if its one of the two.

For the item if statement you could copy any paste. Just change the variable names. item.type == "coin" || item.type == "gem" If the items are already out on the map then I supose you dont need the if(item) part since they didnt check if(enemy).

I dont really know how the level plays out but you might get the ‘type’ error again. You can just add if(item) or if(enemy) and that should fix it.
.
.
.
Just know.

if(enemy && enemy.type == "munchkin" || enemy.type == "thrower")
is different from
if(enemy && (enemy.type == "munchkin" || enemy.type == "thrower"))
.
.
.
if(enemy && enemy.type == "munchkin" || enemy.type == "thrower") ==
if((enemy && enemy.type == "munchkin") || enemy.type == "thrower")

Hmm, I feel kind of dumb now since the answer was so obvious looking at it now. I feel like I tried this and it didn’t work but I just typed this in and tried it and this does work.

while(true) {
    var enemy = hero.findNearestEnemy();
    if(enemy.type == "munchkin" || enemy.type == "thrower") {
        hero.attack(enemy);
    }
    var item = hero.findNearestItem();
    // Check the item type to make sure the hero doesn't pick up poison!
    // Look for types: 'gem' and 'coin'
     if(item.type == "coin" || item.type == "gem") {
        hero.moveXY(item.pos.x, item.pos.y);
    }
}

My understanding of this is in the first if statement its checking to see if either a munchkin or thrower exists if they do attack them then its checking to see if a gem or coin exists and if its true the hero will go pick them up. Thus avoiding all the poisons.

Yes all the poison and burls.

Sweet I understand it very well now thanks. Now onto my next problem in a whole new level xD

I tried your code, but the character went for the poison anyway.
// Ogres are attacking a nearby settlement!
// Be careful, though, for the ogres have sown the ground with poison.
// Gather coins and defeat the ogres, but avoid the burls and poison!
while (true) {
var enemy = hero.findNearestEnemy();
if (enemy.type == “munchkin” || enemy.type == “thrower”) {
hero.attack(enemy);
}
var item = hero.findNearestItem();
// Check the item type to make sure the hero doesn’t pick up poison!
// If the item’s type is “gem” or “coin”:
var pos = item.pos;
var x = pos.x;
var y = pos.y;
if (item.type == “coin” || item.type != “poison”) {
var pos = item.pos;
var x = pos.x;
var y = pos.y;
}
// Then move and pick it up:
hero.moveXY(x, y);
}

YT, please do not post the same question in multiple topics…it will not speed up an answer and only clutters the forum.

How do I put the boolean lines in the code I am brand new and can’t figure it out at all

Hi Ratfight,

Welcome to the forum!

Please post the code that you have so far for the level, using the </> in the reply box to format the code.

Thanks,

Jenny

1 Like