Minwsweeper task 3

pro

#1

Howdy guys,

Has anyone got through this minesweeper JS task…I’m about to throw my laptop through the window…

https://www.codecademy.com/courses/minesweeper/projects/dynamic-board-generation?program_content_id=0dc66fcb1f02d7352f82fdfb1295fa87&program_id=fc1cc76cbdee0831fda0677e3fd75ae6

Im just up to step 3 and im getting undefined in my terminal. I cant see what Im doing wrong but then im pretty new to this. If anyone has any wisdom to share it would be muy apreciado! My code below…

const generatePlayerBoard= (numberOfRows, numberOfColumns) => {
  let board= [] ;
  for (let numberOfRowsIndex = 0; numberOfRowsIndex < numberOfRows.length; numberOfRowsIndex++){
    let row= [' ']; { 
    for (let numberOfColumnsIndex = 0; numberOfColumnsIndex < numberOfColumns.length; numberOfColumnsIndex++)`Preformatted text`{
    return  row.push(' ');
  } return  board.push(row);
  }  return board;
 }
};

console.log(generatePlayerBoard(2, 2));


#2

Hi @jamesmacleod1990,

Since I have no access to the pro courses, I would take a wild guess based on your code. Please note that I have no access to all the instructions, my suggestion could be very different from what the lesson asked.


Does the instruction asked to create a A x B columns & rows table for the Board based on the input for numberOfRows and numberOfColumns?

Such as printing the board: ( 2 rows, 2 columns)
[ [ ' ', ' ' ], [ ' ', ' ' ] ]

If yes, I might be able to help point out which part of your code leads to not printing the 2x2.


Firstly, I think this part is correct :white_check_mark:

