CompSci 307
Fall 2021
Software Design and Implementation

Team Project: OOGA

If children can build, play and understand games that work, it's possible that someday they will understand and design systems that work. And the world is full of complicated systems. — Sara Corbett

Specification

In teams, write a Java program from scratch using OpenJFX, following Google's Java Style Guide, that allows users to select, play, and track high scores for a variety of games within one of the following genre:

Game variants must be determined solely by configuration data files (these files can facilitate the use reflection to specify game specific Java code to run during the game, but there cannot be separate setup Java code for individual games) that activate features in your Object Oriented Game Architecture, OOGA. Complete four example games that demonstrate the flexibility of your design by differing primarily in their behavior (one can be simple test oriented version and one example game that is a MOD, differing primarily in all its data values). The exact format and content of these configuration file(s) is to be determined by you, but you must use a standard file type and parser (rather than developing your own) such as:

Any colors, fonts, or other appearance styling should be able to be changed dynamically between at least three different options (such as Dark or Light modes, Duke or UNC colors, larger fonts for presentation mode, etc.). Any text displayed should be able to appear in at least four other languages (Pig Latin is a popular option or you can use Google Translate if no one on your team can do it).

Test your program using JUnit (with assertions both for typical situations and possible thrown Exceptions) to verify it works as intended. Generally, aim to create a test class for each of your concrete classes with at least two well-named tests for each non-trivial public method (more than two are expected for complex methods) and try to achieve at least 85% Line test coverage of each class.

Extensions

Additionally, your team must plan to do something from each category below to stretch your design further and to differentiate your project from others. These extensions 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.

Some ideas include:

Basic
  • Preferences. Allow users to set preferences specific to each game played (like preferred colors, player tokens, starting configurations, etc.).
  • Load Games. Allow users to add new game variants by loading a set of configuration files or load a previously saved game to resume playing it.
  • Save Games. Allow users to save the current state of any active game, so they can suspend a game, come back later, and load the game state back in to continue playing.
  • Multiple Games at Once. Allow users to play multiple, possibly different variants, of games at once while running the program.
Mild
  • 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.
  • 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. Note, this will require a connection to a central database (or files that simulate a database) to keep track of user information that persists beyond the running of a single program.
  • Artificial Players. Allow to select "smart" players to play against. Note, depending on the genre, this may be easy or extremely difficult. Also, making players that appear "smart" but beatable is a challenging problem, so providing levels of intelligence and ways to debug these agents graphically is desirable.
Challenging
  • Save Game Data in the Web. Allow users to save and load game data using an online database or web server with REST API. Note, these use the JSON data format so you likely would also.
  • Game Area Editor. Allow users to design the game's initial configuration 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.
  • Game Data Producer and Viewer. All current high-profile games keep track of what happens during game play and allow it to be viewed so levels can be improved. Note, this will require creating a way for the game designer to choose what to measure in the game (as well as providing standard measures) and then a way to load and visualize that data in a meaningful way later, including comparing two different runs of the game.
  • 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. Note, this will require agreeing on a protocol of exactly what information to send over the network to represent what happens in the game.

Deliverables

Each week you will have something due:

With each deliverable each team will:

Example

Consider the (un)popular game Monopoly and its official rules (which most people have likely never actually read) that determine:

Games that have a similar look and feel, but differ only in storyline are easy to implement. For example, Duke-opoly is a variation that can be implemented simply by changing the text and images used in the basic game. A great many different games have successfully been made in this way (localizing Monopoly's properties has been popular since the game was first invented), but they are exactly the same game. You should be able to support these simple MODs (simply by not hardcoding values within your code), but do not limit your design to only these kinds of variations.

Within the goals of these rules, there are tremendous variation that can completely change the game play as seen in variations like these:

These games (and many other Monopoly variants) share common traits, but allow for different behavior within them, such as:

It should be clear from this brief description that a design must be fairly general in order to support any of these varieties without changing any code, just selecting different subclasses. If you were just building a program to implement a basic Monopoly game, you might have classes called "Utility", "Dice", or "Chance". Instead, your design should use more general terms to indicate more possibilities, like CombinableProperty, Randomizer, and Action, and allow them to be instantiated with options or subclassed to make a specific kind of game. This is especially important when designing protocols for how parts of the game interact.

Your task is to create a design that can accommodate many variations in the behavior of individual games, while using the basic play expectations within your game or genre to structure your work so the code does not have to be completely abstract. To verify your design's generality, you will need to demonstrate games that differ in as many ways as you can think of. If you are not certain about the abstractions at the start, think as concretely as possible about how to implement two different games, paying special attention to the code that they would have in common and the code that would differ. Then figure out a way to design something that captures that difference as an abstraction that can be used by the common parts so that, by the end of the project, any differences can be configured from a data file rather than special case code.

Design Specifications

Your overall grade will be based on the program's design, the functionality of your games, and the overall complexity of the genre and features you choose to implement (i.e., Checkers or Monopoly are more complex games than Black Jack or Breakout). So every team, no matter the size or ability, should be able to create a complete, well designed, program by picking a less complex game genre if necessary.

Ideally, a well-designed program will make implementing new features easier so, when choosing a new feature to implement, look for something that fits into your design or refactor your code first to accommodate it. Specifically, your design should be thoughtful and intentional: clearly avoiding duplicate code structures and making it easy to add new game variations without changing the existing code.

Adding functionality not related to an abstraction or resulting in poor code that diminishes your overall design efforts will not be rewarded. Specifically, the credit you receive for a functionality feature will be in proportion to how clearly it shows that your core classes are closed to modification while open to extension using abstractions to remove dependencies on concrete classes. Thus, a program with fewer features, but plenty of clear paths to easy expansion, is worth more than a program with many features but lacking clean code and good abstractions.

In addition to following the course Code Design Habits Checklist, your project design should clearly show the your progress learning the topics we have discussed in the course:

APIs

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 that are general enough to encourage developers to create new features but stable enough to combine elements together into something useful. 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 and how others think about extending the program. So focus on organizing your program as a collection of interconnected services that work together.

At a high level, this program can easily be divided into at least the following APIs:

The many variations within your game or genre typically differ in certain ways that you can exploit to create APIs that allow specific features to be "plugged into" a general framework, thus providing for the extensibility to support as many different variations as you can. Put another way, the core should be a framework that models the genre's "process" and exposes APIs with extension points for concrete pieces to be created representing different game mechanics and combined to make a specific playable game.

Individual Responsibilities when Working as a Team

These projects requires steady, consistent, work — only by putting in consistent time each week will you see measurable progress and not have to pull "heroic" all-nighters.

Although this is a team project, everyone has individual responsibilities to the team that can be summed up as follows:

Unfortunately conflicts are likely to occur, so please let the Teaching Team know as soon as possible — even if it has happened just once or twice since it is better to deal with the situation early rather than having a disaster at the end when little can be done to get back on track.

Resources