A headless program is one that runs with a UI. It can be useful to design an interactive program (like a game) to be able to run headless in order to expedite testing, run in batch, run across networks and/or run against bots.
For this week's labs and assignments, we'll finish the headless version of the Nine Card Golf game. Your submission will have the specified game classes, unit tests for all the methods and a main
method that runs a single two-player game at the console with random player actions.
Starting with your code from last week, commit your work to this new repository:
https://cssvn.utrgv.edu/svn_etomai/201810_3328/assn05_headless/<username>
Shuffle one or more standard 52 card decks (with Jokers).
Deal 9 cards to each player, the rest of the deck is the draw pile. Flip the top card from the deck to start the discard pile.
Each player organizes their cards face down without looking at them in a 3x3 grid on the table (the hand). Each player turns any 3 of their cards face up.
Each player in turn:
When any player flips their last card face up, the game is over. Score the hands and declare the player with the lowest score the winner.
To score, add the values of all the cards in the hand:
Your program must have the following classes and methods, as we discussed in lab time:
Card
and Deck
from the past assignment, plus these additional Deck
methods:
Add
: add a card to the top of the deckIsEmpty
: returns True if the deck is emptyPeek
: return the card at a specified position without removing it (needed for testing and will be needed for the GUI eventually)Hand
Add
: add a card to the hand, facedown in the next position in the 3x3 gridPeek
: return the card at a specified position without removing it (needed for testing and will be needed for the GUI eventually)TurnUp
: change the card at the specified position from face down to face upIsFaceUp
: returns True if the card at the specified position is face upReplace
: add a card face up to the hand at a specified position and remove and return the card that was there; can also return True/False (by reference) to indicate whether all cards in the hard are now face upIsDone
: alternatively, can have this separate method to indicate whether all cards in the hand are now face upScore
: return the total score for the handPlayer
TakeTurn
: play out a single turn for this playerChooseDrawDiscard
: bot decision-making, returns True to indicate draw from discard, False to indicate draw from the deckChooseReplace
: bot decision-making, returns which card position in the hand to replace with the current drawTo start, the two Choose*
methods should return randomly. However, not completly randomly, as that could make for very long games. Intead, have ChooseReplace
follow a two-step process:
Game
Game()
: constructor, to setup all the necessary objectsPlay
: main loop function that plays a complete gameCreate Unit Tests for all the Deck
and Hand
methods. The Player
methods would require much more complex, sample-based testing to see if they are making reasonable moves (spoiler: they're not) and the Game
methods require interactive testing, which is beyond the scope of unit testing.
Remember that in Visual Studio 2017, you must choose a .Net Framework project rather than .Net Core. Otherwise you won't have access to the unit test tools.
When you run your main
program, it should play out a complete game between two random bots. After each turn, print the two hands to the console, like this (note Jk is Joker, and the 5 of Hearts is the discard):
==================== 2D 7H XX XX 7S JC QC XX XX ---> 5H 4H XX XX XX Jk AS 3D XX XX ====================
At the end of the game, display the final scores.
As with the GUI assignment, you'll need to commit the whole solution here. That means both project subdirectories! Please delete the obj
and bin
directories from both. VS2017 additionally creates frameworks subdirectories which should also not be committed (if you can't find them, don't worry about it this time).