CS5 level 30 "reindeer tender" issues - Unable to figure out error message. (JAVASCRIPT)

So, I have what I believe to be what I’m asked to write on this level.

// This is the array of pen positions
var penPositions = [ {"x":20,"y":24}, {"x":28,"y":24}, {"x":36,"y":24}, {"x":44,"y":24}, {"x":52,"y":24} ];

// Use this array to keep track of each pen's reindeer.
var penOccupants = [ null, null, null, null, null ];

// And this array contains our reindeer.
var friends = hero.findFriends();

// Figure out which reindeer are already in their pens.
var reindeer = null;
for (var deerIndex = 0; deerIndex < friends.length; deerIndex++) {
    reindeer = friends[deerIndex];
    
    // For each position check if it matches a reindeer.
    for (var penIndex = 0; penIndex < penPositions.length; penIndex++) {
        var penPos = penPositions[penIndex];
        
        if (penPos.x == reindeer.pos.x && penPos.y == reindeer.pos.y) {
            // Put the reindeer in occupants at penIndex
            penOccupants[penIndex] = reindeer;
            // Remove the reindeer from the friends array.
            friends[penIndex] = null;
            // break out of the inner loop here:
            break;
        }
    }
}

// Assign the remaining reindeer to new positions.
for (deerIndex = 0; deerIndex < friends.length; deerIndex++) {
    // If the reindeer is null, use continue:
    if(reindeer === null){
        continue;
    }
    
    // Look for the first pen with nothing.
    for (var occIndex = 0; occIndex < penOccupants.length; occIndex++) {
        // If there is nothing, the pen is open:
        if (penOccupants[occIndex] === null) {
            // Put the reindeer in the occupants array.
            penOccupants[occIndex] = reindeer;
            // Command the reindeer to move to the pen.
            hero.command(reindeer,"move",penPos);
            // break out early so we don't reassign:
            break;
        }
    }
}

However, at line 19,

