Feedback: Danger Valley

This level is really cool, but the guide needs help. It isn’t at all clear how the array of data is set up. Where am I supposed to build the traps? (The red Xs on the ground are a good hint though).

Not sure what type of thing we are trying to teach, if this is an advanced looping thing where players have recently been working on laying out a location based on loop indexes maybe, but probably you need to include a bit of the calculation for getting the location of the trap.

On an aesthetics nature, would be really cool if the bombs that you placed didn’t blow up until everyone was in place, so the referee sets them off at the point when the first ogre hits the trip wire. This could allow for a little more randomness in the location of the peasants with some peasants between ogres.

1 Like

Same questions here: there is a the “grid” (= 5x5 array) and a bunch of red Xs (1+4+3+2)… but what’s the relation between them? Where should I build those fire-traps?

2 Likes

Yes, you have an array of arrays. You have to iterate the grid array which contains several rows, each row is an array that contains 0’s and 1’s for each column.

@nemoyatpeace @ant You have to iterate the “grid” array (an array of rows) storing the row index in the i variable, and for each row you have to iterate its columns storing the column index in the j variable. Then, check if the value of the given column in the given row is 1 and call execute the snippet that was commented out in the starting code: self.buildXY("fire-trap", 36 + 6 * j, 20 + 6 * i)

If you have ideas to improve the level or make this easier to understand, here is the place! :wink:

As for my feedback: i believe this level should require a hammer, which it currently doesn’t.
Also, the visual help (the red X’s on the ground) are a nice touch for users to see how close they are to the solution, but I wonder if those couldn’t be used to cheat the level (i.e. just build traps on the X’s)?

2 Likes

I’m rather confused. I see nowhere instructions to define j, but only “Do a check to see if the tile of row i at j is 1.” How is the program supposed to use j if j is undefined?

The comments in the code mention:

Iterate over all the tiles in this array:

And then the next comments and code use j, so I figured I should iterate the tiles in the row storing the iteration index in a j variable. Also, from the courses I’ve taken, it seems to be common practice to name iteration index variables as i, j, k etc. when iterating “multidimensional”/nested arrays/vectors—although I personally find that a terrible practice; variables should have meaningful names. Maybe it would be clearer if the variables were called rowIndex and tileIndex?

2 Likes

At the time I tried the level, there was no sample code in the python version, only comments. I reloaded the level and now I see the commented line of code.

The basic idea is good (to teach about 2D arrays), but it’s probably not the best visual representation of it.

Anyway, the red Xs are unnecessary: they are a bit “misleading”, and not needed for the solution.

I dont understand how use “for…in grid … do”…
I use
for i=1, #hero.grid do

for j=1, #row do

I’m not sure of the correctness of the decision

I’m not really a Lua programmer, but I believe you are looking for the Generic for documentation.

I’m still having problems with this level. Here’s my code:

for i in range(len(hero.grid)):
    row = hero.grid[i]
    # Now, row is just another array!
    # Iterate over all the tiles in this array:
    for j in hero.grid[i]:
        # Check if the tile at i, j is 0:
        if hero.grid[i][j] == 1:
            hero.buildXY("fire-trap", 36 + 6 * j, 20 + 6 * i)
        
# Finally, retreat back to cover.
hero.moveXY(29, 55)

My hero builds fire-traps on the x’s in the leftmost two columns only. Could I have help, please?

for j in hero.grid[i]:

is the problem here. hero.grid[i] is an array. Just like hero.grid is.

1 Like

I’m not sure I understand. Isn’t the point of the for-statement to iterate through an array? Should I use “row” instead?

So, in python, it’s a bit more complicated.

for element in array:
    # element is a[0], a[1], a[2], ..., a[len(array)-1]
for index in range(len(hero.grid)):
    # index is 0, 1, 2, ..., len(array) - 1

The pythonic way of writing the function would be: (which I didn’t understand while writing the level)

# Iterate over each row
for row in hero.grid:
    # Iterate over each cell in a row
    for cell in row:
        hero.say(cell) # 1 or 0

But the traditional for-loop way with indexii is:

# Iterate over each index of the parent array:
for rowIndex in range(len(hero.grid)):
    row = hero.grid[rowIndex]
    # Iterate over each index of the nested array:
    for cellIndex in range(len(row)):
        cell = row[cellIndex]
        hero.say(cell) # 1 or 0

Edit, now finally, what you are saying is:

for i in range(len(hero.grid)):
    row = hero.grid[i]
    for j in hero.grid[i]:
        # hero.grid[i as index (number)][j as element (a number, but only 0 or 1)]
        if hero.grid[i][j] == 1:
            # do stuff
1 Like

Sorry if I’m being thick, but I’m still getting it wrong. I’m trying

for i in hero.grid:
    for j in i:
        if hero.grid[i][j] == 1:
            hero.buildXY("fire-trap", 36 + 6 * j, 20 + 6 * i)

And I get the message, “TypeError: Cannot read property ‘1’ of undefined.”

I am having trouble with this level. Can you help me? This is my code:

// Ogres have taken some peasants hostage!
// The scouts have given you intel for an ambush.
// this.grid holds an array of arrays.
// Inside the sub-arrays, 0 is a peasant, 1 is an ogre.
// Use this information to setup fire-traps.

// Remember the containing array is just an array!
// Iterate over all the elements of this array.
for(var i = 0; i < hero.grid.length; i++) {
    var row = hero.grid[i];
    // Now, row is just another array!
    // Iterate over all the tiles in this array:
    for(var j=0; j < row.length; j++){
        if (row[[i][j]] == 1) {
            hero.buildXY("fire-trap", 36 + 6 * j, 20 + 6 * i);
        }
    
        // Check if the tile at i, j is 1 to build:
        //hero.buildXY("fire-trap", 36 + 6 * j, 20 + 6 * i);
        hero.say(j);

    }
}
// Finally, retreat back to cover.
hero.moveXY(29, 55);

Sorry, I’m not great in javascript but I think @Chaboi_3000 is.
He’ll help you. (if he’s around, I’m not sure)

That part, is slightly wrong.

You want to make a variable, containing row[j]. And you need to check if the variable is one, using [Variable-name]===1, and then build a fire trap.

Remove that

You don’t need it.

1 Like

Okay, coming back at this level after a few years of doing other things. I’m trying to determine how to distinguish, in Python, between the index of an item in an array and the item itself. It’s not working.

Current code:

for i in hero.grid:
    for j in i:
        if i[j] == 1:
            hero.buildXY("fire-trap", 36 + 6 * j, 20 + 6 * i)

hero.moveXY(29, 55)

Got any ideas? Is this just a level that doesn’t work well in Python? I haven’t seen many other complaints about it. I can see why this doesn’t work, but I can’t see what would. I’ve been fiddling with “while i < whatever”, but that doesn’t seem to help.

So are you saying it is working in java but not in python?

I don’t know JavaScript.