CompSci 307
Spring 2019
Software Design and Implementation

Monopoly

Monopoly is a board game, published by Hasbro, named after concept of domination of market by single entity. In the 86 years since it was invented, over a billion players from around the globe have played this game and, based on online forums most of those players either ardently love the game or stridently hate it :) It was originally intended as an educational game to illustrate the negative aspects of concentrating land in private monopolies and, since its original conceptual version in 1903, it has spawned variations that eventually became the version most people today are familiar with.

Today most of the amazing number of variations are based on "localizations" that provide different property names and card actions specific to a real or fictional place. When comparing people's Monopoly experiences, it is clear that most households made up their own rules to supplement the official ones (which are now mostly only played in tournaments). There have also been several attempts to create variants that modernize the game, shorten the game, or based on the number of players, or encourage cooperation over ruthlessly trying to bankrupt your opponents (i.e., friends and family).

Your task is to create a design that can accommodate such variations, while still supporting the basic game play of Monopoly.

Specification

In teams, write a Java program using OpenJFX that allows multiple users to choose among different available variations of Monopoly, join together to play a game with other players (human or not), and track cumulative general information about the games played.

Basic Rules

At a minimum, your program must support allowing multiple users, on the same computer, to play a basic game of Monopoly, in which the official rules are enforced (which, honestly, most people have never actually read), determining which player wins (based on the game's goal) and which lose (based on running out of funds) the game.

Looking at these rules, notice how the game is organized into areas that are common to all Monopoly style games, each of which allow for tremendous variation that can completely change the game play.

The problem of providing a flexible and extensible design that supports this framework but allows for variations is a key design challenge.

User Interface

At a minimum, your program must support allowing users to select a game from the options available, join together to play the game (including selecting automated players), facilitate playing the game, let players know how they are doing in the game and when they lose or win the game, save a game at any point, and return to the available games to select a new game to play. Additionally, it should be possible to add new game options by loading a set of configuration files or load a previously saved game to resume playing it.

Looking at these options, notice how the experience of selecting and playing a game is organized into areas that are common, each of which allow for tremendous variation.

The problem of determining the visible UI elements, their position, and potentially their functionality based on configuration data, rather than being hard-coded is a key design challenge.

APIs to Support Variations

The many variations of Monopoly typically differ in certain areas, so the areas of the game listed in the Basic Rules and User Interface sections above should be extensible so as to support as many different variations as your team can imagine. Put another way, the core Monopoly engine should be a platform that exposes APIs for extending the game in these different areas so that variations can be easily created and combined into a playable game.

Here are links to specific example games to challenge some of your possible assumptions and to give you concrete ideas about the wide range of differences your design should be able to support:

You are definitely not expected to implement every possible variation, but you must be prepared to provide a detailed justification of how your design either already supports adding a new variation or how it would need to change to do so. Your goal should be to create a general platform that requires only a few lines of clearly documented Java code to vary one aspect of the game and few to no lines of code to configure everything into a specific, playable game. Thus, to maximize your grade, implement enough variety to clearly demonstrate that your design supports further such extensions.

Configuration

No modern game hard-codes its data into the source code, so to the extent possible, the configuration of any game variation should be represented using data files. In addition to the obvious local variants that differ in the set of properties and action cards, think about things like the rent/upgrade rates or the active rules in a game or the actions allowed among players between moves. Additionally, the complete state of any active game should be savable, so users can suspend a game, come back later, and load the game state back in to continue playing.

The exact format and content of these configuration file(s) is to be determined by your team, but must use a standard file type and parser (rather than developing your own) such as:

All of these file formats are generally easy to read and generate algorithmically.

Challenges

Do something to stretch your design further and to differentiate your project from others. These challenges must further the good design of your program by being integrated into the project through abstractions, not simply added at the last minute as classes or methods that require changing existing APIs or code that should be closed.

Your team needs to implement at least one of the following challenges, extra credit will be given for implementing more than that:

The amount of credit you will receive for these features will be in proportion to how clearly it follows the goals of your design. Contorting your main design to add in extra functionality or adding poor code that diminishes the rest of your refactoring efforts will not be rewarded. Thus, a program with fewer features, but plenty of clear paths to easy expansion, is worth more than a program with lots of features but no closed classes and no good inheritance hierarchies.

Testing

Create JUnit test classes, one for each of your concrete classes (both backend and frontend), in a separate test package with at least two well named tests for each non-trivial public method (more than two are expected for complex methods) and at least one test for each exception thrown. Each test class should achieve at least 70% Lines test coverage of the class it is testing. Additionally, there should be higher-level integration tests that combine calls from multiple classes to test that your APIs are working together to make a feature work correctly. Finally, each data file should have at least 3 different examples that produce known results to test when it is loaded and used.

While you are not required to practice TDD strictly (always writing a test before writing any code), you are expected to create tests frequently during the coding process rather than waiting until the end. To demonstrate that you are following this general process, all of your GIT commits must include new or updated tests in addition to the feature code (especially when fixing bugs). This requirement is typical in industry and we expect to enforce it for this project by actually rejecting Merge Requests that do not meet test code coverage percentages.

Design Goals

Thinking deliberately about each class' public methods as an Application Programming Interface, or API, for others on your team can really improve how you approach the task of programming and design. One way to view an API is as a contract to provide a service and, once such a contract is in place, developers are enticed to use the API because they know they can rely on its stability. The design of the APIs is arguably the most critical part of designing a program, because it affects the design of other components dependent on them. So focus on organizing your program as a collection of interconnected services that work together.

This assignment provides a context to begin thinking about larger scale design issues:

  1. Develop Programmer's Interface. Change your focus from simply writing code that works to writing APIs, code that serves other parts of the program (other team members) and allows those parts freedom to implement without regard to the internal workings of your code.
  2. Design Patterns. Find the right design to help you solve specific problems and adapt it to your specific situation taking into account its trade-offs.
  3. Data Driven Design. Use data files to drive the flexibility of as much of your code as possible rather than hard-coding it.

Additionally, the overall program should still be clearly divided into packages that clearly separates the Model (which has no dependencies on OpenJFX) from the View (which uses OpenJFX to display and interact with the Model's data) as well as a Controller if determined necessary by the team. 

Individual Responsibilities

This is a large project, and it requires steady, consistent, work. Only if you put in the time each week will you see measurable progress and not have to pull "heroic" all-nighters near the end. However, inevitably conflicts are likely to occur. If there is someone on your team who is not getting their work done or not attending meetings, please let the course staff know as quickly as possible. Even if it has happened just once or twice, it is better to deal with the situation early rather than having a big disaster at the end when little can be done to get back on track.

Participation

The first sign that a project is going to be a disaster is that meetings stop getting full attendance. You are expected to attend all such meetings, on time, and to participate in the discussion. If you are not going to be able to attend, you need to let people know in advance and work out some appropriate way to make up attendance (e.g., meet at some other time).

Functionality

Every week, you are expected to develop code that implements new features or significantly improves the project's design. The following does not count as successful work:

It can be a little difficult to exactly quantify what a reasonable amount of code is: sometimes, just the right 150 lines might be really hard to write; other times you can add 1,000 lines of duplicated boilerplate and still have accomplished nothing. A good rule of thumb is to work with your team to agree on what needs to get done each week and then get a least a basic version of most of that done.

Code Cleanliness

The code you write should be clear, free of duplication, and meet all checklist items from previous projects. The following does not count as clean code:

Interesting Design Challenge

Everyone on the team should take at least one opportunity to show their design skills individually by taking responsibility to solve at least one design problem. Your resulting design should:

Although you are encouraged to discuss your design with a TA and team mates, the final decisions should be yours and you should be able to justify them. You will be responsible for both discussing this problem and your solution in public presentations and your analysis, as well as implementing the design in code backed by your GIT commits. The quality of your individual design will form a large part of your overall project grade.

Going Above and Beyond

To make a project a success, it is often the case that sometimes you need to go above and beyond the call of duty to help. Sometimes you may have do another person's part because they are suddenly ill or you may spend several hours helping someone on another team solve a particularly nasty bug. If that is the case, definitely make sure you get credit. It is generally expected that everyone will go above beyond at least once during the project since you are in this together and that is expected of being a good team mate. Going above and beyond does not have any direct mechanical affect on your grade, be we will evaluate it on a case by case basis when your final project grade is decided.

Deliverables

Each week you will have something due:

After each deliverable:

Resources