For the past two years, our AP Computer Science A (APCSA) students have completed the Tetris Lab at the end of the Object Oriented Design (OOD) unit. The initial idea and structure for the lab was forked from Stanford Tetris Project from Stanford’s CS108 by Nick Parlante, which I found as it was a SIGCSE 2001 Nifty assignment. We made significant changes during the first implementation of the lab and before the second. The current version of the Tetris Lab is a great fit for the goals that we have for our students at the point in the semester when they complete it. Your students may need something different or at a different time. Regardless, I hope you find something to adapt to your class.
To provide some context, for our APCSA classes, the OOD unit is the second to last unit before the AP exam. The last unit focuses on recursion along with sorting and searching algorithms. Our OOD unit still includes interfaces even though that is no longer part of the AP curriculum. Students also implement basic Swing-based graphical user interfaces. At the end of this unit, we want students to demonstrate their understanding of the OOD concepts as well as practice the design and implementation of more advanced algorithms in preparation for the AP exam. We have designed all of our summative programming labs to be scored based on the defined requirements but also to have various extensions that students can pursue based on their interest and time available. We also provide opportunities for students to personalize their summative programming labs. Honestly, that is a weakness of the Tetris Lab as personalization is primarily presented through extensions and not requirements and, therefore, not incorporated by all students.
The lab is split into two parts. The first part focuses on the model for a Tetris piece and students work with their pair-programming partner to complete this part. This part emphasizes the design and implementation of various algorithms related to Tetris pieces. We found that students working in pairs help each other especially with the design of these algorithms. The Piece class with declared methods and instance variables is provided in the starter code. Pairs implement the following methods:
- Piece constructor in which they have to design and implement an algorithm to:
- copy an Array of references to Point objects and copy the Point objects (they really struggle with this and it is a great opportunity to review one of the most challenging concepts in the course, Java references);
- determine the width and height of the piece
- determine the skirt of the piece (this is the most challenging algorithm in the constructor and pseudocode is provided so that student can focus on implementing the algorithm)
- toString (used when debugging)
- the rotation algorithm in the pieceRow method; the starter code defines three steps to rotate a piece to decompose this algorithm and make it more accessible for students to implement:
- step 1: reflect across the line y = x
- step 2: reflect across y axis
- step 3: translate right
In other summative programming labs, students write their own unit tests. In this lab, the test code is provided and students run the tests to verify that their have completed each milestone. The first part of this lab consists of two milestones:
- Milestone 1: JPieceTest Initial Pieces
- Milestone 2: JPieceTest with Rotations
Students run the JPieceTest class and visual verify that the output matches the expected output in the lab document.
After completing these two milestones, which comprise the first part of the lab, the TetrisViewer class can be executed to play the game of Tetris. The Board, JTetris, and TetrisViewer classes are fully implemented in the starter code. (This is the most significant departure from the original lab as students do not implement the Board class. The first year we did this lab, I expected students to implement the algorithms in the Board class and, after witnessing how they were challenged with the algorithms in the Piece class, changed course and provided them with a fully-implemented Board class.)
The second part of the lab focuses on enhancing the game of Tetris such that the code can play the game autonomously. In this part students demonstrate their understanding of defining a subclass, overriding methods, and interfaces.
Milestone 3 focuses on the extension of the GUI defined in the JTetris class by the JBrainTetris class which adds a combobox used to select which “brain” is active and a button to enable/disable the brain. Students implement the JBrainTetris class from scratch to demonstrate their understanding of creating a subclass and overriding methods. While students have used the JButton class previously, they have learn how to incorporate the JComboBox class into the code. In addition to the components and their associated listeners, students also implement the createBrains method in the BrainFactory class. This is straightforward but a good opportunity for students to see the factory pattern and appreciate the strengths of polymorphism.
Milestone 4 focuses on overriding the JTetris methods pickNextPiece and tick to support the “brains” playing Tetris. These are challenging methods to override and students needs to understand the provided JTetris code in order to do so successfully. Understanding and then leveraging provided code is an authentic feature of many of our summative programming labs.
Milestone 5 is an additional test that shouldn’t require any additional implementation. However, students often have undetected bugs that need to be addressed.
Completing the 5 milestones meets the requirements for the lab. There are, however, several opportunities to “add more awesome” through extensions:
- new pieces (define additional pieces with more or less than four blocks; this is a great opportunity to appreciate the benefit of abstraction as only the Piece class has to be modified)
- adversary (add a feature where the code uses a brain to select the most challenging next piece; this is a great example of how decomposition can lead to code reuse)
- BigBrain (implement a new brain that is smarter than the provided SimpleBrain class; students can take this extension as far as they want and spend significant time tuning their algorithm either by hand or with the assistance of a genetic algorithm)
The latest starter code is available on GitHub.