patternjavaMinor
Second attempt at a Blackjack game
Viewed 0 times
gameblackjacksecondattempt
Problem
I posted yesterday about my first attempt at a Blackjack game. After I received much helpful advice I tried my best to fix up my code. I was wondering what you would think about round two!
Edit: I also wanted to implement the ability to split a hand if you have two of the same card. My User class already has a split method that adds another hand; what do you think would be the best way to go about adding this feature?
Card
Deck
Hand
```
package Blackjack;
import java.util.ArrayList;
import java.util.Arrays;
class Hand {
private ArrayList ha
Edit: I also wanted to implement the ability to split a hand if you have two of the same card. My User class already has a split method that adds another hand; what do you think would be the best way to go about adding this feature?
Card
package Blackjack;
class Card {
private final int rank;
private final int suit;
private static String[] ranks = { "Joker", "Ace", "Two", "Three", "Four",
"Five", "Six", "Seven", "Eight", "Nine", "Ten", "Jack", "Queen",
"King" };
private static String[] suits = { "Clubs", "Diamonds", "Hearts", "Spades" };
Card(int suit, int values) {
this.rank = values;
this.suit = suit;
}
public String toString() {
return ranks[rank] + " of " + suits[suit];
}
public int getRank() {
return rank;
}
public int getSuit() {
return suit;
}
public int getValue() {
int value=0;
if (rank > 10) {
value = 10;
} else if (rank == 1) {
value = 11;
} else {
value = rank;
}
return value;
}
}Deck
package Blackjack;
import java.util.ArrayList;
import java.util.Random;
class Deck {
private ArrayList deck;
Deck() {
deck = new ArrayList();
for (int i = 0; i < 4; i++) {
for (int j = 1; j <= 13; j++) {
deck.add(new Card(i, j));
}
}
}
public void shuffle() {
Random random = new Random();
Card temp;
for (int i = 0; i < 200; i++) {
int index1 = random.nextInt(deck.size() - 1);
int index2 = random.nextInt(deck.size() - 1);
temp = deck.get(index2);
deck.set(index2, deck.get(index1));
deck.set(index1, temp);
}
}
public Card drawCard() {
return deck.remove(0);
}
}Hand
```
package Blackjack;
import java.util.ArrayList;
import java.util.Arrays;
class Hand {
private ArrayList ha
Solution
Structure
Your structure is a lot better. There are a couple of things I would do differently, but generally it's good.
Arrays and Lists
I noted this last time, but as you still convert lists to arrays, I think maybe you don't know how to handle lists on their own?
Generally - if you don't have a good reason to do it differently-, you should stick with the collection you have. If it's an array, handle the array. If it's a list, handle the list.
Eg this:
Can be rewritten without the array like this:
Personally, I would handle the value counting in
You do the same conversion from list to array in a couple of other places as well. Eg this:
could be this:
Same in
Naming
Misc
Your structure is a lot better. There are a couple of things I would do differently, but generally it's good.
- a
Handdoesn't really need a deck, just a card (it makes more logical sense, I think).
- I think you have many
Hands inPlayerbecause of splitting? That makes sense. But yourhasBlackJacketc methods only handle the first hand, so that makes it useless. I would probably move those check methods directly intoHand.
- I would let
choiceisHitreturn aActionenum, which could beHit,Stay,Split, etc. This will make it a lot easier to add other actions later on (double, split, surrender, etc).
- your main method is too long, it's really hard to find the pieces you are interested in, which will make it really hard to change it or extend it. I would at least create a method for one round of blackjack and one method for the setup at the beginning.
Arrays and Lists
I noted this last time, but as you still convert lists to arrays, I think maybe you don't know how to handle lists on their own?
Generally - if you don't have a good reason to do it differently-, you should stick with the collection you have. If it's an array, handle the array. If it's a list, handle the list.
Eg this:
for (int i = 0; i 0 && handValue > 21) {
handValue -= 10;
aceCounter--;
}
}Can be rewritten without the array like this:
for (int i = 0; i 0 && handValue > 21) {
handValue -= 10;
aceCounter--;
}
}Personally, I would handle the value counting in
getHandValue on the fly, to avoid the trouble with the aces and the duplication in Hand and Hit (you could also avoid this by just calling Hit twice in your constructor).You do the same conversion from list to array in a couple of other places as well. Eg this:
public Card getCard(int cardnum) {
Card[] aHand = new Card[]{};
aHand = hand.toArray(aHand);
return aHand[cardnum-1];
}could be this:
public Card getCard(int cardnum) {
return hand.get(cardnum);
}Same in
toString, hasBlackJack, hasBusted, etc.Naming
- your naming isn't always consistent. Eg
getNewHandreturns nothing, whilegetHandreturns a hand.getNewHandshould probably be something likedealHand.
choiceIsYesretrieves user input, whileisyesornodoes not. I would use thegetXnaming pattern you used for the other methods here.
- always use camelCase (see eg
ishitorstand).
- again, methods should start with a lower-case character, so they are not confused with classes/constructors.
Misc
- in
drawCardyou do not check if there is still a card left, which will lead to a nullpointer exception when there aren't.
- you still have your
shufflemethod which can be replaced byCollections.shuffle(deck);.
Code Snippets
for (int i = 0; i < 2; i++) {
hand.add(deck.drawCard());
}
Card[] aHand = new Card[]{};
aHand = hand.toArray(aHand);
for (int i = 0; i < aHand.length; i++) {
handValue += aHand[i].getValue();
if (aHand[i].getValue() == 11) {
aceCounter++;
}
while (aceCounter > 0 && handValue > 21) {
handValue -= 10;
aceCounter--;
}
}for (int i = 0; i < 2; i++) {
hand.add(deck.drawCard());
}
for (Card card : hand) {
handValue += card.getValue();
if (card.getValue() == 11) {
aceCounter++;
}
while (aceCounter > 0 && handValue > 21) {
handValue -= 10;
aceCounter--;
}
}public Card getCard(int cardnum) {
Card[] aHand = new Card[]{};
aHand = hand.toArray(aHand);
return aHand[cardnum-1];
}public Card getCard(int cardnum) {
return hand.get(cardnum);
}Context
StackExchange Code Review Q#92703, answer score: 3
Revisions (0)
No revisions yet.