Your Questions and My Answers
Give a short name to your project.
Tetris Game
What are the names of the patterns in your
project?
SINGLETON
Using SINGLETON for class Field, which is the baseclass of PlayingField, in order to ensure there is
only one instance of Field, also provide a global point of access to it.
FACTORY METHOD
1)class ShapeFactory is used as a parameterized FACTORY METHOD. By overriding this parameterized
factory method, you can easily and selectively extend or change the shape object that Build() produces.
You can introduce new identifiers for new kinds of Shapes, or you can associate existing identifiers
with different shape objects.
2)class ShapeColorFactory is used as a parameterized FACTORY METHOD. Create() produces different colors
according to the shapeNumber, which is assigned when the object of ShapeColorFactory is instantiated.
You can introduce new identifiers for new color of Shapes, or you can associate existing color with
different shape objects.
TEMPLATE METHOD
Using TEMPLATE METHOD for class MoveController, which is the baseclass of
LeftKeyController, RightKeyController, UpKeyController and DropController. For handling any movement, it has to perform the
following actions:
erase();
action();
draw();
although different event has different action(), the three steps have to be done in the same order,
that's why TEMPLATE METHOD is used here.
STRATEGY
Using STRATEGY for class LowestCell, whose subclasses implement the concrete algorithms of calculating
the position of the LowestCell of different shapes.
VISITOR
Using VISITOR for class FillingCells. There are four subclasses (FillingCellsat12, FillingCellsat9,
FillingCellsat6, FillingCellsat3) calculating the four positions for each shape object whenever the
figure is rotated.
Describe what your project does.
Please check out my Documentation.
Do you send your output to the screen or do you
write it to a disk file?
I implemented this game in a Java Applet and embedded it in Tetris.html. I
zipped all the class files into Tetris.jar, so that when the applet is loaded,
it will retrieve all the needed classes from Tetris.jar.
In other word, to run this game, just open Tetris.html.
Describe how your patterns work together.
Singleton pattern is used to create the PlayingField, when the game
starts. PlayingField will randomly generate different shapes, where ShapeFactory
and ShapeColorFactory are used (Factory Method pattern). To calculate if
the dropping shape has hit the bottom or landed on the top of other landed
shape(s), LowestCell has to be computed (Strategy pattern). When any
keyboard event happens, the listener will call the MoveController (Template
Method pattern) to decide the corresponding action. When the player rotates
the shape, different position (12 clock, 3 clock, 6 clock or 9 clock) will be
calculated by FillingCells (Visitor pattern).
Does your project operates as you anticipated?
Describe any differences.
I had several problems in achieving the original design, but most of them were
fixed in the process, little by little.
The only difference between the current version and my anticipated one, is
that I was trying to add three more functions --- to let player choose the
WIDTH, HEIGHT and BACKGROUND COLOR of the playingfield. The GUI interface
is easy to create, but the problem is, if I use the SINGLETON pattern for the
playingfield, it's instance can only be GOT, not created, after the
initialization when the game is loaded. If I have to destroy it and create a new
instance, I think the Singleton pattern doesn't make much sense here.
Did you have any difficulty with the programming
language, or with a pattern, or with something else?
I had to spend some time looking up the GUI interface, especially those controllers and their listeners. For example, the last problem I fixed was the KeyListener. I couldn't figure out why I had to click inside the playingfield to make the keylistener work. I tried many different ways, but none of them worked. Finally I realized that, if the current FOCUS is not on the canvas (where playingfield is), then the KeyListener (of the canvas) wouldn't work. So I added this keylistener to the whole panel, but it still didn't work. The reason is, after the user click the START button, the current focus will be always landing on the three buttons (or the canvas), so I finally fixed this problem by adding the canvas keylisterner to both START and PAUSE buttons (since after clicking the STOP button, user won't be able to play the game, no keylisterner is need.)
Surprisingly, there weren't many problems with implementing patterns. But I currently put all the classes in the same directory, if I package them up into different directories, I would have to spend some time in dealing with the accessing of different classes, although that would be more desirable for a Design Pattern class.