6.005 — Software Construction
Team contract due : Monday, April 7, 10:00 pm Warmup due : Thursday, April 10, at meeting with TA Specs due : Monday, April 14, 10:00 pm Implementation due : Friday, April 18, 10:00 pm Reflection due : Monday, April 21, 10:00 pm
This semester's group project is a pinball construction kit called Pingball. The original pinball is an arcade game in which the object is to keep a ball moving around in the game, without falling off the bottom of the playing area. The board has various bumpers on it that deflect the ball, and the player controls a set of flippers that can bat at the ball as it falls. > ![One possible implementation of Pingball](pinball-gui.png) > > _One possible implementation of Pingball. Your implementation will look different._ Pingball has several advantages over a traditional pinball machine. First, multiple people can play it over a network, connected with each other through a server. Each player has their own pinball board, but balls can leave one player's board and enter another player's board, running on a different computer. Second, the board layout is configurable by file, so that pinball boards may form complicated "[Rube Goldberg](http://en.wikipedia.org/wiki/Rube_Goldberg_machine)" contraptions that are intended to be watched rather than played. The project will be divided into two phases. * In phase 1, you will build a text-only version of the game with a client-server component that passes balls over the network, but without user interaction. * In phase 2, you will build an interactive version with a graphical user interface that allows multiple people to play pingball with each other over a network. This document describes only phase 1. The purpose of phase 1 is to help you gain more experience with: * Designing, testing, and implementing abstract data types and method specifications * Working with client-server networking * Working with threads and concurrency in a substantial program * Working in a small group with software engineering techniques like version control, specifications, and unit testing ## Your Team's Repository Clone your team's Git repository using (all one line):

git clone ssh://username@athena.dialup.mit.edu/afs/athena.mit.edu/course/6/6.005/git/sp14/projects/gb1/username1-username2-username3.git pingball-phase1

