/Blackjack

Blackjack in Kotlin

Primary LanguageKotlinMIT LicenseMIT

Blackjack

Implementation of Blackjack in Kotlin for CS 591 D1

How to run

In IntelliJ, simply run the Blackjack.kt file. To run in command line, run java -jar out/artifacts/Blackjack_jar/Blackjack.jar.

Object Design Specification

Blackjack

Contains main game logic. Uses the following global variables:

players // List of Player and Dealer
playerBusted // Did the player bust this round
dealerBusted // Did the dealer bust this round
bet // Player's bet

Implements the following functions:
main: Main game loop. Runs initPlayers then a loop of runRound until the game is over.

initPlayers: Prompts for number of players. If 1, creates an AI Dealer, if 2, creates a playable Dealer (the other player is the normal Player).

runRound: Controls a round of gameplay. Resets the hands of the Player and Dealer and creates a new Deck. Then prompts user for their bet and deals cards to Player and Dealer. Then shows the Player the Dealer's first card, and runs the following in order: runPlayerTurn, runDealerTurn, and compareHands.

runPlayerTurn: Biggest function, controls logic of Player turn. Creates an iterator on the Player's hands (plural because of the case where Player splits a hand), and runs an input loop on each hand. For each hand, the player is shown their hand and their value, and prompted to 1. Hit, 2. Stand, 3. Split, 4. Double Up, or 5. Quit. Those options are implemented according to the assignment handout. Only thing of note is the fact that hands are looped over using an iterator, allowing new hands (in case of a split) to be added into the iterator while in the process of iterating. After player has made choices for each hand, a loop checks to make sure not all hands have busted (in which case we don't have to bother running the Dealer turn). If at least one hand didn't bust, set playerBusted to false and continue.

runDealerTurn: Runs the Dealer logic. If Dealer is an AI, just run the autoRunTurn function in the Dealer class. Else, present options similar to the player: 1. Hit, 2. Stand, 3. Quit. They are implemented according to the assignment handout. If the dealer doesn't bust, make sure dealerBusted is false and continue.

compareHands: Compares Player hands to the Dealer's and awards bets as required. If a Player hand is greater, the Player gets double the bet money for that hand. If it's worse, the Player loses the bet money for that hand. If it's a draw, nothing happens.

Card

Keeps track of data for individual cards. Has the following private instance variables (required in constructor):

suit // String of suit name
numVal // int of card value (0 - 12)

Has the following static class variables:

suits // Arrays of possible suits (Strings)
readableNames // Array of readable names (card values are stored as ints)

Implements the following functions:
getNumVal: Returns the value of the private numVal

equals: Helper to compare two cards (checks equality of card's numVal)

toString: Prints card in form "Value of Suit", e.g. "Ace of Hearts"

Hand

Keeps track of a particular hand, contains instances of the Card class. Takes in a Card optional in the constructor, which if exists will be added to the private list of cards. Has following private instance variables:

cards // List of cards in hand
value // Value of the hand, computed every time hand.value is called

On init, if a Card was passed to constructor, it is added to the cards list.

Implements the following functions:
add: Takes a Card and adds it to the cards list.

canSplit: Returns true if the Hand can be split (if only two cards are in the hand and they have the same numVal).

split: Returns a Pair of the two Cards in the Hand.

isNaturalBlackjack: Returns true if the Hand consists of only two Cards, an Ace and a face card.

toString: Override to allow direct printing of a Hand, in which each newline is a printed Card.

Deck

Keeps track of a deck of 52 cards. A new one is generated for each round in Blackjack.kt. Has an empty constructor, on init populates list of cards with a standard set of 52 cards and shuffles them. Maintains the following private instance variable:

cards // Mutable list of cards in the deck

Implements the following function:
draw: Takes the first (top) card of the deck, removes it from the deck, and returns it.

Player

Keeps track of the data each Player (and Dealer) needs. Has the following private instance variables (and uses an empty constructor):

money // Only needed for Player, once 0 game is over
hands // Mutable list of hands (since a player can split)
hand // Shorthand for first hand in list

Also has the following static class function:

printPlayerOptions // Prints the options for Players as described in the Blackjack class

Implements the following function:
resetHands: Clears the Player's hands and adds an empty Hand. Used when starting a new round.

Dealer

Extends the Player class with a constructor to set if computer controlled or not. Has no new private instance variables, but inherits those of Player. Has the following static class function:

printDealerOptions // Similar to the Player one, prints options as described in Blackjack class

Implements the following functions:
showFirstCard: Shows the first card of the Dealer hand (when the Player starts their turn).

getIsAI: Returns if the Dealer is computer controlled or not ( Blackjack uses this to decide whether to auto run turn).

autoRunTurn: Simply just "hits" until the Dealer's hand is equal to or greater than 17 (or if the Dealer busts).