Getting Started: Selfish (Space Edition)
version 1.1
Q1703105484
Typos/errors? Email sarah.clinch@manchester.ac.uk and I'll get them fixed. |
Table of Contents
- Preliminaries
- A Staged Guide to Development
- Need More Help?
- Preliminaries
You do not have to follow the instructions in this document if you do not want to, and the instructions below may not give you a complete solution. They're intended to be a general guide for those who want some help knowing how to approach the problem.
Your solution must meet the provided specification, so you should take time to carefully read all instructions and UML class diagrams. Do this before progressing any further with the instructions in this document!
- A Staged Guide to Development
Knowing where to start a game like this can be tricky. Here's one possible set of steps you can follow:
-
- Familiarise yourself with the mechanisms for testing/running code.
Clone the repository and run the tests.sh file. It might seem counter intuitive to start by running the tests before any code, but once you know you can run the tests then it's easy to track your progress. Familiarise yourself with the test output, it should end as follows:
[ | 22 | containers found | ] |
[ | 0 | containers skipped | ] |
[ | 22 | containers started | ] |
[ | 0 | containers aborted | ] |
[ | 22 | containers successful | ] |
[ | 0 | containers failed | ] |
[ | 374 | tests found | ] |
[ | 0 | tests skipped | ] |
[ | 374 | tests started | ] |
[ | 0 | tests aborted | ] |
[ | 0 | tests successful | ] |
[ | 374 | tests failed | ] |
selfish |
selfish.decks |
classes in the
and
packages [1]. If you scroll back
through the output, you'll see it starts with all the compilation errors for the functional tests, followed by something like this:
Each of the red lines represented one failing test, and the blue lines are the classes in which the failing tests can be found. Below this you can view the Stack trace for each failing test:
[1] -- Note that in this document we only have you write class/method
signatures as you come to write associated the functionality. This means that (due to interdependencies between classes) functional tests may not compile until very late on. To avoid this, you could choose to write the class/method signatures now, and then work through adding functionality in accordance with the rest of this guide.
GameDriver.java |
driver -- nothing will happen because the main method is empty.
-
- In order to get the tests to pass, you're going to need to get to grips with packaging. Following the materials signposted on this topic, start by creating the selfish
GameEngine |
game |
see some are now passing.
-
-
Create the package. You should be very comfortable withselfish.deck
-
subclass/superclass (inheritance) relationships so at this point you can write near-
Oxygen |
Deck |
GameDriver.java |
point, your implementation (including the provided represented in UML as follows:
) can be
If you run the tests now, 65 structural tests should pass. If you've not already committed and pushed your changes so far, then do that now. From this point on we're not going to remind you to commit and push, but you should do this regularly.
If you want to avoid a lot of documentation at the end, now might be a good time to read up on Javadoc and add some Javadoc comments in -- check, do the relevant Javadoc tests now pass? (You should document all public/protected classes and members).
-
- Next, we suggest writing some code for the driver program ( GameDriver.java ).
main |
-
- Add some console IO to your driver. A basic loop that let's you add players (and results
Astronaut |
io/artwork.txt |
you can also copy in the header ascii art from be something like this:
. The result might
-
- The Deck class is responsible for reading in cards from file, and is uses the loadCards method to do this. Add an empty constructor. Add an empty loadCards method according to the UML signature, and include a return statement return null to ensure it will compile successfully. Re-run the tests to check that
you've got the signatures correct (more tests will now pass).
-
-
Add some file handling to that reads from the specified path and createsloadCards
-
GameException |
class).
-
- Implement the
constructors in GameDeck and
, calling the
String |
SpaceDeck |
loadCards |
Deck |
the driver, and run both the driver and the tests to ensure that the code executes OK.
-
- Time to branch out into the unknown... take a look at the documentation for
java.util.random |
Random |
should be able to implement the two GameEngine constructors, moving the calls to
Deck |
should be creating an instance of GameEngine , these will still get called). It should now be straightforward to add two more calls to the Deck subclass constuctors (this time for the discard piles), assign them to instance variables and write get methods for those variables. At this point, your implementation can be represented in UML as
follows:
Again... If you've not been writing Javadoc as you go, now might be a good time to update the Javadoc from step 3 / read up on Javadoc and add some Javadoc comments in. Check, do the relevant Javadoc tests now pass? (You should document all public/protected classes and members).
-
-
loadState
Now that you've got text file handling sorted, it's time to do some object file handlingsaveState
-
(serialization). Implement
and
, and add the
serialVersionUID |
loadState |
saveState |
if you just prove to yourself that you can and it works).
You're well on the way, so the instructions for the next steps get sparser, but here are some hints:
-
- At some point you're going to have to tackle a data structure. You have two options here and both connect to pieces you've implemented already.
- Implement functionality related to player management in GameEngine ,
- At some point you're going to have to tackle a data structure. You have two options here and both connect to pieces you've implemented already.
activePlayers |
populating the attributes, implementing associated get methods). This should in
startTurn |
endTurn |
-
-
-
Revisit the classes to make the cards persist. At that point you canDeck
-
-
Deck |
Returning to GameEngine you can now implement mergeDecks and
startGame . If you've already done (i), then update the driver program so that as you cycle through players, a card is drawn and placed on the discard pile. If you
haven't done (i) yet, then update the driver program so that it loops through the decks, drawing a card and placing it on the relevant discard pile. When the deck runs out, use `mergeDecks` to shuffle the discard pile back into the deck.
If you've not been writing Javadoc as you go, now might be a good time to update Javadoc and check the relevant. test output.
-
-
If you didn't tackle in GameEngine in the previous step, then it's asplitOxygen
-
good idea to do that now. Think carefully about the edge cases with this one.
-
- After tackling (i) and (ii) above, there are just a few data structures left in the UML that won't be represented in your implementation. Considering (ii) above, implementing functionality related to an Astronaut's hand ( actions and oxygens ) should seem very similar. After tackling these (together with addToHand , getActions ,
isAlive |
siphon , steal ), you should be able to revisit (i) above to add in the corpses
attribute, getAllPlayers , getFullPlayerCount , and killPlayer . Update the driver program so that as you cycle through players, each player draws a card and then breathes. If you cycle for long enough, maybe some players will die (there's a lot of Oxygen in the game deck, so you may want to temporarily modify the code to reduce this and make death more likely).
At this point, your implementation can be represented in UML as follows:
-
- This is probably a good time to give the driver program an upgrade, making it possible to see how players' hands change during their turn, to allow them to play cards and target other players (even if, in some cases, the only effect is that the card ends up in the discard pile). To represent (and allow interaction with) an Astronaut's hand, you'll
getActionsStr |
implementing the Comparable interface at this point too.
. We'd suggest
-
- Without track logic it's impossible for anyone to win this game. All the unimplemented
Astronaut |
functionality in now relates to tracks, so go ahead and finish off this class
gameOver |
getWinner |
now. This should also allow you to implement , .
At this point, you should have implemented everything in the UML. All the functional and structural tests should pass. Hopefully, you've been writing Javadoc since step 3, but if not then now is the time!
You have (at least) three choices from here:
- Stop development. If all the tests pass (including the Javadoc tests) then you have 80% of the marks.
- Finish the driver program. It's not earning you any extra marks, but at least you'll have finished an awesome game.
- Start development on a JavaFX GUI that uses the classes you've developed in the previous steps to allow a full play through the game.
Whatever you do, be sure to submit your solution by tagging correctly and pushing all commits.
- Need More Help?
Don't forget to run the tests at regular intervals. If you're not sure why a test is failing, take a look at the stack trace. If that's not helping, you can also look at the source code for the relevant test.
You can get also get help prior to submission by asking questions in the labs or online forums.