Fill out javadoc

This commit is contained in:
Dave Burke
2022-03-05 09:47:15 -06:00
parent 926612b736
commit d6e0edb75f
3 changed files with 79 additions and 8 deletions

View File

@@ -4,6 +4,29 @@ import java.io.Reader;
import java.io.Writer;
import java.util.Collections;
/**
* Plays a game of blackjack on the terminal. Looking at the code, the reader
* might conclude that this implementation is "over engineered." We use many
* techniques and patterns developed for much larger code bases to create more
* maintainable code, which may not be as relevant for a simple game of
* Blackjack. To wit, the rules and requirements are not likely to ever change
* so there is not so much value making the code flexible.
*
* Nevertheless, this is meant to be an example that the reader can learn good
* Java coding techniques from. Furthermore, many of the "over-engineering"
* tactics are as much about testability as they are about maintainability.
* Imagine trying to manually test infrequent scenarios like Blackjack,
* insurance, or splitting without any ability to automate a specific scenario
* and the value of unit testing becomes immediately apparent.
*
* Another "unnecessary" aspect of this codebase is good Javadoc. Again, this is
* meant to be educational, but another often overlooked benefit is that most
* IDEs will display Javadoc in "autocomplete" suggestions. This is remarkably
* helpful when using a class as a quick reminder of what you coded earlier.
* This is true even if no one ever publishes or reads the HTML output of the
* javadoc.
*
*/
public class Blackjack {
public static void main(String[] args) {
// Intuitively it might seem like the main program logic should be right

View File

@@ -1,9 +1,11 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
/**
* This is the primary class that runs the game itself.
*/
public class Game {
private Deck deck;

View File

@@ -2,16 +2,18 @@ import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
// TODO fill out the javadoc for this class
/**
* Represents a player and data related to them (number, bets, cards).
*/
public class Player {
private int playerNumber; // e.g. playerNumber = 1 means "this is Player 1"
private double currentBet;
private double insuranceBet;
private double splitBet;
private double insuranceBet; // 0 when the player has not made an insurance bet (either it does not apply or they chose not to)
private double splitBet; // 0 whenever the hand is not split
private double total;
private LinkedList<Card> hand;
private LinkedList<Card> splitHand;
private LinkedList<Card> splitHand; // null whenever the hand is not split
/**
* Represents a player in the game with cards, bets, total and a playerNumber.
@@ -57,6 +59,7 @@ public class Player {
this.total = this.total + this.currentBet;
this.currentBet = 0;
}
/**
* RecordLoss subtracts 'currentBet' to 'total' and then sets 'currentBet' to zero
*/
@@ -65,29 +68,45 @@ public class Player {
currentBet = 0;
}
/**
* Adds 2x the insurance bet to the players total and resets the insurance bet to zero.
*/
public void recordInsuranceWin() {
total = total + (insuranceBet * 2);
insuranceBet = 0;
}
/**
* Subtracts the insurance bet from the players total and resets the insurance bet to zero.
*/
public void recordInsuranceLoss() {
total = total - insuranceBet;
insuranceBet = 0;
}
/**
* Returns the total of all bets won.
* Returns the total of all bets won/lost.
* @return Total value
*/
public double getTotal() {
return this.total;
}
// dealCard adds the given card to the player's hand
/**
* Add the given card to the players main hand.
*
* @param card The card to add.
*/
public void dealCard(Card card) {
dealCard(card, 1);
}
/**
* Adds the given card to the players hand or split hand depending on the handNumber.
*
* @param card The card to add
* @param handNumber 1 for the "first" hand and 2 for the "second" hand in a split hand scenario.
*/
public void dealCard(Card card, int handNumber) {
if(handNumber == 1) {
hand.add(card);
@@ -98,6 +117,10 @@ public class Player {
}
}
/**
* Determines whether the player is eligible to split.
* @return True if the player has not already split, and their hand is a pair. False otherwise.
*/
public boolean canSplit() {
if(isSplit()) {
// Can't split twice
@@ -108,6 +131,10 @@ public class Player {
}
}
/**
* Determines whether the player has already split their hand.
* @return false if splitHand is null, true otherwise.
*/
public boolean isSplit() {
return this.splitHand != null;
}
@@ -121,6 +148,12 @@ public class Player {
splitHand.add(hand.pop());
}
/**
* Determines whether the player can double down.
*
* @param handNumber
* @return
*/
public boolean canDoubleDown(int handNumber) {
if(handNumber == 1){
return this.hand.size() == 2;
@@ -131,6 +164,12 @@ public class Player {
}
}
/**
* Doubles down on the given hand. Specifically, this method doubles the bet for the given hand and deals the given card.
*
* @param card The card to deal
* @param handNumber The hand to deal to and double the bet for
*/
public void doubleDown(Card card, int handNumber) {
if(handNumber == 1){
this.currentBet = this.currentBet * 2;
@@ -142,7 +181,9 @@ public class Player {
this.dealCard(card, handNumber);
}
// resetHand resets 'hand' & 'splitHand' to empty lists
/**
* Resets the hand to an empty list and the splitHand to null.
*/
public void resetHand() {
this.hand = new LinkedList<>();
this.splitHand = null;
@@ -152,6 +193,11 @@ public class Player {
return getHand(1);
}
/**
* Returns the given hand
* @param handNumber 1 for the "first" of a split hand (or the main hand when there is no split) or 2 for the "second" hand of a split hand.
* @return The hand specified by handNumber
*/
public List<Card> getHand(int handNumber) {
if(handNumber == 1){
return Collections.unmodifiableList(this.hand);