where the three Athena usernames are in alphabetical order. ## Tasks During the project, lecture and recitation meetings are replaced by team work time. You can work in the classrooms where we usually meet, where staff will be available to answer your questions. Your team can also work elsewhere if you choose, but you should use these times to __work together__. Your team will be assigned a TA mentor who will help you with your design and help you stay on the right track as you implement it. You are required to meet with your TA several days into your project. Your TA will get in touch with you to set up that meeting. All team members should attend the meeting. Other than reflections, all parts of the project should be committed in the repository you share with your teammates. Each commit to the repository should have a comment saying what you changed, as well as who worked on it. Your TA will be reviewing your git log to see individual contributions. Make sure you commit frequently! During this project, you will perform the following tasks. * __Team contracts__. Before you begin, you should write and agree to a [team contract](teamcontract.html). * __Understand the problem__. Read the [Pingball specification][specification] carefully. It describes how your pingball game should work in this phase of the project. [specification]: pingball-phase1-spec.html * __Warmup__. There is a warmup exercise that your group needs to do, explained below. It will help you learn how to use the physics engine we provide. You don't have to use our provided physics engine, but you do have to do this warmup exercise with it before deciding to go your own way. * __Design__. You will need to create abstract datatypes for various parts of your system: bumpers, balls, boards, simulator, client, server, and parsers for wire protocol, user commands, and file format. Your software's design is perhaps the most important part of the project; a good design will make it simpler to implement and debug your pingball game. Remember to write specifications for your classes and methods, to define abstraction functions and rep invariants, and to make thread safety arguments. * __Implementation__. Implement the project in Java. Remember to do test-first programming, and to write checkRep() methods and use assertions. * __Testing__. Test your entire system on the [staff sample boards](boards/). Furthermore, create at least three additional board files as tests. These should show that your client is able to correctly parse and simulate the various gadgets that can appear on the board, with trigger relationships, and that multiple clients can exchange balls with each other. You should also have JUnit tests that test smaller components of your system, and your test cases should be developed in a principled way (e.g. input space partitioning) justified by a testing strategy described in a comment, as we've been doing all along. * __Reflection__. Individually, you will each write a brief commentary saying what you learned from this experience. * Reflections on your team. How did you feel the team did? How well did your team work together? How was the coding? How did you split the work? * Reflections on yourself. How do you think you did? What specific contributions did you make? How do you feel about your contributions? ## Specification The [Pingball specification][specification] describes how the pingball game should work in this phase of the project. ## Provided Code We have provided you with a library of physics methods for calculating the dynamics of elastic collisions. [Documentation for the physics package](physics-doc/) is found online. Its key features are: * immutable abstract data types such as Angle, Vect, LineSegment, and Circle * a Geometry class that contains methods to model the physics of elastic collisions between balls and other circles and line segments. A jar file for physics package is provided in your starting repository. Source code for the physics package can be found inside the jar file. You can look at it by browsing into the jar file in Eclipse. You are welcome to use or not use this code as you please, and to modify it to meet your needs. While this source is provided in the event that you wish to examine or modify it, we generally discourage you from modifying it. Spend your energy on other parts of the project. ## Warmup In order to get familiar with the physics package and get the hang of the pingball simulation part of the project, you should write a small program that simulates a single ball bouncing around an empty 20L x 20L board. The ball should have a fixed velocity and reflect off each wall that it collides with. Don't simulate friction or gravity. As the ball bounces around, the board and ball should be printed periodically, in text format, to the console, at 10-20 frames per second. The `main()` method of your program should be in the class `Main` in package `warmup`, i.e. in the file `src/warmup/Main.java` in your repo. You can create other classes in the `warmup` package that help make it work, like `Board` or `Ball`, or you can implement everything inside `Main`. The code in `warmup` will not be part of your final project implementation, you aren't expected to write specs and tests for your warmup code. This is practice code for learning about the problem and how to solve it. ## Hints * For managing time in your pingball simulator, you may want to use some combination of [Thread.sleep()][sleep], [System.currentTimeMillis()][currentTimeMillis], or [java.util.Timer][Timer]. [sleep]: http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#sleep(long) [currentTimeMillis]: http://docs.oracle.com/javase/7/docs/api/java/lang/System.html#currentTimeMillis() [Timer]: http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Timer.html ## Deliverables and Grading Mon Apr 7, 10pm : Your team contract must be committed to your group repository. Place it in a file called `team-contract.pdf` in the top level of your repo, in PDF format. Thu Apr 10 : You will have a checkoff meeting with your group's TA mentor, at which you will need to demonstrate: **(a)** the warmup task, working and committed to your repo in the `warmup` package; and **(b)** some progress on specifications for your major classes and methods, including a concurrency design (thread safety arguments for your client and server). You should have committed these specs to your repository as skeleton classes. Mon Apr 14, 10pm : You should have committed **(a)** full specifications for all your classes and methods, and **(b)** some progress on test cases and implementations. Fri Apr 18, 10pm : This is the deadline of the project. Your implementation should be complete and committed to your group's repository. Mon Apr 21, 10pm : Individually, you should have uploaded your reflection to Stellar in PDF format. Grades will be allotted according to the following breakdown: * Team Contract: 5% * Design: 25% * Implementation: 50% * Testing: 15% * Reflection: 5% The three intermediate milestones (team contract, warmup, and specs) will be graded as binary checkoffs, either passed or missed. Each milestone missed will cost 5 points on the overall project grade. ## Automated Testing Starting with Problem Set 0, you have been using the Didit system for automated building and testing: every time you push your commits to Athena, the Didit build server pulls a copy of your code, attempts to compile it, and runs tests. This kind of automation is very common in the world of professional software development, and is very useful for coordinating a team of developers. There is no ambiguity about whether the code compiles or not: if it doesn't compile on the build server, it doesn't compile. And there is no ambiguity about whether the tests pass: if they don't pass on the build server, they don't pass. For this project, Didit will run _your_ tests: any JUnit tests you check in to your team's project repository will be executed and the results included in your Didit build report. Tests must be in the `src` directory with a name like _something_`Test.java` or _something_`Tests.java` for Didit to find them. Your tests will be run in an environment with limited permissions and resources. Any deliberate attempts to circumvent these restrictions are a violation of course policy and academic standards, and will be dealt with harshly. However: * Your code runs with read-only access to your `src` directory. * You may also access directories named `boards` and `resources` at the root of your project, if you want a place to commit additional project assets. * If you find that Didit is unable to run some of your tests but you think they are reasonable and should be supported, email the TAs and include __"Didit test restrictions"__ in the subject line. Hopefully we will be able to make Didit more accommodating. * You may have some tests Didit cannot run. _Don't let Didit's restrictions stop you from writing such tests._ Instead, for these tests, include the Javadoc tag __`@category no_didit`__ on the test class. _All tests in that file will be ignored._ You cannot use __`@category no_didit`__ on methods --- you must use it on the class. Here's an example: ```java package pingball; import org.junit.Test; /** * Test some super complicated stuff. * @category no_didit */ public class SuperComplicatedTest { @Test public void testRelativisticVelocities() { // Didit will not run this test } // nor any other tests in this file } ``` On your build results page, Didit will report which tests it attempted to run, and which tests it skipped. Make sure you and your teammates are running those tests manually. If you include no tests, Didit will count that as a pass --- remember to also check whether your code compiled!