if (penPos.x == reindeer.pos.x && penPos.y == reindeer.pos.y) {

I receive the error “TypeError: cannot read property ‘pos’ of null”.
I’m not sure how to fix this or what I did wrong and would like some help. Thanks!

  1. use let not var, var is outdated and doesn’t work well
  2. === not == since sometimes there is problems
  3. for of loop, for (let variable of array), so instead of having to write a for index loop you can just write for of and it’s much simpler, for (let reindeer of hero.findFriends()), for (let penPos of penPositions)
  4. {x: number, y: number} not {"x": number, "y": number} unless you’re using python or using variable names with spaces (which I do not recommend)
  5. no modifying arrays without first knowing what you’re doing, so no friends[penIndex] = null, and that is the bug, penIndex is not an index of the friends array, but the index of the penPositions array, so it should be friends[deerIndex] = null

hope it worked, if it didn’t, post your code again after applying the changes I mentioned in 4 and 5 (others are not as important)

Only problem with this is that if this is all the problems with the code, then the default javascript code you are given has errors that prevent it from working properly. It shouldn’t be like that; the default code you start with should not have any errors. I appreciate it though and will try it and see if it works.

Okay, UPDATE, @moonwatcher348 your tips did help solve the errors produced except now the reindeer do not move anywhere. I will put the updated code here (I did not alter the for loops as I personally don’t see any benefit in that.)

// This is the array of pen positions
var penPositions = [ {x:20,y:24}, {x:28,y:24}, {x:36,"y":24}, {x:44,y:24}, {x:52,y:24} ];

// Use this array to keep track of each pen's reindeer.
var penOccupants = [ null, null, null, null, null ];

// And this array contains our reindeer.
var friends = hero.findFriends();

// Figure out which reindeer are already in their pens.
var reindeer = null;
for (var deerIndex = 0; deerIndex < friends.length; deerIndex++) {
    reindeer = friends[deerIndex];
    
    // For each position check if it matches a reindeer.
    for (var penIndex = 0; penIndex < penPositions.length; penIndex++) {
        var penPos = penPositions[penIndex];
        
        if (penPos.x === reindeer.pos.x && penPos.y === reindeer.pos.y) {
            // Put the reindeer in occupants at penIndex
            penOccupants[penIndex] = reindeer;
            // Remove the reindeer from the friends array.
            friends[deerIndex] = null;
            // break out of the inner loop here:
            break;
        }
    }
}

// Assign the remaining reindeer to new positions.
for (deerIndex = 0; deerIndex < friends.length; deerIndex++) {
    // If the reindeer is null, use continue:
    if(reindeer === null){
        continue;
    }
    
    // Look for the first pen with nothing.
    for (var occIndex = 0; occIndex < penOccupants.length; occIndex++) {
        // If there is nothing, the pen is open:
        if (penOccupants[occIndex] === null) {
            // Put the reindeer in the occupants array.
            penOccupants[occIndex] = reindeer;
            // Command the reindeer to move to the pen.
            hero.command(reindeer,"move",penPos);
            // break out early so we don't reassign:
            break;
        }
    }
}

I appreciate the tips given so far.

I still do not see a solution, so currently more help is needed, however I will post updates here, mostly for future reference, especially for those in the future who may run into the same problem. I don’t want to be someone who just leaves “solved, thanks” when they fix a problem that is hard to identify a solution for.

Update 2. I changed the “var” in the for statements to “let”, but now I receive the following error “ArgumentError: Target an {x: number, y: number} position.”
at hero.command(reindeer,"move",penPos);.

Here is my current code.

// This is the array of pen positions
var penPositions = [ {x:20,y:24}, {x:28,y:24}, {x:36,y:24}, {x:44,y:24}, {x:52,y:24} ];

// Use this array to keep track of each pen's reindeer.
var penOccupants = [ null, null, null, null, null ];

// And this array contains our reindeer.
var friends = hero.findFriends();

// Figure out which reindeer are already in their pens.
var reindeer = null;
for (let deerIndex = 0; deerIndex < friends.length; deerIndex++) {
    reindeer = friends[deerIndex];
    
    // For each position check if it matches a reindeer.
    for (let penIndex = 0; penIndex < penPositions.length; penIndex++) {
        var penPos = penPositions[penIndex];
        
        if (penPos.x === reindeer.pos.x && penPos.y === reindeer.pos.y) {
            // Put the reindeer in occupants at penIndex
            penOccupants[penIndex] = reindeer;
            // Remove the reindeer from the friends array.
            friends[deerIndex] = null;
            // break out of the inner loop here:
            break;
        }
    }
}

// Assign the remaining reindeer to new positions.
for (deerIndex = 0; deerIndex < friends.length; deerIndex++) {
    // If the reindeer is null, use continue:
    if(reindeer === null){
        continue;
    }
    
    // Look for the first pen with nothing.
    for (var occIndex = 0; occIndex < penOccupants.length; occIndex++) {
        // If there is nothing, the pen is open:
        if (penOccupants[occIndex] === null) {
            // Put the reindeer in the occupants array.
            penOccupants[occIndex] = reindeer;
            // Command the reindeer to move to the pen.
            hero.command(reindeer,"move",penPos);
            // break out early so we don't reassign:
            break;
        }
    }
}

Nevermind, I identified an error. PenPos is not in the relevant context. I will instead create a new variable that stores the current relevant pen position.

Update
Now, only one reindeer, specifically one that is already in a pen, will move to the last pen. The rest remain stationary.

// This is the array of pen positions
var penPositions = [ {x:20,y:24}, {x:28,y:24}, {x:36,y:24}, {x:44,y:24}, {x:52,y:24} ];

// Use this array to keep track of each pen's reindeer.
var penOccupants = [ null, null, null, null, null ];

// And this array contains our reindeer.
var friends = hero.findFriends();

// Figure out which reindeer are already in their pens.
var reindeer = null;
for (let deerIndex = 0; deerIndex < friends.length; deerIndex++) {
    reindeer = friends[deerIndex];
    
    // For each position check if it matches a reindeer.
    for (let penIndex = 0; penIndex < penPositions.length; penIndex++) {
        var penPos = penPositions[penIndex];
        
        if (penPos.x === reindeer.pos.x && penPos.y === reindeer.pos.y) {
            // Put the reindeer in occupants at penIndex
            penOccupants[penIndex] = reindeer;
            // Remove the reindeer from the friends array.
            friends[deerIndex] = null;
            // break out of the inner loop here:
            break;
        }
    }
}

// Assign the remaining reindeer to new positions.
for (deerIndex = 0; deerIndex < friends.length; deerIndex++) {
    // If the reindeer is null, use continue:
    if(reindeer === null){
        continue;
    }
    
    // Look for the first pen with nothing.
    for (var occIndex = 0; occIndex < penOccupants.length; occIndex++) {
        // If there is nothing, the pen is open:
        if (penOccupants[occIndex] === null) {
            // Put the reindeer in the occupants array.
            penOccupants[occIndex] = reindeer;
            // Command the reindeer to move to the pen.
            var targetPenPos = penPositions[occIndex];
            hero.command(reindeer,"move",targetPenPos);
            // break out early so we don't reassign:
            break;
        }
    }
}

variable doesn’t exist in context, needs let, let is in private scope while var is global (still, don’t use var though)

Didn’t catch that, thanks!

Using let on the noted for statement causes an error; it’s already declared. Using var causes the same issue I’ve been experiencing; only one moves.

Just found another strange issue. It’s not just that only one reindeer moves, it’s always Vixen, no matter what the arrangement is. This is strange because I don’t think the friends array would be in the same order every single time.

UPDATE. I have discovered one of the issues here.

Same code. I have discovered, by adding a hero.say(penOccupants) to the end of the program, that the code seems to assign a specific reindeer (Vixen) to every unoccupied slot and then ends in moving to the rightmost unoccupied pen as the last pen they are commanded to move to. I’m not sure what is causing this as there doesn’t seem to be anything that should make this error occur.

It is clearly an issue with the following code block,

// Figure out which reindeer are already in their pens.
var reindeer = null;
for (let deerIndex = 0; deerIndex < friends.length; deerIndex++) {
    reindeer = friends[deerIndex];
    
    // For each position check if it matches a reindeer.
    for (let penIndex = 0; penIndex < penPositions.length; penIndex++) {
        var penPos = penPositions[penIndex];
        
        if (penPos.x === reindeer.pos.x && penPos.y === reindeer.pos.y) {
            // Put the reindeer in occupants at penIndex
            penOccupants[penIndex] = reindeer;
            // Remove the reindeer from the friends array.
            friends[deerIndex] = null;
            // break out of the inner loop here:
            break;
        }
    }
}

as it is the only piece of code in the program that alters the friends and penOccupants arrays.

It seems so far there are no solutions and the problem seems to lie in either the default code given to you or some other problem. Using my own code results in similar problems that should not be occurring, so it appears to be that the problem lies not in the code but the actual level or codecombat itself. Something is causing the for loop to only select a specific reindeer, move them to a specific place, and end afterwards, even after removing the breaks meant to prevent reassignment and more looping than is necessary. I will create a new post and mark it as a bug as, even with help, it does not function correctly.

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