Problem statement
I have another thread on this, but I can't seem to locate it. Basically, I have a Black Jack game. The user is given two random cards (then those cards are added together, and display the total). Then it prompts user if they want another card (They pretty much will want to have a total lower than 21). If they choose "yes," they are given a random card number (they can keep getting a card, but should avoid going over 21), but if they choose "no," the game stops.
Here's the output I should get: [blackjackoutput.jpg]
And here's what I'm getting: [output1.jpg]
Source code:
public class BlackJackGame {
public static void main(String[] args) {
int randomnum1 = (int) (1 + Math.random() * 10);
int randomnum2 = (int) (1 + Math.random() * 10);
int total;
char anotherCard = 'y';
char playAgain;
Scanner input = new Scanner(System.in);
// Prints cards player starts off with
System.out.println("First cards: " + randomnum1 + ", " + randomnum2);
// Sum of the 2 cards
total = randomnum1 + randomnum2;
// Prints Total
System.out.println("Total: " + total);
// Do While Loop that asks question to get lower than 21 or terminate.
while (anotherCard != 'n') {
if (total <= 21) {
System.out.print("Do you want another card? (y/n): ");
anotherCard = input.next().charAt(0);
int randomnum3 = (int) (1 + Math.random() * 10);
System.out.println("Card: " + randomnum3);
total += randomnum3;
System.out.println("Total: " + total);
} else if (total > 21) {
System.out.println("BUST.");
System.out.print("Would you like to play again? (y/n): ");
playAgain = input.next().charAt(0);
}
}
}
}
Issue
When I reach to 21, I choose "no," to stop the program. But, it continues to display the next card and the updated total.
When I "BUST." (Or go over 21). It'll ask me if I want to play. And on separate occasions, I choose "y" and it says "Bust." and asks me if I want to play again (it loops, says "BUST.", and asks me the same question, without being able to end the program). Same thing if I choose "no" it'll say "Bust." and ask me if I can want to play again.
How do you play the game again?
PLEASE HELP!!!
The issue you have is a logic issue here:
if (total <= 21)
{
System.out.print("Do you want another card? (y/n): "); //<--------------
anotherCard = input.next().charAt(0);
int randomnum3 = (int) (1 + Math.random() * 10);
System.out.println("Card: " + randomnum3);
total += randomnum3;
System.out.println("Total: " + total);
You need to check if(anotherCard == 'n') to break out of the loop
Side Note
This blackjack game should have a better distribution of random cards better modeled off a 52 card deck
Related
import java.util.Scanner;
public class Blackjack {
class Commands {
static final String yes = "yes";
static final String no = "no";
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
//Opponent player2 = new Opponent();
double AiCard1 = 0;
double AiCard2 = 0;
double AiCard3 = 0;
double AiTotalcard3 = AiCard1 + AiCard2 + AiCard3;
double card1 = 0;
double card2 = 0;
double card3 = 0;
double card4 = 0;
double total2 = card1 + card2 + card3 + card4;
double total = card1 + card2 + card3;
System.out.println("Hello and Welcome to my custom version of blackjack!");
System.out.println("You will start off with $300");
System.out.println();
System.out.println("Do you want to read the rules before playing?");
System.out.print("Press 1 if yes, press 2 for no");
int choice = input.nextInt();
switch (choice) {
case 1:
System.out.println("You have 4 cards to get as close to 21 as possible. Whoever is closest to 21 wins");
break;
default:
break;
}
int balance = 300;
System.out.println("Your bank balance is $" + balance);
//user places a bet
System.out.println("Place a bet");
int bet = input.nextInt();
System.out.println("You placed a bet of " + bet);
//this is the AI
AiCard1 = Math.random() * 12 + 1;
AiCard1 = Math.round(AiCard1);
AiCard2 = Math.random() + 12 + 1;
AiCard2 = Math.round(AiCard2);
double AiTotal2cards = AiCard1 + AiCard2;
if(AiTotal2cards < 15) {
AiCard3 = Math.random() * 12 + 1;
AiCard3 = Math.round(AiCard3);
AiTotalcard3 = AiCard1 + AiCard2 + AiCard3;
}
card1 = Math.random() * 12 + 1;
card1 = Math.round(card1);
System.out.println("Your first card was a " + card1);
System.out.println();
card2 = Math.random() * 10 + 1;
card2 = Math.round(card2);
System.out.println("Your second card was a " + card2);
System.out.println();
System.out.println("Your cards add up to " + (card1 + card2));
System.out.println("Do you want to add another card?");
String answer = input.next();
here:
if(answer.equals(Commands.yes)) {
card3 = Math.random() * 12 + 1;
card3 = Math.round(card3);
System.out.println("Your third card was a " + card3);
System.out.println("Your cards add up to " + (card1 + card2 + card3));
total = card1 + card2 + card3;
if(total > 21) {
System.out.println("You lose");
break here;
}
System.out.println("Do you want to add another card?");
String answer1 = input.next();
if(answer1.equals(Commands.no)){
break here;
}
if(answer1.equals(Commands.yes)) {
card4 = Math.random() * 12 + 1;
card4 = Math.round(card4);
System.out.println("Your fourth card was a " + card4);
System.out.println("Your cards add up to " + (card1 + card2 + card3 + card4));
total2 = card1 + card2 + card3 + card4;
if(total2 > 21) {
System.out.println("You lose");
break here;
}
break here;
}
}
System.out.println("Your total cards were " + total2);
System.out.println("AI total cards were " + AiTotalcard3);
input.close();
}
}
When you run the program I was hoping that the variables at the top would have new numbers saved into them when the user went through the program. Is there a better way to do this because the console output is always 0 for the total.
First lets look at AiTotalcard3:
It shouldn't always output 0 for that, more precisely it will output 0 in the case where AiCard1 + AiCard2 >= 15, which probably happens a lot.
It makes sense if you trace through your actual code. The first thing that happens is those initializers:
double AiCard1 = 0;
double AiCard2 = 0;
double AiCard3 = 0;
double AiTotalcard3 = AiCard1 + AiCard2 + AiCard3;
So AiTotalcard3 is initially set to 0. It will remain 0 until you change it, which happens here:
AiCard1 = Math.random() * 12 + 1;
AiCard1 = Math.round(AiCard1);
AiCard2 = Math.random() + 12 + 1;
AiCard2 = Math.round(AiCard2);
double AiTotal2cards = AiCard1 + AiCard2;
if(AiTotal2cards < 15) {
AiCard3 = Math.random() * 12 + 1;
AiCard3 = Math.round(AiCard3);
AiTotalcard3 = AiCard1 + AiCard2 + AiCard3;
}
But that only happens if the first two cards add up to less than 15. After that you never touch AiTotalcard3 again.
Your logic can be greatly simplified all around, and also it makes a lot more sense to use int instead of double for the cards, but ignoring all that and sticking to your current style, you could fix this by making sure all paths set AiTotalcard3, for example (again not the cleanest logic but just sticking to your pattern):
if(AiTotal2cards < 15) {
AiCard3 = Math.random() * 12 + 1;
AiCard3 = Math.round(AiCard3);
AiTotalcard3 = AiCard1 + AiCard2 + AiCard3;
} else {
AiTotalcard3 = AiCard1 + AiCard2; // be sure to always set it
}
Now, with all that in mind, you have a similar problem with total2: Not all of your execution paths set the value of total2. It works if you make it up to the 4th card but prior to that you never change it from its initial value of 0. So you're just going to have to go through this with a fine-toothed comb.
One of your fundamental issues is for some reason you're using different variables all over the place for the first 2 cards vs. all the cards. If you just used a single aiTotal and total to accumulate the card totals as you go, you'd avoid most of these issues.
I think your main issue is confusing total and total2. You seem to use both interchangeable in multiple places.
At first, if the user does not pick a third card, total2 will always equal 0 because if the if(answer.equals(Commands.yes)) { is never entered, total2 is never set past the original initialization of 0.
If the user picks a third card but not a fourth, you update the value of total correctly but not total2.
If the user picks a fourth card, then it should work correctly.
Besides the main fixes, here are some tips that you should keep in mind when writing your game:
You mention that the global variables are not recognized, but none of your variables are actually global. You should read up on what exactly that means.
I would suggest using ints or a custom datatype to store card values, as you would never need the decimal places a double provides.
Use loops in your structure to save a lot of code. It will make it cleaner and easier to understand.
Print what the AI is doing. There's no point to having an AI if you can't see its moves.
Anyway, good luck with your game! Programming can be intimidating at first but this is a great start.
I am making a program called "count 21". How it's supposed to work is, "Two people play the game of Count 21 by taking turns entering a 1, 2, or 3, which is
added to a running total. The player who adds the value that makes the total exceed
21 loses the game. Create a game of Count 21 in which a player competes against the
computer, and program a strategy that always allows the computer to win. On any
turn, if the player enters a value other than 1, 2, or 3, force the player to reenter the
value."
I am having trouble figuring out how I should do this, this is what I have so far:
import javax.swing.JOptionPane;
import java.util.Scanner;
public class Count21 {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int x; //running total
int y; //input num
String strInput = "";
String message = "";
String answer = "";
do {
strInput = JOptionPane.showInputDialog(null, "Welcome to Count 21. \n In this game you will play against "
+ "the computer and add the numbers 1, 2, or 3 together. \n Whoever pushes the "
+ "numbers over 21 loses. \n Do you want to add 1, 2, or 3? "
+ "(please enter the number you choose.");
y = Integer.parseInt(strInput);
x++;
if (y == 1) {JOptionPane.showMessageDialog(null, "You chose the number 1."
+ " 1 will be added to the running total of" + (x + 1) +" .");
}
else if (y == 2) {JOptionPane.showMessageDialog (null, "You chose the number 2."
+ "2 will be added to the running total of" + (x + 2) + " .");
}
else if (y == 3) {JOptionPane.showMessageDialog (null, "You chose the number 3."
+ "3 will be added to the running total of" + (x + 3) + " .");
}
else{
JOptionPane.showMessageDialog(null, "You didn't type a valid number, please try again. \n");
}
} while (x > 21);
}
}
After the program runs and the user types in the number they chose the program ends. This is all I have so far, but I am stuck on how to keep the number's from the user adding until it reaches 21. I also am unsure of how to make the computer win the game. I think I should be using a for loop?
Any advice or comments are greatly appreciated. I apologize if my code or question is unclear.
As suggested in the comments, you shouldn't be incrementing xby one for each time a value is entered. This also causes further problems as when invalid numbers are entered it would still get incremented. Instead you should be checking the value of y and then adding the appropriate amount within the conditional logic (IF statement). This should also simplify the output messages contained within the logic, as you shouldn't need to add anything to x when printing it.
Again, as stated in the comments, the while condition should be x < 21.
I'm trying to create a blackjack game, where the player starts off with 2 cards, and then asked if he/she would like to have another card (user input: yes or no), if yes, another card is added to the total. if no, the game just terminates.
Here is a sample output I'm trying to get:
And this is what I have so far (It's probably wrong in terms of the placement):
import java.util.Scanner;
public class BlackJackGame {
public static void main(String[] args) {
int randomnum1 = (int) (1 + Math.random() * 10);
int randomnum2 = (int) (1 + Math.random() * 10);
int randomnum3 = (int) (1 + Math.random() * 10);
int total;
char anotherCard = 'y';
Scanner input = new Scanner(System.in);
System.out.println("First cards: " + randomnum1 + ", " + randomnum2);
total = randomnum1 + randomnum2;
System.out.println("Total: " + total);
while (anotherCard != 'n')
{
System.out.print("Card: " + randomnum3);
System.out.print("Do you want another card? (y/n): ");
anotherCard = input.next().charAt(0);
}
}
}
Tips and reworking the source code will be highly appreciated.
As Far as card games go, there are 52 cards in a deck, and I'm assuming there's one deck.
If you want it to be a fair game, then you have to keep that in mind.
But if you just want output to look correct, you just have to avoid getting more than 4 aces, 2's, 3's, and 4's.
One way to achieve this would be to make an int array of size 52 with 4 of each card. I suppose Ace would be 1 and 10,J,Q,K would be 10, so there would be 16 10's.
Get a random number between 0 and 51 to get the index of the array you want to use. Once you use that index, set the value of that array = -1, and always check for -1 before using that index, and if it is -1, get another random value.
int [] deck = size 52 array with 4 of each card.
int random = get random number between 0 and 51.
while(deck[random] == -1){
random = get random number between 0 and 51.
}
int card1 = deck[random]
deck[random] = -1;
something like that.. I just did that quickly, hopefully you get the idea.
Here are the tips you requested:
You need to introduce a variable to keep track of your sum. For example, you could initialize it with: int sum = randomnum1 + randomnum2; and keep adding the next card to it inside the loop: sum += randomnum3;
You need to generate randomnum3 inside the while loop. This way, you will get a different card every time. Basically, you have to call the random function every time you generate a card, not just once. Otherwise the value of randomnum3 will be unchanged and you will get the same card over and over.
To exit when you get to 21, you would have to use if and possibly break within the loop, once you have added the current card to the sum: if(sum > 21) { break; }
Alternatively, you can set the value of anotherCard to 'n' instead of using a break
You should keep track of which cards the user has already gotten if you want to simulate an actual deck. This is not technically necessary for the program you appear to be writing though.
Here are a few simple improvements for you to look over. I'll leave it like this as part of the joy of learning to program is in the discovery. As a next step I'd suggest generating a dealers hand and then seeing if the player can beat it. Good luck!
public static void main(String[] args) {
int card1 = (int) (1 + Math.random() * 10);
int card2 = (int) (1 + Math.random() * 10);
int total = card1 + card2;
System.out.println(String.format("First cards: %d & %d. Total %d", card1, card2, total));
System.out.println();
Scanner input = new Scanner(System.in);
System.out.print("Do you want another card? (y/n): ");
char anotherCard = input.next().charAt(0);
while (anotherCard != 'n' && total < 21) {
int nextcard = (int) (1 + Math.random() * 10);
total += nextcard;
System.out.println(String.format("You drew a %d. Your total is now %d", nextcard, total));
if (total > 21) {
System.out.println("You busted!");
} else {
System.out.print("Do you want another card? (y/n): ");
anotherCard = input.next().charAt(0);
}
}
}
I have a problem with my dealerhand method in my blackjack game.
I have a method to produce a random card from the class deck.
The cards have assigned values to them and so forth.
however the problem lies in the code where i want the dealer to draw a new card, and add the value to the existing total hand value. the code is a following.
//Basics for the values of dealers cards
int dealerHandValue = 0;
int tempDealerHandValue = 0;
int totalDealerHandValue= 0;
//Dealers first card
randomGenNum = (int)((range * Math.random()) + 1)*2;
dealerHandValue = arrayCardRank[randomGenNum];
CardSuit = arrayCardSuit[randomGenNum];
System.out.println("Dealer First Card Shows : " + (CardSuit));
tempDealerHandValue = dealerHandValue;
//Code executed when player stops drawing and stands.
while (totalDealerHandValue < 18 && totalDealerHandValue <21)
{
randomGenNum = (int)((range * Math.random()) + 1)*2;
dealerHandValue = arrayCardRank[randomGenNum];
CardSuit = arrayCardSuit[randomGenNum];
System.out.println("Dealer next Card Shows : " + (CardSuit));
tempDealerHandValue = dealerHandValue;
totalDealerHandValue = (tempDealerHandValue) + (dealerHandValue);
System.out.println("Dealer total hand value is " + (totalDealerHandValue));
}
{
System.out.println("Dealer stopped drawing");
if (totalDealerHandValue >= totalUserHandValue)
{
System.out.println("Dealer wins");
return;
}
else
System.out.println("Congratulations! You Win!");
return;
}
This method will just add the new cards value to itself, on and on until the while statement ends.
i have gone blind on the problem, and i know it is easily fixed.
can anyone help me towards what i am missing?
you're never incrementing totalDealerHandValue, just overwriting the value over and over again.
Replace these two lines:
tempDealerHandValue = dealerHandValue;
totalDealerHandValue = (tempDealerHandValue) + (dealerHandValue);
with
totalDealerHandValue += dealerHandValue;
I have an application a number guess game, users have to guess a number between 0 and 100, when they guess right the program asks them if they would like to play again when their done play I display the least number of guesses in a game and the greatest number of guess in a game. Right now all i get is the sum of all their guesses in the when using the "Math.min(,)"?
How do I get the minimum function to work??? the function code is in further below.
leastNumGuesses = Math.min(leastNumGuesses,guesses);
double rightNum = Math.random() *100;
int randomNum = (int) rightNum; //convert the random number to int
int tries = 0; //single game gussess output
int numberOfGames = 0;
int allTries = 0; //accumalates all tries(sum of all tries)
int guesses = 0; // guesses of all games combined
int gameGuesses = 0;
int leastNumGuesses = 100;
int mostNumGuesses = 0;
while (choice.equalsIgnoreCase("y"))
{
System.out.println();
int guess = getIntWithinRange(sc,"Enter the Number: ", 0, 100);
tries++;
guesses++;
gameGuesses++;
if (guess == randomNum)
{
numberOfGames++;
System.out.println("You got it in " + tries + " tries.");
leastNumGuesses = Math.min(leastNumGuesses,gameGuesses);
if (tries <=3)
System.out.println("Great work! You are a mathematical wizard.");
else if (tries > 3 && tries <= 7)
System.out.println("Not too bad! You've got some potential.");
else if (tries > 7)
System.out.println("What took you so long? Maybe you should take some lessons.");
System.out.println();
System.out.println("Would you like to play again (y/n):");
choice = sc.nextLine();
while (!choice.equalsIgnoreCase("n") && !choice.equalsIgnoreCase("y"))
{
System.out.println("Error! entry must be \"y\" or \"n\".");
System.out.println("Would you like to play again (y/n):");
choice = sc.nextLine();
}
if (choice.equalsIgnoreCase("y"))
{ // reset the random number & tries
rightNum = Math.random() *100;
randomNum = (int) rightNum;
tries=0;
gameGuesses++;
}
else if (choice.equalsIgnoreCase("n"))
{
allTries += guesses;
int averageNumGuess = allTries / numberOfGames;
System.out.println("Bye - Come back again");
System.out.println("Number of Games Played: " + numberOfGames);
System.out.println("Average Number of Guesses: " + averageNumGuess);
System.out.println("Least Amount of Guesses In a Single Game: " + leastNumGuesses);
}
}
It seems that you're changing what you want guesses to stand for in the middle of the program.
Remember that guesses is the total number of guesses over all games played, and that leastNumGuesses is initially set to 100. In most cases, you will find that guesses < leastNumGuesses, and thus the Math.min(guesses, leastNumGuesses) function will return guesses.
To fix: use variable other than guesses, for example, gameGuesses to keep track of how many guesses were made in a game. Then, Math.min(,) will behave as you expect.