# Blackjack odds calculator

I'm working on getting switch and if statements down and I came up with this. It works well and I don't have any problems with it running properly. I was wondering if I could get some feedback on how I put it together. If there are things I am doing wrong or could do better, I'm very open to suggestions!

public static void main(String[] args) {

double edge = 0;

Scanner sc = new Scanner(System.in);

System.out.println("Enter the name of your Casino.");
String casino = sc.nextLine();

System.out.println("How many decks? (1, 2, 4, 6, 8)");
int decks = sc.nextInt();
System.out.println("Dealer hits Soft 17 (1 for Yes; 2 or No)");
int soft17 = sc.nextInt();
System.out.println("Double after Splits Allowed (1 for Yes; 2 or No)");
int doubleAfterSplit = sc.nextInt();
System.out.println("Double 10/11 Only (1 for Yes; 2 or No)");
int double1011 = sc.nextInt();
System.out.println("Double 9/10/11 Only (1 for Yes; 2 or No)");
int double91011 = sc.nextInt();
System.out.println("Resplit Aces (1 for Yes; 2 or No)");
int rSA = sc.nextInt();
System.out.println("Late Surrender (1 for Yes; 2 or No)");
int lateSurrender = sc.nextInt();
System.out.println("Early Surrender (1 for Yes; 2 or No)");
int earlySurrender = sc.nextInt();
System.out.println("Lose All Doubles/Splits vs. Natural (1 for Yes; 2 or No)");
int loseAllDS = sc.nextInt();
sc.close();

//Number of Decks Option
if (decks == 1) {
edge += 0.01;
} else if (decks == 2) {
edge -= 0.32;
} else if (decks == 4) {
edge -= 0.49;
} else if (decks == 6) {
edge -= 0.54;
} else if (decks == 8) {
edge -= 0.57;
} else {
System.out.println("You made a mistake.  Start over.");
}

//Soft 17 Options
if (soft17 == 1) {
edge -= 0.20;
} else {
edge += 0;
}

//Double After Splits Option
if (doubleAfterSplit == 1) {
edge += 0.14;
} else {
edge += 0;
}

//Double 10 and 11 Only Option
if (double1011 == 1) {
edge -= 0.17;
} else {
edge += 0;
}

//Double 9, 10, and 11 Only Option
if (double91011 == 1) {
edge -= 0.08;
} else {
edge += 0;
}

//Resplit Aces Option
if (rSA == 1) {
edge += 0.08;
} else {
edge += 0;
}

//Late Surrender Option
if (lateSurrender == 1) {
edge += 0.08;
} else {
edge += 0;
}

//Early Surrender Option
if (earlySurrender == 1) {
edge += 0.65;
} else {
edge += 0;
}

//Lose on All Doubles and Splits vs Natural Option
if (loseAllDS == 1) {
edge -= 0.11;
} else {
edge += 0;
}

DecimalFormat newFormat = new DecimalFormat("#.##");
edge =  Double.valueOf(newFormat.format(edge));

System.out.print("At, " + casino + " ");
if (edge >= 0) {
} else {
}

}


}

edge += 0; doesn't do anything You can just remove it and the else branches where you do it.

The number of decks handling can be done with an array:

int[] deckEdge = new int[]{0, 0.01, -0.32, 0, -0.49, 0, -0.54, 0, -0.57};//insert 0 in invalid places;

edge += deckEdge[decks];


(there is a trick you can use here by dividing the number of decks by 2 to remove the inserted 0s but that is less readable and understandable)

The switch solution is perhaps the most straightforward setup for this though:

switch(decks){
case 1:
edge += 0.01;
break;
case 2:
edge -= 0.32;
break;
case 4:
edge -= 0.49;
break;
case 6:
edge -= 0.54;
break;
case 8:
edge -= 0.57;
break;
default:
System.out.println("You made a mistake.  Start over.");
return;//stop program;
}


You also just continue on when a wrong number of decks is specified. You can either use return to stop immediately (like in the above switch) or use a do...while loop while reading it:

do{
System.out.println("How many decks? (1, 2, 4, 6, 8)");
int decks = sc.nextInt();
}while(decks!=1 && decks!=2 && decks!=4 && decks!=6 && decks!=8);

• Your while loop should be all &&'s. – Robin Jan 29 '15 at 19:54

Additionally to the excellent answer from ratchet freak: Always encode data according to their meaning, don't use another type just because it seems more "convenient". E.g. variables like soft17 represent "yes/no" choices, so an appropriate type would be boolean - even if you "get" them as numbers:

boolean soft17 = (sc.nextInt() == 1);


If you decide later that strings would be a better input format, you can write...

boolean soft17 = sc.next().toLowerCase().equals("y");


... and nothing after this line needs to change.

Put the number of decks vs increment value in a Map instance and validate the return value.

Map<Integer, Float> deckMap = new HashMap<Integer, Float>;
deckMap.put(1, 0.01);
deckMap.put(2, -0.32);
deckMap.put(4, -0.49);
deckMap.put(6, -0.54);
deckMap.put(8, -0.57);

int numDecks = 0
do {
System.out.println("How many decks? (1, 2, 4, 6, 8)");
numDecks = sc.nextInt();
} while(!deckMap.containsKey(numDecks));

edge += deckMap.get(numDecks);


(I will leave it as an exercise for the reader to use the keyset to generate your list of acceptable values.)

Use a method to input the boolean values, and make decisions based on the method call. This will eliminate the numerous int's you are currently using. You can easily do error checking and allow for other accepted values this way (y or n, yes or no,...).

private boolean isEdgeChanged(String inputString) {
System.out.println(inputString +  " (1 for Yes; 2 or No)");
decision = sc.nextInt();
return (decision == 1);
}


Make the calls to this method and set the edge like this.

if (isEdgeChanged("Dealer hits Soft 17")) {
edge -= 0.2;
}

if (isEdgeChanged("Double after Splits Allowed")) {
edge += 0.14;
}


You can also pair the questions and their matching values in another structure and loop through them for added flexibility.