Our game is close to being complete -- or at least complete
enough that it can be fun to play. All that remains is removing full
rows (since filling rows is the object of Tetris) and keeping score.
Writing removeFullRows:
This function will iterate a variable, oldRow, from the bottom to the top
of the board (that is, from rows-1 to 0). It will also start
another variable, newRow, at the bottom of the board. Each oldRow that
is not full is copied to the newRow, which is then decremented by one.
Each oldRow that is full is not copied, and the fullRows counter is
incremented. At the end, the rows on top are cleared (set to
emptyColor) as necessary
Note that there is a very common mistake here: instead
of copying a row element-by-element, you might simply assign the oldRow into the newRow as such:
board[newRow] = board[oldRow] # WRONG!!!
While it is possible to make this approach work (and it can even be
more efficient than the approach described above), it is almost
universally a source of bugs and confusion. You will likely end
up with two or more rows in your board referencing the same list (that
is, they will be "aliases" rather than "copies")! This leads to
very confusing situations, but now you know to expect it and to avoid
it!
Now that we are removing rows, we should keep score.
To do that, we will introduce a canvas data value "score" (which is set to
zero in the init function). In our removeFullRows function, we will
increment the score by the square of total number of full rows
removed in order to reward removing
multiple lines at once. And now that we are keeping score, we should
display the score, which involves adding a function drawScore, which is
called by redrawAll.
David Kosbie |