mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-26 04:41:52 -08:00
Fill out javadoc
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user