CSE 115 - Spring 2007 - Banner
   CSE 115 - Spring 2007 - Introduction to Computer Science for Majors I
CSE 115 - Spring 2007 - Left Navigation CSE 115 - Spring 2007 - Lab 8

Lab 9

Notice

This lab is a modified version of a lab originally developed at Brown University.

Introduction

Congratulations! If you're reading this, it means you've decided to stick it out to the very end. You've survived it all and you've made it to the "other side"! Now, for the ultimate challenge this semester. Well, my little programmers embrace your final challenge read on...


New Concepts Covered

The following are the new concepts covered in this lab.

  • Collections of objects
  • primitive types (boolean, int)
  • control structures
    • if statement
    • for,while, and for-each loop
  • Design Patterns
    • Proxy pattern
    • State pattern
    • Iterator pattern

Assignment Specification

If you are working from home, make sure to follow any special directions posted here.

Your assignment is to write the CSE115 version of the incredibly addictive game of Tetris, without getting addicted to it yourself. There are many renegade versions of Tetris out there, with slight differences among them; to give you a better idea of what your assignment entails, read the following description of how the CSE115 version of Tetris behaves.

When the game starts, only an empty board with borders drawn around its edges should be displayed. A Tetris piece, chosen randomly from the seven possible Tetris pieces, shown below, should appear at the top of the board. This piece should fall by moving down the board, one square at a time. A piece cannot fall into a square already occupied by a previously fallen piece. When a piece can fall no further, it should stop moving; a new random piece should then appear at the top of the board and begin to fall. As pieces fall, rows (or horizontal lines) of occupied squares spanning the board's width may form. When such a line is formed, it disappears and all the squares above it fall down one line to fill the newly empty squares. This process continues until a new piece appears and has no room to fall because it is already resting on a previously fallen piece. The game is then over, and everything on the board should stop completely. A message should be displayed to let the user know that the game is over.
 

While a piece is falling, the player may rotate or shift it by pressing certain keys on the key board. Pressing the left arrow should shift the piece one square to the left. Pressing the right arrow should shift the piece one square to the right. Pressing up arrow should rotate the piece counter-clockwise by ninety degrees. At regular intervals, the piece should simply fall vertically one square at a time. The player should be able to drop the piece quickly by pressing the down arrow. By dropping a piece, the player forfeits his/her chance to manipulate the piece any further and the piece simply falls as far as it can. The player should be able to pause the game at any time by pressing `p'. When the game is paused, the player should not be able to manipulate the piece in any way. Pressing `p' again should allow the user to resume play.

As a piece moves, it would not make sense for it to be able to move through previously fallen pieces or beyond the edges of the board. In order to prevent these illegal moves, when a piece wants to move to a new location, it should check that the new location is not already occupied by a previously fallen piece and that it is not beyond the edges of the board. These checks should be made whenever a piece wants to shift left, shift right, fall, or rotate.

Note: You may not use arrays. You will use one of the java.util.Collections and details will be discussed about which ones would be most appropriate in lecture and in lab. Using arrays will result in no credit for the lab.


Helpful Hints

There are several new concepts used in this assignment. Before you even start thinking about Tetris, you should make sure that you completely understand all of the concepts listed in the "Concepts Covered" section. As with the previous assignments, but most importantly with Tetris, if you thoroughly understand these concepts before you start, this program will be easier to design and to code.

The next thing you should do is play a game of Tetris. If you are not familiar with Tetris, you should play a number of games. Remember that our version does not have to be as sophisticated as many that you will encounter out on the Internet, but after playing around with the game, you can get a better idea of how our version should behave. Once you are familiar with how the Tetris works and what the requirements for our game are, you should start thinking about your design. You will want to think about:

  • how to randomly create different types of pieces
  • how to generate new pieces modularly (easy extensibility to add new types of pieces)
  • how each new piece will appear at the top of the board
  • how each piece will keep track of its current location
  • how each piece will fall
  • how each piece will shift to the left or to the right
  • how each piece will rotate
  • how to handle user input
  • how each piece will check if its desired move is legal - i.e., not into an already occupied square and within the edges of the board
  • how the board will keep track of where the pieces have fallen
  • how the board will check for horizontal lines
  • how to update the board after a horizontal line disappears
  • how to stop the piece when the game is paused
  • how to check for the end of the game

Also, you will want to give special consideration to how the different pieces will rotate in a polymorphic way. We will discuss rotation in more detail below.

Handling User Input

For this assignment, you will need to have a key interactor that can respond to each one of the player's valid inputs: shifting left, shifting right, rotating, and dropping a piece, and pausing the game. This brings up a critical design issue. Since each of the four "different" key interactors operate on the current piece, they will need to send messages to it and they will all need a way in which to communicate with the current piece.

