Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript Object-Oriented JavaScript: Challenge Adding the Game Logic Build the checkForWin() Method

George Roberts
seal-mask
.a{fill-rule:evenodd;}techdegree
George Roberts
Full Stack JavaScript Techdegree Student 8,474 Points

My attempt at a solution for the checkForWin() method

Hi there,

I would really appreciate any feedback on how I approached this - please see my code below. It's not complete but I think maybe repeating the last section for the different directions (with the right adjustments each time) might lead to a functioning solution?

Thanks!

/**
   * Checks if there is a winner on the board after each token drop.
   * @param {array} spaces the 2D array of all spaces @ this.board.spaces
   * @param {Object} activePlayer the active player
   */
  checkForWin(spaces, activePlayer) {

    // flatten 2D array spaces into a 1D array of all spaces:
    const arrayOfAllSpaces = spaces.reduce((accArray, column) => {
      return [...accArray, ...column];
    }, []);

    // filter 1D array of spaces by activePlayer ownership:
    const spacesOwnedByActivePlayer = arrayOfAllSpaces.filter(space => space.owner === activePlayer);

    // use space x and y properties to check for victory streaks in each possible direction:
    // check for vertical down victory:
    const verticalDown = [];
    let incrementor = 1;
    for (space of spacesOwnedByActivePlayer) {
      if (space.y === activeSpace.y + incrementor) {
        verticalDown.push(space);
      }
      incrementor++;
    }
    //check if direction array contains at least 4 in a row:
    if (verticalDown.length >= 4) {
      // call gameover method / winner alert
    }

    // repeat above code (from 'const verticalDown = []' onwards) for the different directions.
  }

3 Answers

Steven Parker
Steven Parker
231,275 Points

It's not clear what "activeSpace" refers to, but it looks like consecutive pairs of owned spaces will all be added to the "verticalDown" array. So basing the determination on length alone may mean several isolated pairs could be misinterpreted as "win".

Otherwise, the basic idea seems viable.

Felix Ding
Felix Ding
5,144 Points

Hey Chris, sure.

So the function can be said to have three sections

  1. first for loop. This loops through the direction sets in the 'dirs' array. It also sets up the counter at the same time.

  2. the second for loop. this loops through the elements in each row of the 'dirs' vector. Note that the counter i is incrementing at 2. Counter i is to be used for increments in x, and counter j is to be used for increment in y.

  3. the while loop. In conjuction with the if statements, this just propagates the program in the direction specfied in the previous step until one of the following conditions are violated:

    • it goes out of bounds
    • the owner of the last token scanned differs from the most recent one

You can also see a nested if condition that checks if the win condition has been met (count === 3), if so we have reached our fourth consecutive token, if not, we simply increment the counter by 1.

Hope that helps.

Felix Ding
Felix Ding
5,144 Points

Here is mine

checkForWin(target) {
        // using the newly placed token as center
        // check if there are four connected
        let dirs = [[1, 0, -1, 0], 
                    [0, 1, 0, -1],
                    [1, 1, -1, -1],
                    [1, -1, -1, 1]];
        // check up down left right and diagonal
        for(let dir of dirs) {
            let i=0;
            let count = 1;
            for(; i<=2; i+=2) {
                let j = i + 1;
                let x = target.x + dir[i];
                let y = target.y + dir[j];
                let test = 0;
                while(x<this.board.columns && x>=0 && y<this.board.rows && y>=0) {
                    if(this.board.spaces[x][y].owner && this.board.spaces[x][y].owner === target.owner) {
                        if(count === 3) {
                            return true;
                        } else {
                            count++;
                        }
                        x += dir[i]; y += dir[j];
                    } else {
                        break;
                    }
                }
            }
        }
        return false;
     }
Christopher Gardner
Christopher Gardner
12,719 Points

Hi Felix! I'm a little newer to programming and am trying to learn all I can! I was wondering if you would be willing to give a bit of a breakdown on what's going on in your code? For example, what's with the 1, -1, 0 etc. in dirs, and in your for loop, why are you checking for 'i' to be less than or equal to two, and then adding 2 to it? Just trying to get where I can think more programmatically like this. Cheers!

Christopher Gardner
Christopher Gardner
12,719 Points

Steven Parker Maybe you could help with this as well? Trying to get a better grasp on what all is happening in Felix's version!

Steven Parker
Steven Parker
231,275 Points

I think we'd better let Felix Ding explain his own code!