From d6e0edb75f29e58cc3775735db860afc7c4d9780 Mon Sep 17 00:00:00 2001 From: Dave Burke Date: Sat, 5 Mar 2022 09:47:15 -0600 Subject: [PATCH] Fill out javadoc --- 10_Blackjack/java/src/Blackjack.java | 23 +++++++++++ 10_Blackjack/java/src/Game.java | 4 +- 10_Blackjack/java/src/Player.java | 60 ++++++++++++++++++++++++---- 3 files changed, 79 insertions(+), 8 deletions(-) diff --git a/10_Blackjack/java/src/Blackjack.java b/10_Blackjack/java/src/Blackjack.java index bc8c2194..2809431e 100644 --- a/10_Blackjack/java/src/Blackjack.java +++ b/10_Blackjack/java/src/Blackjack.java @@ -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 diff --git a/10_Blackjack/java/src/Game.java b/10_Blackjack/java/src/Game.java index 1733ae96..4c90d9c5 100644 --- a/10_Blackjack/java/src/Game.java +++ b/10_Blackjack/java/src/Game.java @@ -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; diff --git a/10_Blackjack/java/src/Player.java b/10_Blackjack/java/src/Player.java index 699a4f69..0416ae8e 100644 --- a/10_Blackjack/java/src/Player.java +++ b/10_Blackjack/java/src/Player.java @@ -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 hand; - private LinkedList splitHand; + private LinkedList 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 getHand(int handNumber) { if(handNumber == 1){ return Collections.unmodifiableList(this.hand);