Thu Oct 13, Mon Oct 17, Tue Oct 18
Due date:
ALL SECTIONS: Tue Oct 25 before 23:59
The purpose of this lab is to partially implement the game Tetris. In this lab you will:
The game Tetris is a puzzle game where the player can move and spin falling blocks of various shapes. The goal of the game is to stack the blocks without leaving any gaps between the blocks.
If you have never played Tetris before, there is a wiki with lots of information about the game.
There are 7 standard blocks (called Tetriminoes). The blocks are all
defined on a square grid of size 3-by-3 or 4-by-4. In this lab,
you are given a class BlockGrid
that helps you describe
the shape of a block. BlockGrid
lets you get, set, and
clear the individual grid positions. You specify the grid position
using a pair of zero-based integer indices (the row index and the
column index). The figure below shows the indices for each
grid location on a 3-by-3 BlockGrid
:
The shape of each block can be represented using a BlockGrid
object. The figure below shows the BlockGrid
for the
S-block; the white grid locations have the value false
and the green grid locations have the value true
.
The player is able to spin a block into any of 4 possible orientations. The figures below show the 4 possible orientations for the I-block, J-block, and S-block. Column A show the blocks in their starting orientation. Column B shows the blocks after they have been spun once to the right. Column C shows the blocks after they have been spun again to the right. Column D shows the blocks after they have been spun again to the right. Spinning the blocks once more returns the blocks to Column A. If the player spins the blocks to the left starting from Column A, then the orientations are given by Column D, then Column C, then Column B, returning to Column A.
The Tetris playing field is typically a grid with 20 rows and 10 columns.
The location of a block on the field is given by the coordinates of the
top-left corner of its grid. The image below shows a J-block with position
(6, 14)
on the playing field.
For this lab you will implement three blocks: IBlock
,
JBlock
, and SBlock
. All Tetris blocks have
three essential features: (1) they can be drawn on the playing field;
(2) they can be moved; (3) they can be spun. There are elements of the
game that can be drawn, but not moved or spun (such as the border
of the playing field). Some versions of Tetris have drawable elements
that can be moved but not spun (such as the climber in the Field Climber
mode of Wii Tetris Party Deluxe). To implement these features, you will
create three interfaces: Drawable
,
Movable
, and Spinnable
. Finally, there is
information needed for every type of block such as the location of
the block on the playing field, the color of the block, and the
shape of the block; this information can be managed by an abstract
base class Block
that all blocks will extend. The relationships
between the interfaces and classes are shown in the following UML
diagram:
The APIs for all of the classes and interfaces associated with this lab can be found here:
Pay attention to the package names! All of your classes must be
in the package eecs2030.lab4
You are provided with a partial implementation of Block
,
a Jar file containig the complete implementations of BlockGrid
,
Point2
, and StdDraw
, and a test program:
The test program drops random blocks from the top of the playing field. You can move and spin the blocks (but not fast drop or stack the blocks) using the keyboard. The controls for the tester are as follows:
You can see what the tester should do by running the following program in the EECS Prism lab:
java -jar /cse/dept/www/course/2030/labs/lab4/TetrisTest.jar
Block
implementation first. The various
move
methods should adjust the position of the block.
The move
methods do not need to ensure that the block
stays inside the playing field.
Don't touch the abstract methods; the child classes
IBlock
, JBlock
, and SBlock
are responsible for implementing the abstract methods.
IBlock
class second. Note that this is
the first time that we have asked you to decide what fields (attributes)
the class needs. Remember that IBlock
inherits all of the
protected
fields from Block
so you should not
include similar fields in IBlock
. The fields that
IBlock
requires are a field that can store the shape of
an IBlock
and a field that stores which orientation the
block is currently in. If you read the lab carefully, you will find
that we have given you a class for representing the shape of any block.
spinLeft
and spinRight
methods change
the shape of the block. When a block is spun its orientation changes.
JBlock
and SBlock
classes.
They are very similar to IBlock
.
Please wait until Mon Oct 17 to submit so that I can install some unit tests to check your work.
Submit your program when you are finished:
submit 2030 lab4 Block.java IBlock.java JBlock.java SBlock.java
or if you are working in a group:
submit 2030 lab4 Block.java IBlock.java JBlock.java SBlock.java group.txt
Instructions for submitting from outside the lab can be found here.