| CPSC 329 | Software Development | Fall 2026 |
This lab provides an opportunity to practice two cooperating programming techniques: pair programming and swarming.
Labs are for learning and practice — you may help and be helped by others when it comes to figuring out what to do, but in the end you need to understand and be able to do the things for yourself.
You may not use AI to figure out what to do or to do the task for you.
due Fri 9/18 at the start of class — though everything should actually be handed in at the end of lab
Make sure that you have handed in your code, repository, commit history, and debrief form for the pair programming exercise and your work and the debrief form for the swarming exercise as directed in those sections. One handin per group for each part.
You've been provided with a partial implementation of a Klondike Solitaire game, following the class organization discussed in class. This is similar to the code you worked with in last week's lab.
The task in this part is to implement TableauColumn's isSequenceValid(List<Card> sequence) method.
Pair up with another person for this part. You will be using one computer.
One person should set up the code you'll be working with:
Create a new Eclipse project named lab3. Remember that the project directory should end up under ~/cs329/dev, not in Eclipse's workspace.
Import all of the Java files from /classes/cs329/lab3 into your project. Make sure they end up under the src folder in the project.
Update the build path to include JUnit: open IsSequenceValidTest.java, click on one of the error icons in the left margin of the editor, and choose "Add JUnit 5 library to the build path". (If quick fix doesn't offer that option, try a different error.)
Confirm that there are now no errors — there shouldn't be any error icons shown in the Package Explorer.
Create a new git repository and do the initial commit.
Together:
Run the tests in IsSequenceValidTest and confirm that they fail.
Locate the isSequenceValid method in TableauColumn and read its comments so you know what it should do.
Decide who drives first.
Pair programming practices:
Work in driver/navigator roles. Switch every 6-7 minutes — a timer will be called out; switch immediately when it is announced, mid-thought or not.
Commit at every switch. The driver writes the commit message describing what was just done; the incoming driver reads it before continuing. Include the driver's name in the commit comment to help document your process for grading purposes.
Navigator: give direction, not dictation — guide towards the next step rather than giving exact syntax. Apply the 5-second rule before pointing out something you notice.
Driver: narrate what you are doing out loud as you type. Narrate ideas rather than exact syntax — "I'll check the empty-column case first...if the column size is 0..." rather than "if open paren column dot size equals 0 close paren open curly bracket..."
Following pair programming practices outlined above, implement TableauColumn's isSequenceValid(List<Card> sequence) method according to its comments. When you are done, all of the tests in IsSequenceValidTest should pass.
If you finish early, continue with Stock.draw(), Waste.removeTop(), and Stock.restock(Waste waste), in that order. Read the comments for those methods to find out what they should do. Note that Stock has no sequencing rules like TableauColumn does — it's just a pile you draw from. Also be sure to read restock's contract carefully — drawing from the stock pile after a restock should reproduce the same order the cards were originally drawn in.
When time is called:
One person should hand in your code, repository, and commit history:
Copy your entire ~/cs329/dev/lab3 directory into your handin directory. Make sure you end up with a lab3 directory inside your handin directory that contains the src directory (with your code) — you shouldn't have a bunch of stuff loose in the top level of your handin directory or multiple levels deep of lab3 folders.
In Eclipse, take a screenshot of the History view that shows all of your commits (with the commit comment, author, and timestamp info) and save it with the name "commit.png" in the top level of your handed-in lab3 directory (the one in your handin folder).
Together fill out the pair programming debrief form (handed out in class). Make sure the names of both team members are on the form! Hand in the form.
The task in this part is to design a way to undo a tableau column move.
Join with another pair (so that you have a group of four) for this part.
Together:
Read the description of the task:
Right now, once a player moves cards from one tableau column to another, there's no way to take it back. Your team wants to add the ability to undo the most recent tableau-column move.
Assume the following existing API:
TableauColumn: boolean isEmpty() int size() Card top() boolean canPlace(Card card) void place(Card card) boolean canPlace(List<Card> sequence) void place(List<Card> sequence) Card pickUp() List<Card> pickUp(int n) List<Card> topCards(int n) GameEngine: boolean moveCards(TableauColumn from, TableauColumn to, int n)
Swarming practices:
No fixed roles — anyone can propose, anyone can push back. Don't let one person's first suggestion become the answer by default; if you notice everyone's agreeing quickly, explicitly ask "does anyone see this differently?"
Make sure everyone in the group agrees on what question you're actually answering before you start proposing solutions.
Write ideas down as you go — don't wait until the final product at the end. Use paper or a whiteboard.
As a group (and following the swarming practices outlined above), work through:
What information is needed to reverse a move?
What needs to change, and where?
Identify how this will be reflected in the code — instance variable(s), method signature(s), class(es).
Write a one-sentence contract for each new method you are proposing.
If your group finishes early, consider one or both of the following scenarios. For each, discuss whether your single tableau-move undo approach extends to it or whether it would need a significant change. Sketch the outline of the idea first, then fill in more details if you still have time.
The game will eventually have other kinds of moves (dealing from the stock pile to the waste pile, moving from the waste pile to a tableau column or foundation pile, moving to a foundation pile, etc). Allow undo for other move types.
Allow undoing a whole sequence of moves, potentially all the way back to the beginning of the game.
When time is called:
Together fill out the swarming debrief form (handed out in class). Make sure the names of all team members are on the form! Hand in the form.
Also hand in your scratchwork — the paper itself or a photo of the whiteboard. You can email the photo to me.