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.
- Dice: type of dice (2 6-sided dice, N-sided dice, even the Speed Die); extra turn after rolling doubles; go to jail after too many doubles in a row
- Funds: money bills; electronic money; starting amount per player; income-tax rate, etc.
- Properties: order on board; which property group, including utilities/railroads; cost; house/hotel prices; rents; mortgaging/un-mortgaging
- Go: collecting $200 or other amount; landing directly on it; when passing enables player to collect money
- Landing on properties: buying; auctioning; paying rent based on mortgage/monopoly/house/hotel status
- Chance/Community Chest: different actions on cards; keeping cards (e.g., get out of jail)
- Jail: various ways to get into and out of jail; various options for money paid to get out of jail
- Houses/hotels: cost; buying; building shortages
- Turn-based business: roll and move; moving again based on game actions; other results of move; any player can manage property
- Joining a game: choose token; choose first to go; choose starting position; choose number of tokens per player; choose "local" variation separate from game rules
- Players: interactive players; random automated players; strategic automated players; a tax-man player
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.
- Available games: how to display the game, its information (like active rules); categorize, search, or comment on games
- Available rules: allow user to see available rules, a description for each, enable or disable them for a specific running of a game
- In-game display: show scores/properties owned/etc. for each user on screen during play; other things may be relevant depending on the goals and rules of the game
- Cumulative information: high score can mean the highest or lowest value depending on the game's goals; other information may be relevant depending on the goals and rules of the game
- Views: support for multiple OpenJFX views such as the complete board, just the relevant property or card, general stats about the game like number of properties remaining, total time, etc.
- Cheat keys for testing and experimentation
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:
- Board sizes, shapes, and paths:
- Monopoly Jr.: a smaller board with simplified rules
- Monopoly Mega: larger board
- Monopoly Star Wars: circular board
- Triopoly: complex "3D" board
- SolarQuest: solar system view, very different style of board
- Double Board: two boards connected together to form a figure eight
- U-Build Monopoly: domino-like board with hexagonal spaces
- Goals for winning the game:
- Monopoly Millionaire: first to reach million dollars
- Monopoly Here and Now: collect all passports
- Monopoly Empire: own the top brands
- Monopoly Millennials: collect experiences
- Illuminopoly: subvert properties
- Game rules:
- House Rules: common "at home" rule variations
- Monopoly City: different property add-ons, auctions
- Monopoly Cheaters Edition: promotion of "cheating"
- SolarQuest: different style of rules
- Anti-Monopoly: "anti" rules
- Co-opoly: cooperative rules
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:
- Properties File, a list of key/value pairs, specific to Java, but easy to parse and use
- Comma-separated Values, CSV, like those used to represent spread sheets, that should parsed using a third party library
- eXtensible Markup Language, XML, an open, industry standard, flexible format, that can be parsed directly within Java
- JavaScript Object Notation, JSON, an open, industry standard, flexible format, that is requires a third party library to parse
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:
- Dynamic Game Rules: Allow users to change the rules of the game during the game, perhaps after voting or otherwise confirming that everyone playing understand the rule change.
- Auctions/Trading: Allow users to auction or trade properties between turns
- Multiple Games at Once: Allow users to play multiple, possibly different variants, of games at once while running the program.
- Networked Players: Allow users to find games over the network that are starting or start one and wait for others to join it. Update at any one computer should be made visible to all connected users.
- Player Profiles: Allow users to log in, choose an avatar to be used within the game player, view personal high scores, and save their preferences (e.g., name, password, image, age (if parental controls are implemented), and favorite variants, tokens, colors, etc). Player information should be saved between runs of the program.
- Social Center: Offer social aspects by allowing users to rate, comment, or generally collaborate while playing games.
- Save Game Data in the Web: Allow users to save and load game data using a web server and REST API.
- Board Editor: Allow users to design a board and its content dynamically using a GUI, rather than just editing text data files. Users should be able to load any existing data for editing or save their design in the common format.
- Multiple Views: In addition to the multiple view required within OpenJFX, allow multiple game views in different mediums like text, HTML, or even mobile.
- Generating Interesting Monopoly Boards from Open Data: Use live data to generate game content (main description starts on page 4)
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:
- 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.
- 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.
- 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).
- each meeting should end with clear action items for each member of the team
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:
- code that is not functional (e.g., code that does not compile or that has such severe bugs it doesn't do anything)
- code that works on your local system, but is incompatible with the current version of the repository code
- code that is emailed to someone else on the team, and having them submit it into source control because you have not set up git properly
- code that is submitted too close to the deadline for your team mates to properly integrate together
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:
- code that does not follow the team's naming conventions
- code that does not follow the team's current API
- code that is a mess, making it "unreadable"
- code that does not have tests of any kind
- no code definitely does not count!
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:
- involve multiple interacting classes
- use a design pattern or other "advanced" techniques
- showcase the skills you have learned in this class beyond the checklist
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:
- Plan: plan project, design initial APIs, agree to standard file formats
- Sprint 1: implement the team's planned first release features
- Sprint 2: implement the team's planned second release features
- Complete: implement the team's complete functionality
- Final Demo: implement a variety of games to show off the design's flexibility
- Analysis: reflection on the project
After each deliverable:
- each team will demo their progress in different ways to the class (or the professors for the Final Demo on Monday, April 29 between 12-7pm)
- individually you will reflect on your progress and teamwork