| CompSci 308 Spring 2026 |
Advanced Software Design and Implementation |
In this lab, you will refactor two working games of Hangman to remove code duplication and clarify their differences. Refactoring is the process of changing the implementation of a piece of code without changing the functionality.
In pairs of your choosing, complete the following steps:
Please complete each step before moving onto the next.
The result of this lab will be a Hangman game that functions the same as the initial game, and generalize the result into a single game with multiple classes as options for change.
Labs in this course expect you to work either in pairs or with your project team.
Professionally, this practice is called Pair Programming. In class meetings, you will:
Follow these steps to setup your Pair Programming environment:
lab_hangman to their repository to allow pushing your pair's changes.
Manage → Members (in the left side panel) to add your partner so both people in the group can access the same repositoryMaintainer role in the project and choose Add to Projectgit clone to copy the forked repository to the local machine.DISCUSSION.md.Note: When pair programming, it is a good idea for the non-coding partner to have a copy of the code in front of them for reference. This will also help in the next section.
Before Moving On: Add your names to the DISCUSSION.md file, thenadd, commit the file, and push to your forked lab_hangman repository.
In the game of Hangman, one player tries to guess a secret word that another player has chosen by guessing a letter at a time. There are two similar versions of the game that simulate four different kinds of players (based on assignments given in CompSci 101). A player is either a guesser or secret keeper.
HangmanInteractiveGame.java: An interactive guesser versus a secret keeper that chooses a random secret word.HangmanAutoGame.java: An auto guesser that chooses letters based on frequency versus a sneaky secret keeper that changes the secret word after each guess to maximize the remaining possible words.Refactoring is the practice of updating a program to improve its design and maintainability without changing its current functionality. For example, creating a single method from two similar code blocks to reduce duplicate code.
Review the two classes linked above first with your partner to identify what lines of code in their respective play() method represent behavior specific to the various guesser or secret keeper players. Consider opening them in separate windows and viewing them side by side.
Do not look at the versions in the repository yet.
While it is not essential to understand the algorithm used by the sneaky secret keeper, consider using an LLM to help explain the code to you rather than spending significant time inspecting it. After reviewing the code yourself, prompt an LLM for suggestions to get its take on your thoughts or suggest new ideas.
To guide your discussion, consider the following questions:
The method play() is composed of several steps:
Another way to help identify candidate code within each game that could be turned into methods, consider how would you make the following new game using the current design:
Do not worry about the exact Java code needed to implement these players, just identifying what lines in either one of the game classes need to be changed to implement the new players described above.
In
the DISCUSSION.md file, write down the methods you will create. For each method, specify
The goal of this step is not to get all the implementation details exactly correct, but rather to develop an understanding of how the classes need to interact with each other to remove duplication.
Before Moving On: Write short summaries of
your discussion in the DISCUSSION.md file, then add, commit the file, and
push to your forked lab_hangman repository.
In this section, you will plan several refactoring steps to change two classes with heavily duplicated code into the following three classes with no duplicated code:
HangmanGameGuesserSecretKeeperYou will also separate the game rules from the player logic so that they can be changed independently.
Now consider the code that you cloned. It has already been refactored to create several short, private methods such that the two play() methods are identical and all of the differences have been factored out into some of the methods (some methods are still duplicated and represent the same behvaior). Thus your task now is to:
To help you in this process, consider the following:
HangmanGame, Guesser, or SecretKeeper) should be responsible for these instance
variables (and why): mySecretWord, myNumGuessesLeft, myDisplayWord, and myLettersLeftToGuess?Your pair may create any new methods or classes you want to help improve the program. However, because the functionality of the program should not change in this refactoring, you should focus primarily on moving existing code rather than creating any new code.
Before Moving On: Write short summaries of
your discussion in the DISCUSSION.md file, then add, commit the file, and push to your forked lab_hangman repository.
Using pair programming in 15 minute increments (or after each change described below), perform the refactoring your planned above.
First, rename InteractiveHangmanGame to HangmanGame. For the rest of your refactoring, you will
gradually extract functionality out of HangmanGame into Guesser and SecretKeeper classes. Below, an
ordering of steps is provided, but not the changes themselves. You will
need to implement the methods you defined your Refactoring Plan. It’s
fine if you need to alter the methods from what you originally planned
to make things work.
Note: Please leave at least 10 minutes at the end of lab to Debrief and Submit your Work. It is okay if you are not finished with your refactoring by then. Just find a stopping place (ideally with working code), commit your changes, and move on to Debrief.
Guesser class that implements the interactive
guessing using the methods from your planMain class to create the Guesser and pass it to the HangmanGameHangmanGame class to call methods on the Guesser in place of its own methodsMake sure you can play an interactive game using your new Guesser.
Add and commit your changes to the source
code before moving on.
SecretKeeper class that implements choosing a random secret word using the methods from your planMain class to create the SecretKeeper and pass it to the HangmanGameHangmanGame class to call methods on the SecretKeeper in place of its own methodsMake sure you can play an interactive game using both the Guesser and your new SecretKeeper.
Add and commit your changes to the source
code before moving on.
Guesser class to implement choosing letters
automatically by using the logic from the original AutoHangmanGame.No changes should need to be made to the HangmanGame or Main classes.
Make sure you can run an auto game using both the Guesser and your new SecretKeeper.
Add and commit your changes to the source
code before moving on.
SecretKeeper class to implement changing
the secret word after each guess by using the logic from the original AutoHangmanGame.No changes should need to be made to the HangmanGame or Main classes.
Make sure you can run an auto game using both the Guesser and the sneaky version of the SecretKeeper.
Before Moving On: Add and commit your changes to the source
code and push them to your forked lab_hangman repository.
In this section, review your changes (or planned changes if you did not get to implement everything). Then, you add short
summaries of your discussion to the Debrief section of DISCUSSION.md file.
Discuss with your partner, as concretely as you can, how to implement these changes using this new version of the code:
HangmanGame class.main() method, not copying any
existing classes.Taking the totality of the lab in mind, discuss the following with your partner:
At the end of lab, use Gitlab's Merge
Request from your forked repository's main branch back
to the original organization repository's main branch to
submit your group's answers to the discussion questions and your
refactored code.
Make the Title of your Merge Request is of the form "lab_hangman - NetIDs".
You only need to create one Merge Request, no matter how many commits you make, and you do not worry about potential conflicts since your request will not be approved (it is just an easy way for us to see what changes you made).
If you are using two machines for Pair Programming, then both lab partners need to clone the environment (as instructed above).
You have two options for synchronizing across machines:
commit and push changes to Gitlab after each partner
codes. Then, the other partner will need to pull the changes.