A good design choice to simplify this is to have the interactor have a reference to the same object for the duration of the program; let's call this class the piece proxy. This object would then contain the (one) reference to the current piece that constantly needs to be updated. This way, when a new piece is created, you will only have to update one reference (the proxy's reference), as opposed to many references (the proxy, key interactors, perhaps the board, etc). The key interactor can then communicate with the proxy, which will in turn communicate with the actual current piece.

Creating Random Pieces

What is a random number? Forty-two is a random number, as is 8900, and 8675309, and . . . These are all random numbers because they were chosen at random. You might be asking yourself, why will I need random numbers for this assignment? In computer science, we can use random numbers to produce some sort of random behavior. In this assignment, you will want to use random numbers to decide which one of the seven possible Tetris pieces will start to fall next. The utilities.Random class has a method randomInteger(Integer low, Integer high) which returns a random integer (whole number) between low and high.

Dropping and Rotating Pieces

The key to dropping a piece is to make sure that the squares that the piece wants to fall through are not already occupied by a previously fallen piece. In other words, if you are keeping track of already occupied squares within a board, then as the current piece falls, you simply have to check with the board to see if the squares where it wants to move are already occupied.

This same sort of checking should be used for rotations. You should check with the board to make sure that locations where the piece wants to be after it rotates are free. If they are free, then the piece can rotate; if any one of these squares is not free, then the piece cannot rotate. In order to relieve some of the mathematical grunt work involved in figuring out rotations, we are giving you a nifty formula that performs rotation operations. See Appendix A for this nifty formula and its explanation.

The Board

Before discussing some of the design issues in coding the Tetris board, let's review what it needs to accomplish. Once a piece has fallen, the squares from that piece should remain on the screen in their original color, should block other pieces' motion, and should be able to be removed from the board in rows. This may mean removing only part of what used to be a single Tetris piece. Once a row has been removed, all the rows above it should move down.

First, how can we keep all the squares around after pieces have fallen? How can we arrange an arbitrary number of squares as pieces fall and organize them such that the functionality listed above is easy to implement?

Also, the design of the board needs to prevent pieces from moving or rotating off the edge of the board. You could do this by dealing with checking the boundaries of your board's HashMap, but it might be easier to come up with a design that allows edge-checking to function exactly like checking for occupied squares within the board.   

Graphics and the Grid

Recall that each square of each shape actually occupies a position (row, column) on the board. It will be easier to think of your board as a grid of row, column positions each potentially containing a square from a Tetris piece. You can convert a row, column position into an actual pixel location fairly easily and the TAs will discuss this further in recitaiton.

Programming and Design Tips

For this assignment, spend a while really thinking about the design the entire program carefully before you write even one line of Java code. Part of your design process should include a lot of hand simulation; that is, stepping through your design to make sure that it deals with every last detail. Remember to look for classes that share responsibilities, capabilities, or interfaces and make an interface or superclass for them. Look for the main puzzles in the program and Design Patterns that might solve them. Try to avoid unnecessary if and switch statements by exploiting polymorphism and abstract methods. Once you are satisfied with your design, you are encouraged to run it by a TA during office hours.

Then begin coding small chunks at a time. First, get one piece to simply fall down the board (hint: the line piece is probably the best piece to start with). Then, get it to shift left and right, and finally, make it rotate and drop. Next, implement the detection and removal of lines and the updating of the board. Once you have all of this working for one piece, it should be fairly simple to get the other pieces to exhibit the same behaviors. Finally, implement pause and the end of the game scenario.

Remember: small victories are the keys to success.


Lab tasks

At your lab session your teaching assistant will briefly discuss how to carry out each of the tasks below. She or he will also be available to answer questions you might have. You must carry out each of the following tasks.

Create your project for Lab 9

Refer back to Lab 8 if you do not remember how to create a project for your submission. Name the project Lab9 and the package inside it tetris. If you are planning to do the extra credit, you should create another project called Lab9ExtraCredit with a package in it called tetrisextra.

Lab Design

Once again you are required to design your solution to the lab. Create a file called Lab9.dia in your project and submit it with your project.

Once again, remember to design and code iteratively.


Grading

Basic requirements (100 points)

The basic requirements are:

  • For a grade of F [50 points] Basic gameboard requirements:
    • A game window appears at start up that does not have the board configuration showing [2 points], but does provide:
      [3 points] A way for the user to start the game
      [3 points] Directions about how the user should move the falling pills
      [3 points] Directions about how the user can pause the game
      [3 points] The ability to end the game (quit functionality)
  • When the user presses start:
    • [6 points] A piece appears on the screen in the center of the top row of the board.
    • [6 points] The piece should begin moving down when the game begins.
  • A pause/unpause game functionality should be implemented so that when a user selects to pause the game, the currently dropping piece disappears [6 points] from the screen. Unpausing the game resumes normal game functionality [6 points].
  • Overall design considerations:
    • There are multiple classes, all code not written in main method [6 points].
    • Code demonstrates good object decomposition. There is a board, several piece classes, etc [6 points].
  • For a grade of D [55 points] Implement all of the above plus:
    • [5 points] Piece stops moving when it hits the bottom of the screen.
  • For a grade of C- [60 points] Implements all of the above plus:
    • [5 points] Piece is controlled by the player with the keyboard and reacts properly for right and left (i.e. - doesn't go through the two side walls)
  • For a grade of C [65 points] Implements all of the above plus:
    • [5 points] Rapid-fall works for each piece.
  • For a grade of C+ [68 points] Implement all of the above plus:
    • [3 points] When one piece stops another appears on the screen and is able to be controlled by the user
  • For a grade of B- [71 points] Implement all of the above plus:
    • [3 points] New pieces appear randomly and all seven different types appear in the game.
  • For a grade of B [77 points] Implement all of the above plus:
    • [6 points] Implementation of the Proxy pattern used within the code.

  • For a grade of B+ [82 points] Implement all of the above plus:
    • [5 points] Pieces stop when they land on other pieces.

  • For a grade of A- [87 points] Implement all of the above plus:
    • [5 points] If a piece or any piece part comes to rest in any column of the top row of the game, the game is over.

  • For a grade of A [100 points] Implement all of the above plus:
    • [5 points] When an entire row is filled, that row must disappear and the rows above must fall down appropriately.
    • [8 points] Pieces can be controlled by the user to rotate by using the keyboard.

  • All notices about naming and commenting will apply to this lab and will result in penalties to your grade if not followed.
  • You must submit a UML diagram with your solution to Lab 9. [If not submitted, you will lose 10 points]
  • Prepare a plain-text README file describing: [If not submitted, you will lose 10 points]
    • the testing of your code that you have done, and
    • all known bugs with your code. This is important - if we find bugs that you haven't listed, we will deduct extra points. If we find bugs you have listed, then we will simply deduct the points listed above.

Extensions (83 points extra credit described so far - may be adding more!)

The following are possible extensions that you may choose to undertake. If you have an idea that is not on the list, send email to your instructor for approval of it as an extension and a point breakdown.

  • [5 points] Keep score and line count (remember: completing 4 lines at once is a Tetris!).
  • [5 points] Keep lives - as soon as the player loses three times, the game is over.
  • [5 points] Timed game - player must complete so many lines in a particular amount of time or game over.
  • [5 points] Make new and interesting pieces.
  • [10 points] Make the game progressively harder (e.g., make the pieces drop progressively faster) as the player completes more and more lines.
  • [5 points] Allow the player to restart the game at any time (i.e., aborting the current game and starting a new game immediately)
  • [7 points] Allow the user to see the next piece which will fall down the screen.
  • [8 points] Add obstacles to the board (other pieces) already on the board when the level begins.
  • [10 points] Two-player option that alternates players after each player loses a life.
  • [20 points] Two-player option where both players are playing on the screen at the same time on two different boards.
  • [3 points] Add sounds to the game.

Submission Directions

You must include in the project a README file, as indicated above. This file must be a plain text file. You can create a plain text file in Eclipse by right clicking on your project and selecting New -> Untitled Text File. Now select File->Save As. Navigate to the Lab9 package within your Lab9 project (you should see "Lab9/tetris" as the parent folder location). Name the file "README" and click OK.

After you are finished writing your code, confirm that your .java files, your UML diagram, and the README file are located in the tetris package in your Lab9 project. Once you are certain that you have the correct set of files in your project, export your solution as a jar file, just as you did in previous labs, but name your jar file Lab9.jar.

VERY IMPORTANT NOTE- If you decide to do work beyond the minimum requirements, you must do the following:

  • A submission with just your basic requirements, named Lab9.jar.
  • A separate submission with the extra work included, named Lab9ExtraCredit.jar.
    • The Lab9Extra.jar file must be able to be imported as an exisiting project entitled "Lab9ExtraCredit." This means that the project folder name must be "Lab9ExtraCredit" before you attempt to export.
    • In your Lab9ExtraCredit README file, you must include a list of the extra credit items you completed, as well as the testing and bug information for the extra credit items.

You must follow all directions about filenames exactly, otherwise your work will not be graded.

When you are ready to submit your work, use the electronic submission program that corresponds to your recitation.


Due Dates

Due 11:59:59pm on Monday, April 30th for all sections.


Appendix A

To move a point 90 degrees counter-clockwise in a circle around another point:

xLocation = centerOfRotationX - centerOfRotationY + oldYLocation
yLocation = centerOfRotationY + centerOfRotationX - oldXLocation

where xLocation and yLocation are the new coordinates of the point being moved, centerOfRotationX and centerOfRotationY are the coordinates of the fixed point around which this point is moving, and oldXLocation and oldYLocation are the original coordinates of the point being moved. Note that this assumes that the positive y axis points down.


CSE 115 - Spring 2007 - Footer

 

 
Last modified: Thu Mar 29 10:18:13 2007
© Adrienne Decker