Hey guys,
I am writing a program to play blackjack automatically. I am having trouble though with a while loop. For some reason, it just stops. It should be outputting, so it isn't even like it is stuck in an infinite loop. There are no errors either. My code and an example of the output are below. As far as I can tell, this happens when either it should hit or stay. Can someone help me out?
An example of the output I am getting (Obviously not running the 10 hands that it should)
How many hands would you like to run?
10
What would you like the base bet to be?
1
Current balance is: 1000
Player bets 1. Balance is now 999
0
1
Player has: Jack, 10 for a value of 20. Dealer shows 7
(18,5)
Player stays.
Dealer has 7, 7, 3 for 17
Player beat dealer.
Current balance is: 1001
Player bets 3. Balance is now 998
0
1
Player has: 10, 2 for a value of 12. Dealer shows 5
(0,3)
Player stays.
Dealer has 3, 5, 8, 3 for 19
Dealer beat player.
Current balance is: 998
Player bets 2. Balance is now 996
0
1
Player has: 3, 9 for a value of 12. Dealer shows Jack
(0,8)
Player hits.
2
Player has: 3, 9, 2 for a value of 14. Dealer shows Jack
(2,8)
Player hits.
3
The part that is not working (the while loop is the issue, not the for loop. just added the for loop in case it helps you see what it should do.)
for (int i = 0; i < hands.size(); i++) { if (i == 1) continue; int handIter = 0; while (true) { handIter++; System.out.println(handIter); p("Player has: " + hands.get(i) + " for a value of " + hands.get(i).getValue() + ". Dealer shows " + hands.get(1).getCard(1).getName()); if (hands.get(i).getValue() <= 21) { String action = actions.getAction(hands.get(i), hands.get(1)); if (action.equals("HIT")) { p("Player hits."); hands.get(i).addCard(deck.draw()); } else if (action.equals("STAY")) { p("Player stays."); break; } else if (action.equals("DOUBLE") && handIter == 1) { p("Player doubles."); if (bal - origBet >= 0) { bal -= origBet; bet += origBet; hands.get(i).addCard(deck.draw()); break; } else { hands.get(i).addCard(deck.draw()); } } else if (action.equals("SPLIT") && handIter == 1) { if (bal - origBet < 0) { p("Player is out of money!"); break game; } p("Player splits."); hands.add(new Hand()); hands.get(hands.size() - 1).addCard(hands.get(i).removeCard(1)); hands.get(hands.size() - 1).addCard(deck.draw()); hands.get(i).addCard(deck.draw()); handIter--; } } else { p("Player busts."); break; } } }
The full code
import java.util.ArrayList; import java.util.List; import java.util.Scanner; public class Blackjack { private static final int DECKS = 6; private static Scanner in = new Scanner(System.in); private static Actions actions = new Actions(); private static int bal = 1000; public static void main(String[] args) { Deck deck = new Deck(DECKS); List<Hand> hands; boolean playing = true; while(playing) { p("How many hands would you like to run?"); int ans = in.nextInt(); p("What would you like the base bet to be?"); int b = in.nextInt(); int[] bets = {(b * 1), (b * 3), (b * 2), (b * 6), (b * 3), (b * 4), (b * 5), (b * 6), (b * 7), (b * 8), (b * 9), (b * 10)}; int currBetPos = 0; //Begin automation game: for (int iter = 1; iter <= ans; iter++) { deck.shuffle(); hands = new ArrayList<Hand>(); p("Current balance is: " + bal); while (bal - bets[currBetPos] < 0) { currBetPos--; if (currBetPos < 0) break game; } int bet = bets[currBetPos++]; bal -= bet; p("Player bets " + bet + ". Balance is now " + bal); int origBet = bet; if (currBetPos > bets.length) currBetPos = 0; //Initial Deal Hand pHand = new Hand(); Hand dHand = new Hand(); pHand.addCard(deck.draw()); dHand.addCard(deck.draw()); pHand.addCard(deck.draw()); dHand.addCard(deck.draw()); hands.add(pHand); hands.add(dHand); //Play main player hand hands: for (int i = 0; i < hands.size(); i++) { if (i == 1) continue; int handIter = 0; while (true) { handIter++; System.out.println(handIter); p("Player has: " + hands.get(i) + " for a value of " + hands.get(i).getValue() + ". Dealer shows " + hands.get(1).getCard(1).getName()); if (hands.get(i).getValue() <= 21) { String action = actions.getAction(hands.get(i), hands.get(1)); if (action.equals("HIT")) { p("Player hits."); hands.get(i).addCard(deck.draw()); } else if (action.equals("STAY")) { p("Player stays."); break; } else if (action.equals("DOUBLE") && handIter == 1) { p("Player doubles."); if (bal - origBet >= 0) { bal -= origBet; bet += origBet; hands.get(i).addCard(deck.draw()); break; } else { hands.get(i).addCard(deck.draw()); } } else if (action.equals("SPLIT") && handIter == 1) { if (bal - origBet < 0) { p("Player is out of money!"); break game; } p("Player splits."); hands.add(new Hand()); hands.get(hands.size() - 1).addCard(hands.get(i).removeCard(1)); hands.get(hands.size() - 1).addCard(deck.draw()); hands.get(i).addCard(deck.draw()); handIter--; } } else { p("Player busts."); break; } } } //Play dealer hand while (true) { if (hands.get(1).getValue() < 17) { hands.get(1).addCard(deck.draw()); } else { break; } } p("Dealer has " + hands.get(1).toString() + " for " + hands.get(1).getValue()); //Check outcome for (int i = 0; i < hands.size(); i++) { if (i == 1) continue; if (hands.get(i).getValue() > 21) { p("You bust."); continue; } if (hands.get(1).checkBlackjack()) { if (hands.get(i).checkBlackjack()) { bal += origBet; p("Both had blackjack. Player pushes."); } } else if (hands.get(i).checkBlackjack()) { bal += origBet; bal += (origBet * 1.5); p("Player had blackjack."); } else if (hands.get(i).getValue() > hands.get(1).getValue()) { bal += (origBet * 2); p("Player beat dealer."); } else { p("Dealer beat player."); } } } } } private static void p(String s) { System.out.println(s); } private static void p(int s) { System.out.println(s); } }
And finally the rest of the classes:
Actions.java
public class Actions { private static final String[][] actions = { // 2 3 4 5 6 7 8 9 10 Ace /* 12 */{"HIT ", "HIT ", "STAY ", "STAY ", "STAY ", "HIT ", "HIT ", "HIT ", "HIT ", "HIT "}, //Index 0 /* 13 */{"STAY ", "STAY ", "STAY ", "STAY ", "STAY ", "HIT ", "HIT ", "HIT ", "HIT ", "HIT "}, /* 14 */{"STAY ", "STAY ", "STAY ", "STAY ", "STAY ", "HIT ", "HIT ", "HIT ", "HIT ", "HIT "}, /* 15 */{"STAY ", "STAY ", "STAY ", "STAY ", "STAY ", "HIT ", "HIT ", "HIT ", "HIT ", "HIT "}, /* 16 */{"STAY ", "STAY ", "STAY ", "STAY ", "STAY ", "HIT ", "HIT ", "HIT ", "HIT ", "HIT "}, /* 17 */{"STAY ", "STAY ", "STAY ", "STAY ", "STAY ", "STAY ", "STAY ", "STAY ", "STAY ", "STAY "}, /* 8 */{"HIT ", "HIT ", "HIT ", "HIT ", "HIT ", "HIT ", "HIT ", "HIT ", "HIT ", "HIT "}, //Index 6 /* 9 */{"HIT ", "DOUBLE", "DOUBLE", "DOUBLE", "DOUBLE", "HIT ", "HIT ", "HIT ", "HIT ", "HIT "}, /* 10 */{"DOUBLE", "DOUBLE", "DOUBLE", "DOUBLE", "DOUBLE", "DOUBLE", "DOUBLE", "DOUBLE", "HIT ", "HIT "}, /* 11 */{"DOUBLE", "DOUBLE", "DOUBLE", "DOUBLE", "DOUBLE", "DOUBLE", "DOUBLE", "DOUBLE", "DOUBLE", "HIT "}, /* 2 - 2 */{"SPLIT ", "SPLIT ", "SPLIT ", "SPLIT ", "SPLIT ", "SPLIT ", "HIT ", "HIT ", "HIT ", "HIT "}, //Index 10 /* 3 - 3 */{"SPLIT ", "SPLIT ", "SPLIT ", "SPLIT ", "SPLIT ", "SPLIT ", "HIT ", "HIT ", "HIT ", "HIT "}, /* 4 - 4 */{"HIT ", "HIT ", "HIT ", "SPLIT ", "SPLIT ", "HIT ", "HIT ", "HIT ", "HIT ", "HIT "}, /* 5 - 5 */{"DOUBLE", "DOUBLE", "DOUBLE", "DOUBLE", "DOUBLE", "DOUBLE", "DOUBLE", "DOUBLE", "HIT ", "HIT "}, /* 6 - 6 */{"SPLIT ", "SPLIT ", "SPLIT ", "SPLIT ", "SPLIT ", "HIT ", "HIT ", "HIT ", "HIT ", "HIT "}, /* 7 - 7 */{"SPLIT ", "SPLIT ", "SPLIT ", "SPLIT ", "SPLIT ", "SPLIT ", "HIT ", "HIT ", "HIT ", "HIT "}, /* 8 - 8 */{"SPLIT ", "SPLIT ", "SPLIT ", "SPLIT ", "SPLIT ", "SPLIT ", "SPLIT ", "SPLIT ", "SPLIT ", "SPLIT "}, /* 9 - 9 */{"SPLIT ", "SPLIT ", "SPLIT ", "SPLIT ", "SPLIT ", "STAY ", "SPLIT ", "SPLIT ", "STAY ", "STAY "}, /* 10 - 10 */{"STAY ", "STAY ", "STAY ", "STAY ", "STAY ", "STAY ", "STAY ", "STAY ", "STAY ", "STAY "}, /* A - A */{"SPLIT ", "SPLIT ", "SPLIT ", "SPLIT ", "SPLIT ", "SPLIT ", "SPLIT ", "SPLIT ", "SPLIT ", "SPLIT "}, /* A2 - A3 */{"HIT ", "HIT ", "HIT ", "DOUBLE", "DOUBLE", "HIT ", "HIT ", "HIT ", "HIT ", "HIT "}, //Index 20 /* A4 - A5 */{"HIT ", "HIT ", "DOUBLE", "DOUBLE", "DOUBLE", "HIT ", "HIT ", "HIT ", "HIT ", "HIT "}, /* A6 */{"HIT ", "DOUBLE", "DOUBLE", "DOUBLE", "DOUBLE", "HIT ", "HIT ", "HIT ", "HIT ", "HIT "}, /* A7 */{"STAY ", "DOUBLE", "DOUBLE", "DOUBLE", "DOUBLE", "STAY ", "STAY ", "HIT ", "HIT ", "HIT "}, /* A8 */{"STAY ", "STAY ", "STAY ", "STAY ", "STAY ", "STAY ", "STAY ", "STAY ", "STAY ", "STAY "}, /* A9 */{"STAY ", "STAY ", "STAY ", "STAY ", "STAY ", "STAY ", "STAY ", "STAY ", "STAY ", "STAY "} }; public static String getAction(Hand player, Hand dealer) { int playerIndex = 0; int dealerIndex = 0; //Find player index switch (player.getValue()) { case 12: playerIndex = 0; break; case 13: playerIndex = 1; break; case 14: playerIndex = 2; break; case 15: playerIndex = 3; break; case 16: playerIndex = 4; break; case 17: playerIndex = 5; break; case 8: playerIndex = 6; break; case 9: playerIndex = 7; break; case 10: playerIndex = 8; break; case 11: playerIndex = 9; break; } if (player.getValue() >= 17 && player.getValue() <=21) { playerIndex = 25; } if (player.getHandSize() == 2) { int plyrVal = player.getCard(0).getValue(); int plyrVal1 = player.getCard(1).getValue(); String plyrName = player.getCard(0).getName(); String plyrName1 = player.getCard(1).getName(); if (plyrVal == 2 && plyrVal1 == 2) { playerIndex = 10; } else if (plyrVal == 3 && plyrVal1 == 3) { playerIndex = 11; } else if (plyrVal == 4 && plyrVal1 == 4) { playerIndex = 12; } else if (plyrVal == 5 && plyrVal1 == 5) { playerIndex = 13; } else if (plyrVal == 6 && plyrVal1 == 6) { playerIndex = 14; } else if (plyrVal == 7 && plyrVal1 == 7) { playerIndex = 15; } else if (plyrVal == 8 && plyrVal1 == 8) { playerIndex = 16; } else if (plyrVal == 9 && plyrVal1 == 9) { playerIndex = 17; } else if (plyrVal == 10 && plyrVal1 == 10) { playerIndex = 18; } else if (plyrName.equals("Ace") && plyrName1.equals("Ace")) { playerIndex = 19; } else if ((plyrName.equals("Ace") && (plyrVal1 == 2 || plyrVal1 == 3)) || (plyrName1.equals("Ace") && (plyrVal == 2 || plyrVal == 3))) { playerIndex = 20; } else if ((plyrName.equals("Ace") && (plyrVal1 == 4 || plyrVal1 == 5)) || (plyrName1.equals("Ace") && (plyrVal == 4 || plyrVal == 5))) { playerIndex = 21; } else if ((plyrName.equals("Ace") && plyrVal1 == 6) || (plyrName1.equals("Ace") && plyrVal == 6)) { playerIndex = 22; } else if ((plyrName.equals("Ace") && plyrVal1 == 7) || (plyrName1.equals("Ace") && plyrVal == 7)) { playerIndex = 23; } else if ((plyrName.equals("Ace") && plyrVal1 == 8) || (plyrName1.equals("Ace") && plyrVal == 8)) { playerIndex = 24; } else if ((plyrName.equals("Ace") && plyrVal1 == 9) || (plyrName1.equals("Ace") && plyrVal == 9)) { playerIndex = 25; } } //Find dealer index if (dealer.getCard(1).getValue() == 2) { dealerIndex = 0; } else if (dealer.getCard(1).getValue() == 3) { dealerIndex = 1; } else if (dealer.getCard(1).getValue() == 4) { dealerIndex = 2; } else if (dealer.getCard(1).getValue() == 5) { dealerIndex = 3; } else if (dealer.getCard(1).getValue() == 6) { dealerIndex = 4; } else if (dealer.getCard(1).getValue() == 7) { dealerIndex = 5; } else if (dealer.getCard(1).getValue() == 8) { dealerIndex = 6; } else if (dealer.getCard(1).getValue() == 9) { dealerIndex = 7; } else if (dealer.getCard(1).getValue() == 10) { dealerIndex = 8; } else if (dealer.getCard(1).getName().equals("Ace")) { dealerIndex = 9; } System.out.println("(" + playerIndex + "," + dealerIndex + ")"); return actions[playerIndex][dealerIndex].trim(); } }
Card.java
public class Card { private String name; private int value; public Card(String n, int v) { name = n; value = v; } public String getName() { return name; } public int getValue() { return value; } public String toString() { return name; } }
Deck.java
import java.util.ArrayList; import java.util.Collections; import java.util.List; public class Deck { private List<Card> cards; private List<Card> cardsback = new ArrayList<Card>(); public Deck() { String names[] = {"Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King"}; for (int j = 0; j < names.length; j++) { int val = j + 1; if (val > 10) val = 10; if (names[j].equals("Ace")) val = 11; for (int k = 0; k < 4; k++) cardsback.add(new Card(names[j], val)); } shuffle(); } public Deck(int d) { String names[] = {"Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King"}; for (int i = 0; i < d; i++) { for (int j = 0; j < names.length; j++) { int val = j + 1; if (val > 10) val = 10; if (names[j].equals("Ace")) val = 11; Card c = new Card(names[j], val); for (int k = 0; k < 4; k++) cardsback.add(c); } } shuffle(); } public List<Card> getDeck() { return cards; } public void shuffle() { cards = new ArrayList<Card>(); cards.addAll(cardsback); Collections.shuffle(cards); } public Card draw() { Card c = new Card(cards.get(0).getName(), cards.get(0).getValue()); cards.remove(0); return c; } public String toString() { String s = ""; for (int i = 0; i < cards.size(); i++) { s = s + cards.get(i) + ", "; } s = s.substring(0, s.length() - 2); return s; } }
Hand.java
import java.util.ArrayList; public class Hand { private ArrayList<Card> cards; private int value; public Hand() { cards = new ArrayList<Card>(); } public Hand(Hand h) { cards.addAll(h.getHand()); getValue(); } public Hand(ArrayList c) { cards = c; } public Card removeCard(int index) { Card c = cards.get(index); cards.remove(index); return c; } public void addCard(Card c) { cards.add(c); value += c.getValue(); } public Card getCard(int pos) { return cards.get(pos); } public int getHandSize() { return cards.size(); } public int getValue() { int nv = 0; for (int i = 0; i < cards.size(); i++) { nv += cards.get(i).getValue(); } while (nv > 21) { checkAce(); } value = nv; return value; } public ArrayList getHand() { return cards; } public void checkAce() { for (int i = 0; i < cards.size(); i++) { if (cards.get(i).getName().equals("Ace")) { value -= 10; } } } public boolean checkBlackjack() { if (getHandSize() == 2 && getValue() == 21) { return true; } return false; } public String toString() { String s = ""; for (int i = 0; i < cards.size(); i++) { s = s + cards.get(i) + ", "; } s = s.substring(0, s.length() - 2); return s; } }