librejack

Blackjack clone written in java
git clone https://github.com/michaelneuper/librejack.git
README | Files | Log | Refs | LICENSE

commit 49b2fe73ca4fb648c3dba4d4da7bed8a3068004e
parent 8cf0ea6e3f11faf98bc97c9fadf9556988076548
Author: Michael Neuper <michael@michaelneuper.com>
Date:   Fri, 28 Apr 2023 14:00:29 +0200

Update javadoc source

Diffstat:
Msrc/controller/Controller.java | 50+++++++++++++++++++++++++++++++++++++++++++++-----
Msrc/controller/Hand.java | 23++++++++++++++++++-----
Msrc/controller/LoginController.java | 28++++++++++++++++++++--------
Msrc/model/Card.java | 58+++++++++++++++++++++++++++++++++++++++++++++++++++++++---
Msrc/model/Dealer.java | 23++++++++++++++++++++---
Msrc/model/Deck.java | 41+++++++++++++++++++++++++----------------
Msrc/model/Person.java | 50++++++++++++++++++++++++++++++++++++++------------
Msrc/model/Player.java | 17+++++++++++++----
Msrc/model/Statistics.java | 53++++++++++++++++++++++++++++-------------------------
9 files changed, 262 insertions(+), 81 deletions(-)

diff --git a/src/controller/Controller.java b/src/controller/Controller.java @@ -7,8 +7,14 @@ import model.Player; import model.Statistics; /** - - * Handles most of the game logic. + * <p> + * The Controller class is responsible for handling most of the game logic for a + * Blackjack game.</p> + * <p> + * It creates a new instance of the Dealer and Player classes, initializes the + * deck with a new shuffled and populated Deck object, and keeps track of the + * bet and balance of the player. It also keeps track of game statistics using a + * Statistics object.</p> * * @author Michael Neuper * <a href="mailto:michael@michaelneuper.com">michael@michaelneuper.com</a> @@ -23,7 +29,9 @@ public class Controller { private Statistics stats = new Statistics(); /** - * Controller Constructor: Initializes score to 0. + * Creates a new instance of the Controller class. Initializes the dealer + * and player, the deck and discarded decks, and the bet and balance of the + * player. The deck is also populated and shuffled. */ public Controller() { // create new dealer and player @@ -42,10 +50,21 @@ public class Controller { discarded = new Deck(); } + /** + * Gets the current player's bet. + * + * @return the current player's bet + */ public double getBet() { return bet; } + /** + * Sets the current player's bet. If it is greater than the total balance, + * an error is displayed. + * + * @param bet the bet amount + */ public void setBet(double bet) { if (bet < balance) { this.bet = bet; @@ -54,17 +73,32 @@ public class Controller { } } + /** + * Gets the current player's balance. + * + * @return the current player's balance + */ public double getBalance() { return balance; } + /** + * Sets the current player's balance. + * + * @param balance + */ public void setBalance(double balance) { this.balance = balance; } /** - * Handles logic for each round. - * + * <p> + * Starts a new round of the game.</p> + * <p> + * Discards the dealer and player hands to the discarded deck if there are + * no cards left, and reloads the deck from the discarded deck if there are + * fewer than four cards left. Deals two cards to the dealer and two cards + * to the player.</p> */ public void startRound() { @@ -87,6 +121,12 @@ public class Controller { } + /** + * Checks who wins the game and returns a message indicating the result. + * Increments game statistics for wins, losses, and pushes. + * + * @return a message indicating the result of the game + */ public String checkWhoWins() { // check if dealer has blackjack diff --git a/src/controller/Hand.java b/src/controller/Hand.java @@ -17,7 +17,7 @@ public class Hand { private ArrayList<Card> hand; /** - * Hand Constructor: Creates empty hand. + * Creates a new empty Hand object. */ public Hand() { hand = new ArrayList<Card>(); @@ -33,12 +33,11 @@ public class Hand { } /** - * Method to calculate the value of a hand. + * Calculates the value of a hand. * * @return value value of the hand */ public int calculateValue() { - int value = 0; // current total value int aceCount = 0; // number of aces @@ -63,20 +62,33 @@ public class Hand { return value; } + /** + * Gets the card at a specific index. + * + * @param i the index of the card or get + * @return the card at index i + */ public Card getCard(int i) { return hand.get(i); } /** - * Discards hand to deck. + * Discards the current hand and adds its cards to the specified discard + * deck. * - * @param discardDeck + * @param discardDeck the deck to which the current hand's cards will be + * added */ public void discardHandToDeck(Deck discardDeck) { discardDeck.addCards(hand); // copy cards from discardDeck hand.clear(); // clear the hand } + /** + * Returns a string representation of the current hand. + * + * @return a string representation of the current hand + */ @Override public String toString() { @@ -87,4 +99,5 @@ public class Hand { return ret; } + } diff --git a/src/controller/LoginController.java b/src/controller/LoginController.java @@ -6,7 +6,10 @@ import java.util.regex.Pattern; import javax.swing.JOptionPane; /** - * Controller for handling user login. + * <p> + * Controller for handling user login.</p> + * <p> + * Validates all login fields.</p> * * @author Michael Neuper * <a href="mailto:michael@michaelneuper.com">michael@michaelneuper.com</a> @@ -34,11 +37,16 @@ public class LoginController { /** * Determines whether a given email is a valid email format according to the - * following criteria: - The email must contain a username and a domain - * separated by an @ symbol. - The username may contain alphanumeric - * characters, underscores, plus signs, asterisks, and hyphens. - The domain - * must consist of one or more subdomains separated by periods, and end in a - * top-level domain (TLD) of two to seven letters. + * following criteria: + * <ul> + * <li>The email must contain a username and a domain separated by an @ + * symbol.</li> + * <li>The username may contain alphanumeric characters, underscores, plus + * signs, asterisks, and hyphens.</li> + * <li>The domain must consist of one or more subdomains separated by + * periods, and end in a top-level domain (TLD) of two to seven + * letters.</li> + * </ul> * * @param email the email to be validated * @return true if the email is a valid email format, false otherwise @@ -145,8 +153,12 @@ public class LoginController { /** * Checks the following conditions to determine whether a password is valid: - * - is at least 10 characters in length - has at least 1 special character. - * - has at least 1 number - has at least 1 uppercase and lowercase letter. + * <ul> + * <li>is at least 10 characters in length</li> + * <li>has at least 1 special character</li> + * <li>has at least 1 number</li> + * <li>has at least 1 uppercase and lowercase letter</li> + * </ul> * * @param password to be validated * @return true if password is valid, false otherwise diff --git a/src/model/Card.java b/src/model/Card.java @@ -1,7 +1,7 @@ package model; /** - * Represents a card and handles card operations. + * Represents a standard playing card and handles card operations. * * @author Michael Neuper * <a href="mailto:michael@michaelneuper.com">michael@michaelneuper.com</a> @@ -9,6 +9,9 @@ package model; public class Card { // TODO: change name to image + /** + * Represents the four possible suits in a standard playing card deck. + */ public enum Suit { CLUBS("Clubs"), @@ -18,15 +21,30 @@ public class Card { public String suitName; + /** + * Creates a new Suit object with the specified name. + * + * @param suitName the name of the suit + */ Suit(String suitName) { this.suitName = suitName; } + /** + * Returns the name of the suit as a string. + * + * @return the name of the suit + */ public String toString() { return suitName; } } + /** + * Represents the thirteen possible ranks in a standard playing card deck. + * + * Each rank has a name and a value. + */ public enum Rank { TWO("Two", 2), @@ -46,11 +64,23 @@ public class Card { String rankName; public int rankValue; + /** + * Creates a new Rank object with the specified name and value. + * + * @param rankName the name of the rank + * @param rankValue the value of the rank + */ Rank(String rankName, int rankValue) { this.rankName = rankName; this.rankValue = rankValue; } + /** + * Returns the name of the rank as a string. + * + * @return the name of the rank + */ + @Override public String toString() { return rankName; } @@ -60,7 +90,7 @@ public class Card { private Rank rank; /** - * Card Constructor: Creates a card given a suit and rank. + * Creates a new Card object with the specified suit and rank. * * @param suit Card suit * @param rank Card rank @@ -71,7 +101,7 @@ public class Card { } /** - * Card Constructor: Creates a new card as a copy of another card. + * Creates a new Card object as a copy of another Card object. * * @param card card to be added */ @@ -80,20 +110,42 @@ public class Card { this.rank = card.getRank(); } + /** + * Gets the value of the card. + * + * @return The value of the card. + */ public int getValue() { return this.rank.rankValue; } + /** + * Gets the suit of the card. + * + * @return The suit of the card. + */ public Suit getSuit() { return suit; } + /** + * Gets the rank of the card. + * + * @return The rank of the card. + */ public Rank getRank() { return rank; } + /** + * Returns a String representation of the Card object, including the rank + * and suit of the card, as well as its value in parentheses. + * + * @return a String representation of the Card object + */ @Override public String toString() { return "[" + rank + " of " + suit + "](" + this.getValue() + ")"; } + } diff --git a/src/model/Dealer.java b/src/model/Dealer.java @@ -1,8 +1,13 @@ package model; /** - * Handles dealer specific operations, such as drawing cards to 16 and standing - * on 17 or above. + * Represents a dealer in a card game and handles dealer-specific operations. + * + * <p> + * This class extends the {@link Person} class, which contains shared methods + * and properties between players and dealers.</p> + * + * @see Person * * @author Michael Neuper * <a href="mailto:michael@michaelneuper.com">michael@michaelneuper.com</a> @@ -10,17 +15,29 @@ package model; public class Dealer extends Person { /** - * Creates a new dealer. + * Creates a new dealer with the default name "Dealer". */ public Dealer() { super.setName("Dealer"); } + /** + * Returns a string representation of the dealer's first card in their hand. + * + * @return the first card in the dealer's hand as a String + */ public String printFirstHand() { return "" + super.getHand().getCard(0); } + /** + * Returns a string representation of the value of the dealer's first card + * in their hand. + * + * @return the value of the first card in the dealer's hand as a String + */ public String printFirstCardValue() { return "" + super.getHand().getCard(0).getValue(); } + } diff --git a/src/model/Deck.java b/src/model/Deck.java @@ -7,7 +7,13 @@ import model.Card.Rank; import model.Card.Suit; /** - * Holds multiple cards and performs operations such as shuffling the deck. + * <p> + * Holds multiple cards and performs operations such as shuffling the deck.</p> + * <p> + * This class is responsible for creating a deck, populating it with 52 cards, + * shuffling the deck, adding cards to the deck, removing a card from the deck, + * checking if the deck has any cards left, emptying the deck, and returning the + * deck's current size.</p> * * @author Michael Neuper * <a href="mailto:michael@michaelneuper.com">michael@michaelneuper.com</a> @@ -17,6 +23,7 @@ public class Deck { private ArrayList<Card> deck; // creates a "deck" of card objects /** + * * Deck constructor */ public Deck() { @@ -24,10 +31,10 @@ public class Deck { } /** + * * Populates empty deck with 52 cards by looping over each rank and value. */ public void populate() { - for (Suit cardSuit : Suit.values()) { for (Rank cardRank : Rank.values()) { // adds a new card to the deck @@ -37,13 +44,12 @@ public class Deck { } /** - * Shuffles deck. + * Shuffles deck using a temporary deck for storing cards in random order. */ public void shuffle() { - ArrayList<Card> shufDeck = new ArrayList<Card>(); // temporary deck for storing cards in random order - Random random = new Random(); // FIXME: use math method instead + Random random = new Random(); int randomCardIndex = 0; while (deck.size() > 0) { @@ -52,12 +58,11 @@ public class Deck { shufDeck.add(this.deck.get(randomCardIndex)); // add card to random index of temporary deck this.deck.remove(randomCardIndex); // remove card from original deck } - this.deck = shufDeck; } /** - * Method to add a card to the deck. + * Adds a card to the deck. * * @param inCard card the be added */ @@ -68,9 +73,9 @@ public class Deck { /** * Takes copy of first card from deck and removes card from deck. * - * @return cardToTake card that was removed + * @return the card that was removed */ - public Card takeCard() { // TODO: change take to draw + public Card takeCard() { Card cardToTake = new Card(deck.get(0)); deck.remove(0); @@ -80,15 +85,14 @@ public class Deck { /** * Makes sure the deck we're hitting from has cards in it. * - * @return true (if the deck has cards in) - * @return false (if the deck is empty) + * @return true if the deck has cards in or false if the deck is empty */ public boolean hasCards() { return deck.size() > 0; } /** - * Mehtod to empty the deck. + * Removes all Card objects from the deck. */ public void emptyDeck() { deck.clear(); @@ -114,7 +118,7 @@ public class Deck { /** * Take all cards from discarded deck and place them in this deck, shuffled. - * Clear the old deck + * Clear the old deck. * * @param discard the deck cards are coming from */ @@ -126,21 +130,26 @@ public class Deck { } /** - * @return deck.size() number of cards left in the deck. + * @return number of cards left in the deck. */ public int cardsLeft() { return deck.size(); } + /** + * Returns a String representation of the Deck object. The String contains a + * list of all the cards in the deck, with each card on a new line. + * + * @return a String representation of the Deck object + */ @Override public String toString() { - String ret = ""; // holds the string to return for (Card card : deck) { ret += card; ret += "\n"; } - return ret; } + } diff --git a/src/model/Person.java b/src/model/Person.java @@ -3,7 +3,14 @@ package model; import controller.Hand; /** - * Parent class of the Player and Dealer Objects. + * <p> + * Parent class of the Player and Dealer Objects.</p> + * <p> + * Contains information about a person in a blackjack game, such as their name + * and hand.</p> + * + * @see Player + * @see Dealer * * @author Michael Neuper * <a href="mailto:michael@michaelneuper.com">michael@michaelneuper.com</a> @@ -14,34 +21,53 @@ public abstract class Person { private String name; /** - * Creates a person. + * Creates a person with an empty hand and no name. */ public Person() { this.hand = new Hand(); this.name = ""; } + /** + * Returns the hand of the person. + * + * @return the hand of the person + */ public Hand getHand() { return hand; } + /** + * Sets the hand of the person. + * + * @param hand the hand to set + */ public void setHand(Hand hand) { this.hand = hand; } + /** + * Returns the name of the person. + * + * @return the name of the person + */ public String getName() { return name; } + /** + * Sets the name of the person. + * + * @param name the name to set + */ public void setName(String name) { this.name = name; } /** - * Checks if a person has blackjack. + * Checks if the person has blackjack. * - * @return true (if player has a blackjack) - * @return false (if player does not have a blackjack) + * @return true if the person has a blackjack, false otherwise */ public boolean hasBlackjack() { return this.getHand().calculateValue() == 21; @@ -49,25 +75,25 @@ public abstract class Person { /** * Prints a formatted version of the person's hand. + * + * @return a formatted string representing the person's hand */ public String printHand() { return this.hand + "[" + this.hand.calculateValue() + "]"; } /** - * Checks if deck has cards and reloads deck if it ran out. + * Draws a card from the deck and adds it to the person's hand. If the deck + * has no cards, the deck is reloaded from the discard pile. * - * @param deck deck to draw from - * @param discard deck to discard to + * @param deck the deck to draw from + * @param discard the discard pile to reload from if the deck is empty */ public void hit(Deck deck, Deck discard) { - - // if there are no cards left in the deck if (!deck.hasCards()) { deck.reloadDeckFromDiscard(discard); } - this.hand.takeCardFromDeck(deck); } - + } diff --git a/src/model/Player.java b/src/model/Player.java @@ -8,16 +8,24 @@ import java.io.PrintWriter; import java.util.Scanner; /** - * Represents a player in a Blackjack game. + * <p> + * Represents a player in a blackjack game. A player has a name and a hand of + * cards. They can take actions such as hitting, standing, and doubling down. + * They can also make bets and receive payouts.</p> + * + * <p> + * This class extends the {@link Person} class, which contains shared methods + * and properties between players and dealers.</p> + * + * @see Person * * @author Michael Neuper * <a href="mailto:michael@michaelneuper.com">michael@michaelneuper.com</a> */ public class Player extends Person { - private double balance; // Player's balance - private final String BALANCE_FILE = "db/balance.txt"; // File to store the player's balance - private Scanner input = new Scanner(System.in); + private double balance; // player's balance + private final String BALANCE_FILE = "db/balance.txt"; // file to store the player's balance /** * Creates a new player with a default name of "Player". @@ -59,4 +67,5 @@ public class Player extends Person { this.balance = balance; } + } diff --git a/src/model/Statistics.java b/src/model/Statistics.java @@ -9,12 +9,17 @@ import com.opencsv.CSVWriter; import com.opencsv.exceptions.CsvValidationException; /** + * <p> * The Statistics class represents a set of statistics for a blackjack game. - * Statistics are stored in a CSV file with the following format: - Column 1: - * number of wins - Column 2: number of losses - Column 3: number of pushes - * (ties) + * Statistics are stored in a CSV file with the following format: + * <ul> + * <li><b>Column 1:</b> number of wins</li> + * <li><b>Column 2:</b> number of losses</li> + * <li><b>Column 3:</b> number of pushes(ties)</li> + * </ul></p> * - * The file is named 'statistics.csv' and is stored in the 'db/' directory. + * <p> + * The file is named `statistics.csv` and is stored in the 'db/' directory.</p> * * @author Michael Neuper * <a href="mailto:michael@michaelneuper.com">michael@michaelneuper.com</a> @@ -38,7 +43,6 @@ public class Statistics { } /** - * * Constructs a new Statistics object with the given statistics. * * @param wins the number of wins @@ -52,7 +56,6 @@ public class Statistics { } /** - * * Gets the number of wins. * * @return wins number of wins @@ -62,7 +65,6 @@ public class Statistics { } /** - * * Gets the number of losses. * * @return losses number of losses @@ -72,7 +74,6 @@ public class Statistics { } /** - * * Gets the number of pushes (ties). * * @return pushes number of pushes @@ -82,7 +83,6 @@ public class Statistics { } /** - * * Sets the number of wins. * * @param wins the new number of wins @@ -92,7 +92,6 @@ public class Statistics { } /** - * * Sets the number of losses. * * @param losses the new number of losses @@ -112,7 +111,6 @@ public class Statistics { } /** - * * Increments the number of wins by 1 and saves the new statistics to the * CSV file. */ @@ -122,7 +120,6 @@ public class Statistics { } /** - * * Increments the number of losses by 1 and saves the new statistics to the * CSV file. */ @@ -132,7 +129,6 @@ public class Statistics { } /** - * * Increments the number of pushes (ties) by 1 and saves the new statistics * to the CSV file. */ @@ -142,12 +138,14 @@ public class Statistics { } /** - * + * <p> * This method saves the current statistics (number of wins, losses, and - * pushes) to a CSV file. The file path is defined by the CSV_FILE constant - * in the Statistics class. The method uses a CSVWriter object to write the - * data to the file. If an IOException occurs during the file writing - * process, it is caught and ignored. + * pushes) to a CSV_FILE file. The file path is defined by the CSV_FILE + * constant in the Statistics class.</p> + * <p> + * The method uses a CSVWriter object to write the data to the file. If an + * IOException occurs during the file writing process, it is caught and + * ignored.</p> */ private void save() { try (CSVWriter writer = new CSVWriter(new FileWriter(CSV_FILE))) { @@ -159,15 +157,19 @@ public class Statistics { } /** + * <p> * This static method loads the statistics from the CSV file located at the * path defined by the CSV_FILE constant in the Statistics class. The method - * uses a CSVReader object to read the data from the file. If the CSV file - * does not have the expected headers, an IOException is thrown. The method - * returns a Statistics object with the values read from the CSV file. If an - * IOException occurs during the file reading process, it is caught and - * ignored. If a CsvValidationException is thrown during the file reading - * process, it is handled internally and an empty Statistics object is - * returned. + * uses a CSVReader object to read the data from the file.</p> + * <p> + * If the CSV file does not have the expected headers, an IOException is + * thrown. The method returns a Statistics object with the values read from + * the CSV file.</p> + * <p> + * If an IOException occurs during the file reading process, it is caught + * and ignored. If a CsvValidationException is thrown during the file + * reading process, it is handled internally and an empty Statistics object + * is returned.</p> * * @return a Statistics object with the values read from the CSV file, or an * empty Statistics object if there was a problem with the CSV file format @@ -196,4 +198,5 @@ public class Statistics { } return stats; } + }