const generatePlayerBoard= (numberOfRows, numberOfColumns) => {
  let board= [] ;

Currently the board is an empty array.
Next…


for (let numberOfRowsIndex = 0; numberOfRowsIndex < numberOfRows.length; numberOfRowsIndex++){

I think you’d need to check this part: numberOfRows.length

Based on end of your code, you have passed 2 as the argument,

generatePlayerBoard(2, 2)

replacing numberOfRows in

generatePlayerBoard= (numberOfRows, numberOfColumns) => {

So, it would mean numberOfRows.length, becomes ===> 2.length (It doesn’t make sense)
I think it should be just:

numberOfRowsIndex < numberOfRows

without the .length
so when you passed the argument 2, it would be numberOfRowsIndex < 2 in the for loop. Much reasonable that way.

Next…


let row= [' ']; { 

I think the row should be empty array as well, could it be like the board variable?
Just let row = [ ] ?

If you write [' '], it does not mean empty, it means a value of a "space", just like a space between words in a sentence. Yes, space must be accounted for in string type.

Example:
let row = [2 ] the space does not matter because the value is number type.
let row = ['2 '] the space is counted because the value is string type. (enclosed with quotation marks)

And I think the { opening curly bracket doesn’t do much? I think it’s fine to delete it.

Next…


for (let numberOfColumnsIndex = 0; numberOfColumnsIndex < numberOfColumns.length; numberOfColumnsIndex++)`Preformatted text`{

This part: numberOfColumns.length, same explanation as the above, I think it should be just numberOfColumns

And I think you accidentally added Preformatted text into the code while posting this topic, it shouldn’t appear in your source code. :wink:

The syntax is correct, please don’t delete any of it.

Next…


return  row.push(' ');

When you use return, it exits the function, I’ve learnt it the hard way, wondering why the rest of my code doesn’t execute after return

In your code above, when you use return, it exits the function and the rest of your code is not executed.

just delete return and write:

row.push(' ');

(' ') is correct this time :white_check_mark:
because you’d want to push an empty space into the row array.

Next…


} return  board.push(row);

This part too: delete just the return, because you still have some code to run after this.

Don’t delete the closing curly bracket }, it’s correct. :slight_smile:

Next…


  }  return board;
}

This part I think is correct :white_check_mark:, because it’s the final code of the function, you’d want the function to return the value of the board and also at the same time, it exits the function.

Just delete the closing } curly bracket after board;, because I have suggested to delete an opening { curly bracket above at:

let row= [' ']; {  //<=== this one

Finally:

};

console.log(generatePlayerBoard(2, 2));

This part is correct nothing to change. Please retain one }; closing curly bracket to close the function. Basically don’t change any of the above. :white_check_mark:


After changing all the codes I mentioned, you can try run the code and see if it returns

[ [ ' ', ' ' ], [ ' ', ' ' ] ]

Note: As I mentioned before, I have no access to the link you provided because it’s for Pro membership. However, you can have a look on my suggestions and see if it is what the lesson intended.

PS: Should you have a Pro membership, I think you should be able to gain access to CodeCademy Advisors. Maybe they can help you better, since they will have direct access to those exercises.

Quoted from the Pro page:

Live Help From Advisors
Our advisors are experienced coders who are ready to help you at a moment’s notice. Contact them via live chat and they’ll review your code, debug your issues, and help you get unstuck!


Just wanted to help. Hope it does.

Thanks for posting your code in such nice and correct format. It really helps! Cheers :slight_smile:


#4

Hey @codexthon,

This is extremely helpful. Thanks for your help.

I amended the code as such;

const generatePlayerBoard= (numberOfRows, numberOfColumns) => {
  let board= [] ;
  for (let numberOfRowsIndex = 0; numberOfRowsIndex < numberOfRows; numberOfRowsIndex++){
    let row= [];
    for (let numberOfColumnsIndex = 0; numberOfColumnsIndex < numberOfColumns; numberOfColumnsIndex++){
    row.push('  ');
  } board.push(row);
} return board;
 };

console.log(generatePlayerBoard(2, 2);

Does that look right to you? I got an output of just one row with 2 columns;

[ [ ' ', ' ' ] ]

But I played around a bit and now my transcribing function is not working…but that a separate issue I think.

Sorry I didnt provide more info in the first place but the purpose of this task is described as:

Before we continue, let’s walk through how this function should behave.

generatePlayerBoard(), when called, will accept two arguments: the number of rows and number of columns.

The function should:

Add an empty space (’ ') to each column in every row
Add each row to to a larger game board, thereby constructing the player’s board

Thanks again for the help.

J


#5

I haven’t looked at the project yet but it already looks like a nightmare, from where I stand. I find that the logic just gets buried in all the long variable names, and don’t see what purpose they serve. But if the grader insists, what can we do?

This is an ES6 project, so I don’t understand why the author didn’t take it more down that road, than just brush over ES5 with a smidgeon of ES6.

Here is all we really need to make a y X x board:

const generatePlayerBoard = (rows, cols) => Array(rows).fill(Array(cols).fill('  '));

To test it,

board = generatePlayerBoard(10, 10);

console.log(board);
// ->
 Native Browser JavaScript
 >  
[ [ '  ', '  ', '  ', '  ', '  ', '  ', '  ', '  ', '  ', '  ' ],
  [ '  ', '  ', '  ', '  ', '  ', '  ', '  ', '  ', '  ', '  ' ],
  [ '  ', '  ', '  ', '  ', '  ', '  ', '  ', '  ', '  ', '  ' ],
  [ '  ', '  ', '  ', '  ', '  ', '  ', '  ', '  ', '  ', '  ' ],
  [ '  ', '  ', '  ', '  ', '  ', '  ', '  ', '  ', '  ', '  ' ],
  [ '  ', '  ', '  ', '  ', '  ', '  ', '  ', '  ', '  ', '  ' ],
  [ '  ', '  ', '  ', '  ', '  ', '  ', '  ', '  ', '  ', '  ' ],
  [ '  ', '  ', '  ', '  ', '  ', '  ', '  ', '  ', '  ', '  ' ],
  [ '  ', '  ', '  ', '  ', '  ', '  ', '  ', '  ', '  ', '  ' ],
  [ '  ', '  ', '  ', '  ', '  ', '  ', '  ', '  ', '  ', '  ' ] ]
=> undefined   

#6

hey @mtf,

Yeah I thought that this would have sufficed also. But I think that it has something to do with the board needing to be ‘dynamic’…I assume there is a reason for this later down the task.

J


#7

Any function that can act upon a random set of parameters is dynamic. The exercise is clearly more focused on rudiments and the author wants us to be sure of the nuts and bolts of declarative programming.

Perhaps the instruction text is not explicit and exhaustive as may be needed. I cannot say because I’m biased already and understand the instructions too well to hit any walls. I have to reverse engineer newbie problems to try and see it from their perspective.

If I get into the project it will be with that bias and it borders on contempt should I criticize the author in public so I send my comments down the bug line. I probably should have kept my trap shut on this one, but something wouldn’t let it go, so we get my unhelpful post caught up in your topic. Hope you are okay with this.

We will, of course get you through this, and maybe both learn something from it. In the meantime, let’s cheat a wee bit and simplify your posted code so the logic shows through a little better…

const generatePlayerBoard = (rows, cols) => {
  let board = [];
  for (let row = 0; row < rows; row++) {
    board[row] = [];
    for (let col = 0; col < cols; col++) {
      board[row].push('  ');
    } 
  } 
  return board;
};

const board = generatePlayerBoard(2, 2)
console.log(board);

The code might not pass the SCT, but if it works, then you can substitute the long names back in. I’m not trying to lead you off the lesson path as much as give you a method of approaching a buggy chunk of code… Strip it down to its working parts in as simple yet semantic a fashion as possible and look for logic concerns.

When the expected pattern is a particular structure, then we must focus first on getting that structure in place. Same holds for expected variable names. Like them of not, it is always best to stick to the plan as it is spelled out. With the above approach you now have a way to comply, and debug. At the end of the module we can go to town on refactoring the working program.


BTW

There is where your error was. Missing ).


#8

@mtf,

Thanks man. It’s that easy to see that I’m new to this! It’s awesome to see how the community is so supportive!

Ok cool, this makes sense and return me the output;

[ [ '  ', '  ' ], [ '  ', '  ' ] ]

I just need to get the two row on separate lines now…Any trick to this?


#9

Again, I’m outside of the project so only projecting on to it what I would do, given my own bias. See if you can take anything from this less than dynamic function…

// Chess board

const create_board = (s = 64) => {
  let temp = [];
  let a, t, u;
  while (s > 0) {
    t = 0;
    u = 8 - s / 8;
    temp[u] = [];
    while (t < 8) {
      temp[u].push(u % 2 ? (a ? " " : "#") : (a ? "#" : " "));
      a = ! a;
      t++;
    }
    s-= 8;
  }
  return temp;
};

const print_board = board => {
  for (let row = 0; row < board.length; row++) {
    console.log(board[row].join(''));
  }
};

const board = create_board();
print_board(board);

https://repl.it/KeQp

Focus on the print_board part, and ignore the rest. We can come back to that in due course when you have triumphed over this track. There is a lot packed into the create_board function, but for now I’ll leave you to decipher it in your own time. Be sure to bookmark this topic so you can find it again.


#10

@jamesmacleod1990, You’re welcome. :slight_smile:

You should get an output of this:

[ [ ' ', ' ' ], [ ' ', ' ' ] ]

Yeah, @mtf had pointed out that missing part.

No worries. I just wanted to help but having no access to the project, leading me to taking wild guesses.

Agree on the long variable name part. I have slightly changed the variable names when testing the code to ease my eyes. :wink:

const generatePlayerBoard= (numberOfRows, numberOfColumns) => {
  let board= [] ;
  for (let i = 0; i < numberOfRows; i++){
    let row= [];  
    for (let j = 0; j < numberOfColumns; j++){
        row.push(' ');
    } 
    board.push(row);
  }
  return board;
};

console.log(generatePlayerBoard(2, 2));

I don’t know about this. If you increase your number of rows and columns, you will get the desired results, such as:

console.log(generatePlayerBoard(4, 4));

It will generate for me:

[ [ ' ', ' ', ' ', ' ' ],
  [ ' ', ' ', ' ', ' ' ],
  [ ' ', ' ', ' ', ' ' ],
  [ ' ', ' ', ' ', ' ' ] ]

Which is visually 4 x 4.

I think you meant to generate a 2 x 2 like this?

[ [ ' ', ' ' ],
  [ ' ', ' ' ] ]

I have so far yet to find a way to visually generate it that way. Maybe @mtf might be able to help. :thinking:


Discussion:

I find it fascinating what @mtf proposed of writing the code this way:

const generatePlayerBoard = (rows, cols) => Array(rows).fill(Array(cols).fill('  '));

board = generatePlayerBoard(10, 10);
console.log(board);

Or

this way:

const generatePlayerBoard = (rows, cols) => {
  let board = [];
  for (let row = 0; row < rows; row++) {
    board[row] = [];
    for (let col = 0; col < cols; col++) {
      board[row].push('  ');
    } 
  } 
  return board;
};

const board = generatePlayerBoard(2, 2)
console.log(board);

Notice this one is taking a slight different approach by using the .push method once.

And…

I also think the code could be written this way:

const generatePlayerBoard = (numberOfRows, numberOfColumns) => {
  let board = [];
  for (let i = 0; i < numberOfRows; i++) {
    board[i] = [];
    for (let j = 0; j < numberOfColumns; j++) {
      board[i][j] = ' ';
    } 
  } 
  return board;
};

console.log(generatePlayerBoard(2, 2));

Without using .push method.


With my current limited knowledge, I still don’t know what are the benefits of using one versus the other when come to the choices of .fill, .push, using pure loops or any other options.

My guess is that It might have to do with the code’s efficiency and the speed it runs.

Well. More readings should be done on the documentations. :neutral_face:



#11

This is a finite process that takes no time at all regardless which method is used. Any of the above approaches would suffice since they are readable, logically sound and they all work to the same successful completion.

For something such as this use case, I’m more inclined to use the first example, Array.fill() simply because it uses very little code and it is still discernable to the reader what the expected outcome is. That to my mind is the way to go. Less code means less mistakes and easier maintenance.

Still, it boils down to author preference and typical code patterns that they have a habit of writing fluently. Breaking out of an old shell can be torturous because we invariably fall back into our old ways. Write what fits one’s current way of thinking and go over the finer details when and if you ever find a need to refactor the code.


#12

Often, I just saw logical working codes but very rarely get to know the reasons behind why it is being written that way.

I do agree less code means less mistakes. That said, I probably feel more confident with the loop way since I’m still lacking in differentiating all those methods available in JS.

Thanks for taking time to explain the code choices, appreciated. @mtf :slight_smile: