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 trialMichael Cook
Full Stack JavaScript Techdegree Graduate 28,975 PointsMy playToken() Solution
Ashley's solution to this problem is a bit less than efficient in my opinion. To find the target space, you have to look for the lowest space that does not have a token
value of null
. Ashley's solution iterates over the column starting from the beginning and checks each Space
object to see if it is empty, and if it is, assigns it as the target. Obviously by the time the loop finishes iterating over the whole column, there will be a target space that represents the lowest position in the column.
But I think it's a lot more efficient to use a for
loop to start iterating over the column starting from the last index value and move backwards, and as soon as an empty space is found, break
out of the loop. Why iterate over every single space in the column when you only need the lowest one?
Here is my solution:
/**
* Determine if current column location of active player's active token is full
* If not full, determines target space and calls active token's drop() method
*/
playToken()
{
const activeToken = this.activePlayer.activeToken;
const tokenColumnLocation = activeToken.columnLocation;
const column = this.board.spaces[tokenColumnLocation];
if (column[0].token !== null) {
return;
} else {
for (let i = 5; i >= 0; i--) {
if (column[i].token === null) {
this.ready = false;
activeToken.drop(column[i]);
break;
}
}
}
}
First the method determines if the topmost position is occupied, and if it is return
s out of the function. If the topmost position is not occupied, the method loops backwards through the column and passes the first unoccupied Space
object to the drop
method then breaks control flow. I just wanted to share this for anyone else out there interested in considering different ways of doing things. IMO many of Ashley's solutions are meant to be clear and simple to understand, but not necessarily efficient or the way a professional developer would write the solution.
3 Answers
Lewis Marshall
22,673 PointsHeres my playToken() solution
/**
* Find Space object to drop Token into, drops Token
*/
playToken() {
const spaces = this.board.spaces;
const activeToken = this.activePlayer.activeToken;
const targetColumn = spaces[activeToken.columnLocation];
const freeSpaces = targetColumn.filter(space => !space.token);
if (freeSpaces.length) {
game.ready = false;
const targetSpace = freeSpaces[freeSpaces.length - 1];
this.activePlayer.activeToken.drop(targetSpace);
}
}
I filter the targetColumn array to get all the spaces that don't have a token. Then check if there are any spaces available by checking the length of the freeSpaces array. If there is then get the last space in the array as this will have the highest y property value.
Zimri Leijen
11,835 PointsI had this in mind as a possible solution too
Kacper Kucinski
14,011 PointsI took the same approach. It seems more straightforward (well, to me!) than Ashley's solution.
Zimri Leijen
11,835 PointsHere is my solution (I made this before watching the video, even if they are very similar).
Note the else bracket and the break. I have done this because if it finds a non-empty space, obviously all the next spaces will be non-empty too. There's no point in continuing the loop after finding the first filled space.
playToken() {
const column = this.board.spaces[this.activePlayer.activeToken.columnLocation];
let target = null;
for (let space of column) {
if (space.token === null){
target = space
} else {
break;
}
}
if ( target ){
this.ready = false;
this.activePlayer.activeToken.drop(target, this.reset);
}
}
Dzmitry Aliakseichyk
12,290 PointsAs short as I could possibly make it haha. Works as intended by looping from the back of the arrays, finds a spot, drops the token and breaks the loop. I cut out the line that assigns token's .id
to the space it's being placed into for now.
playToken() {
let spaces = this.board.spaces;
let activeToken = this.activePlayer.activeToken;
for (let r = this.board.rows - 1, c = activeToken.columnLocation; r >= 0; r--) {
if (spaces[c][r].token === null) {
this.ready = false;
activeToken.drop(spaces[c][r]);
break;
}
}
}
anmo20
6,470 Pointsanmo20
6,470 PointsI did mine a lot differently. It doesn't look quite as efficient as some other people's code, but seems to work just fine. I decided I didn't care to test if the entire column was full from the beginning or not because I didn't think it mattered if I ran the loop to check whether the space was occupied or not from the bottom since there will never be an empty space in between 2 occupied spaces.