Homework 2
In this TP2 you are requested to do the following:
- (Finalize your model implementation, if not already done)
- Migrate your project to Maven
- Replace the previous interface copies, by a library reference
- Integrate the
execplugin, so your code is runnable
- Implement a controller for:
- Model initialization (using a factory)
- Model state transfer using commands. At least:
- Pop card from stack
- Reject Card
- Reveal undisclosed card
Think of the controller as an invisible game manager, that ensures the rules are followed, as the game is played.
Code is a grade preliminary
Your grade is based on your ability to explain and reason with your submitted code, during the subsequent oral exam. Functional code is a preliminary for taking the oral exam: While missing features in your code will result in a grade reduction, no points by themselves granted for the submitted implementation.
Interfaces
Like last time, you'll be working with provided interfaces, to ensure you rest on track.
- Last time the interfaces were provided as Code.
- This time they are provided as a maven library, along with an online documentation.
Migration to Maven
For the TP2, you are requested to switch from standard java project layout to maven. In detail this means:
- You have to adjust the folder structure.
- You have to create a
pom.xmlfile.
Use a template
If you don't know where to start, create a new maven template project (you've seen the command in the last lecture), and afterwards copy your previous TP1 source files into the template project. This also provides you with a default pom.xml.
Project layout
As seen in class, Maven projects must follow a specific layout.
- Modify your project structure, so it is a valid maven project.
- Create a
pom.xml - Ensure the project compiles using the
mvn compilecommand.
Interfaces as library
- For this second TP, your project must only contain your own classes.
- That is, you have to remove all provided interfaces and the entire
viewpackage. - These classes are still there for your convenience though! To access them as a library, use the following
repositoryanddependencyconfiguration:repositorytells maven where to download the interfaces / classes from (they are not on the official maven servers).dependencytells maven what exactly to download.
...
<repositories>
<repository>
<id>Max's third party repo on a UQAM GitLab file server</id>
<url>https://max.pages.info.uqam.ca/inf2050repo/</url>
</repository>
</repositories>
<dependencies>
<!-- DO NOT ADD ANY OTHER DEPENDENCIES HERE!-->
<dependency>
<groupId>ca.uqam.info.mgl7010.max</groupId>
<artifactId>skyjo-interfaces</artifactId>
<version>f25-1.0</version>
</dependency>
</dependencies>
...
Exec plugin
- By default, maven projects are not executable (maven cannot not know if they are programs, or libraries).
- Add the
execplugin to yourpom.xmlconfiguration, to add a launcher configuration. - Have it point to the provided TP2 launcher code (see sample code further below), so it is executed on
mvn exec:java
Controller
In the previous TP, all your code was in a single package: model.
modelis only for storing game state.- In this TP2, you're dealing with player interactions (which alter state), therefore you need a new
package:
controller.
Model initialization
- Create a new class
LauncherTP2.javain your new controller package. - Use the sample code below to launch your software...
- You will need to implement a new class
ControllerImplwhich implements the providedControllerinterface, to make it work. - Make sure it is your
controllerthat deals with all logic required to instantiate new models (controller.initializeModel(ModelPreset.DEFAULT, players)). This will require some refactoring of your TP1 code, where most likely you placed all logic in the Model constructor. Logic means e.g. creating a card deck, shuffling the cards, etc...
- You will need to implement a new class
public static void main(String[] args) {
// Visual parameters and player names (hard coded for TP2)
boolean useTtyColours = true;
String[] players = new String[] {"Max", "Ryan", "Maram", "Quentin"};
// Initialize a new game
Controller controller = new ControllerImpl();
controller.initializeModel(ModelPreset.DEFAULT, players);
// Register UI to automatically refresh on model updates
CommandSelector controller.addModelObserver(new TextualVisualizer(controller.getModel(), useTtyColours));
// Initialize commandSelector for interactive / TTY mode
commandSelector = new TextualCommandSelector(useTtyColours, false);
// Play the game :)
playUntilGameEnd(controller);
}
/**
* Note: This method is not concerned with updating model state representations, for the model
* adheres to the observer pattern for this purpose.
* This loop is only about retrieving user inputs until game end. The model is automatically
* rendered after each executed command.
*
* @param controller as the MVC controller allowing to progress the game command by command.
* Note that the view has no direct access to the model, and can only
* manipulate model state by executing commands.
*/
private static void playUntilGameEnd(Controller controller) {
// Initialize options for game start
Command[] options = controller.getCurrentPlayerCommands();
// Keep playing until controller offers no more options (game end)
while (options.length > 0) {
// Request a choice from robot / human player
int selectedCommand = commandSelector.selectCommand(options, controller.isUndoAvailable());
// Execute choice (this implicitly re-renders the model)
controller.doCommand(selectedCommand);
// Update options
options = controller.getCurrentPlayerCommands();
}
}
The second method implements the game logic.
- By default, it uses the provided textual UI to prompt users for choices.
- You do not need to implement any UI functionality, all is provided with the maven library.
Ignore undo
It is not required to implement undo for now. I'll ask you to implement that function later.
Test by auto-selection the first option
You can skip the user-prompting, by automatically choosing the first option (0) as selectedCommand. This way your can will fast-forward to the game end, without human interaction, and you can verify your implementation.
Model state transfer with Commands
The above main control loop required your ControllerImpl to determine which player actions are possible.
- To forward the game, you'll distribute the game logic on
multiple
Commands, each command being an object that modifies game state. - You'll learn everything else about commands in a later lecture. For now it is sufficient to know that each command deals with one player action.
For this TP2 you do not need to implement the full game. It is sufficient to limit player actions to:
- Taking a card from the pile (
RevealFreshCardCommand implements Command) - Rejecting the revealed card (
RejectCard implements Command) - Revealing one of the remaining undisclosed player cards (
RevealCard implements Command)
These commands are enough, because the sequence of the above three defines a valid player move.
Do not bother with the other commands
The above commands are enough to play a valid Skyjo session. Do not bother with the remaining cards for now, you'll be asked to implement them later.
Contribution statement
Include a PDF file with the following information and statement:
Information
Per team member:
- The percentage of work they contributed.
- 2 classes / methods they declare themselves designated experts for.
Statement
Include this statement in your submission, sign it on paper, take a photo and add it to your submission.
We hereby declare that we have not used generative AI to produce any content for this TP submission, and have not copied code from other sources without giving credit in the program comments. We understand that including AI generated content, or copying foreign code without due credit is a serious academic offense and will be reported to the university plagiarism commission, which may lead to our expulsion from the study program.
- Signature: ____
- Signature: ____
-
Signature: ____
-
Date: ____
Submission
Submission is due by Friday 07-11-2025 Saturday 15-11-2025, 11:59PM per email
to schiedermeier.maximilian@uqam.ca.
- Subject TP2
- Content:
- Single zip file with: Maven project
pom.xmlsrcfolder
- Contribution statement, signed.
- Single zip file with: Maven project
Do not submit your
targetfolder.
Point reductions
While your grade is based upon your ability to explain your code, you can loose points (i.e. the maximal grade you can obtain is lowered) if certain requests are ignored by your solution:
Implementation reductions
- No maven: -100%, avoid at all costs.
- No controller / 3 basic commands not implemented: -100%, avoid at all costs.
- No contribution statement: -100%, avoid at all costs.
- Provided interfaces modified or not used, i.e. no
implements Controller: -100%, avoid at all costs. - Code does not compile with
mvn clean compile, version 24: -100%, avoid at all costs. - Code crashes upon execution with
mvn exec:java, version 24: -100%, avoid at all costs. - Additional non-jdk dependencies added / third party libraries used (except provided interfaces): -100%, avoid at all costs.
- Deck not implemented with own data structure: -30%
- State is hard coded / does not change on restart: -20%
- Missing/incomplete model method implementations: -10% per missing / incomplete method.
- Overly complicated methods: -5% per method with more than 25 lines (comments not counting)
Submission reductions
- Late submission: -30% starting at the deadline, another -20% for each additional 24h delay.
- Submission contains junk/hidden files or binary files (
.classfiles): -5% per unnecessary file.
MISC
Questions
- For questions related to the TP requirements, please use the Mattermost forum.
- Do not share code or parts of your solution on Mattermost.
Suggestions
While not a strict requirement, and not directly leading to bonus points, it is always a good idea to brighten up the professor's mood with a few tricks:
- Double-check your submission before sending it to the prof:
- Send it first to a team member. Let them extract the ZIP, compile the code etc on a different machine.
- If all works well, forward the email to the prof.
- Format your code: Use IntelliJ code format combo, so your code is easier to read.
- Revisit the labs: Parts of the solutions for this TP have been subtly covered in the labs. If you think a lab solution qualifies for reuse, place a comment in your code.
- Comment your code: Use javadoc
/** ... */for methods, and regular comments//in-line.
Get used to english comments and naming conventions
You have the right to comment in French, and the language you use for comments is guaranteed to have absolutely no impact on your grade. However, keep in mind that computer science is an international discipline and on the long term you'll most likely have to comment in english anyway. Better get used to it early. Same for variables and method names: Get used to english names, it makes things a lot easier on the long run. I once worked in an international team where every intern added comments and naming in their native language, so we have English, German, French, Spanish, even Chinese. With no surprise this had a detrimental effect on the project.