How do i fix this simple program? guessing game - java

Hello please please please can someone help me. I am writing a program where the user can enter a maximum number for a guessing game and using a random generator he/she would have to guess the number from 1-to the max number. i have done most of it but i am stuck on how to loop back the program to enter another input if user say enters a letter or anything else apart from an integer. From the "do" part is where i get confused!
import java.util.ArrayList;
import java.util.Random;
import javax.swing.JOptionPane;
public class guessinggame { // class name
public static void main(String[] args) { // main method
String smax = JOptionPane.showInputDialog("Enter your maximum number for the Guessing Game:");
int max = Integer.parseInt(smax);
do {
if (max > 10000) {
JOptionPane.showMessageDialog(null, "Oh no! keep your choice below 10000 please.");
smax = JOptionPane.showInputDialog("Enter your maximum number for the Guessing Game:");
max = Integer.parseInt(smax);
}
} while (max > 10000);
int answer, guess = 0, lowcount = 0, highcount = 0, game;
String sguess;
Random generator = new Random();
answer = generator.nextInt(max) + 1;
ArrayList<String> buttonChoices = new ArrayList<String>(); // list of string arrays called buttonChoices
buttonChoices.add("1-" + max + " Guessing Game");
Object[] buttons = buttonChoices.toArray(); // turning the string arrays into objects called buttons
game = JOptionPane.showOptionDialog(null, "Play or Quit?", "Guessing Game",
JOptionPane.PLAIN_MESSAGE, JOptionPane.QUESTION_MESSAGE,
null, buttons, buttonChoices.get(0));
do {
sguess = JOptionPane.showInputDialog("I am thinking of a number between 1 and " + max + ". Have a guess:");
try {
guess = Integer.parseInt(sguess);
} catch (NumberFormatException nfe) {
JOptionPane.showMessageDialog(null, "That was not a number! ");
}
if (guess < answer) {
JOptionPane.showMessageDialog(null, "That is too LOW!");
lowcount++;
} else {
JOptionPane.showMessageDialog(null, "That is too HIGH!");
highcount++;
}
break;
} while (guess != answer);
JOptionPane.showMessageDialog(null, "Well Done!" + "\n---------------" + "\nThe answer was " + answer + "\nLow Guesses: " + lowcount
+ "\nHigh Guesses: " + highcount + "\n\nOverall you guessed: " + (lowcount + highcount) + " Times");
System.exit(0);
}
}

First thing's first, the break in the last do-while. If you break without condition inside a loop; it's not a loop; it's a single-execution block.
Other than that, you should, in areas where you're validating input, follow this structure. (pseudo code so you can implement).
Do-While input does not equal answer
Get input from user with dialogue
Begin Try
Parse user input
If input > answer
Notify user
Else-If input < answer
Notify user
End Try
Begin Catch Parse error
Alert user of invalid input
End Catch
End While

Related

How to combine if/else statement

Basically this program roles a dice between a computer and then shows who got the higher score. So in my last if/else statement, the main difference is you won, vs you lost. Is there anyway that I can combine this so it's cleaner? I tried combining it but couldn't figure it out. Any ideas? Appreciate it!!
//import scanner and random
import java.util.Random;
import java.util.Scanner;
//declare variables and methods
class Main {
int userOne, userTwo, compOne, compTwo, userTotal, compTotal;
char playAgain;
Scanner scan = new Scanner(System.in);
Random gen = new Random();
//method to run entire program
public void runProgram()
{
int r=1;
//this will run the roll of the dice for the user and the computer
for(r=1; r<2;)
{
System.out.println("Your turn:");
userOne = gen.nextInt(6)+1;
System.out.println("Your first roll was: " + userOne);
userTwo = gen.nextInt(6)+1;
System.out.println("Your second roll was: " + userTwo);
userTotal = userOne + userTwo;
System.out.println("Your total of the two rolls was: " + userTotal);
System.out.println("Computers turn:");
compOne = gen.nextInt(6)+1;
System.out.println("The computers first roll was: " + compOne);
compTwo = gen.nextInt(6)+1;
System.out.println("The computers second roll was: " + compTwo);
compTotal = compOne + compTwo;
System.out.println("The computers total of the two rolls was: " + compTotal);
//This determines win or loss and lets the user choose if they want to play again
if (userTotal > compTotal)
{
//winning- statement to ask if the user wants to play again
System.out.println("You won! Would you like to play again? Respond with Yes or No: ");
playAgain = scan.next().charAt(0);
if ((String.valueOf(playAgain)).equalsIgnoreCase("y") == true)
{
r=1;
}
else
{
r=2;
}
}
else
{
//losing- statement to ask if the user wants to play again
System.out.println("Sorry, you lost. Would you like to play again? Yes or No?");
playAgain = scan.next().charAt(0);
if ((String.valueOf(playAgain)).equalsIgnoreCase("y") == true)
{
r=1;
}
else
{
r=2;
}
}
}
}
public static void main(String[] args) {
Main prog = new Main();
prog.runProgram();
}
}
Yes, by moving the code responsible for determining whether or not to run the program again outside the if/else statement since it doesn't matter if the user won or lost, in the end, the question remains the same: do you want to play again or not? regardless of the result, therefore such logic should not be encapsulated by the logic responsible for determining who one (because again, irrelevant).
The second thing and this is totally optional but it will make your code cleaner, it seems you're using if/else statements just to determine which values should be assigned to variables, in such cases, it is cleaner to use the ternary operator
And one more thing, when using methods that return a boolean true/false it is unnecessary to type == false/true since the function itself already does that, such as the equalsIgnoreCase() function.
So after all of these edits, your code looks something like this:
//import scanner and random
import java.util.Random;
import java.util.Scanner;
//declare variables and methods
class Main {
int userOne, userTwo, compOne, compTwo, userTotal, compTotal;
char playAgain;
Scanner scan = new Scanner(System.in);
Random gen = new Random();
String result;
//method to run entire program
public void runProgram() {
int r=1;
//this will run the roll of the dice for the user and the computer
for(r=1; r<2;)
{
System.out.println("Your turn:");
userOne = gen.nextInt(6)+1;
System.out.println("Your first roll was: " + userOne);
userTwo = gen.nextInt(6)+1;
System.out.println("Your second roll was: " + userTwo);
userTotal = userOne + userTwo;
System.out.println("Your total of the two rolls was: " + userTotal);
System.out.println("Computers turn:");
compOne = gen.nextInt(6)+1;
System.out.println("The computers first roll was: " + compOne);
compTwo = gen.nextInt(6)+1;
System.out.println("The computers second roll was: " + compTwo);
compTotal = compOne + compTwo;
System.out.println("The computers total of the two rolls was: " + compTotal);
//This determines win or loss and lets the user choose if they want to play again
result = userTotal > compTotal ? "won! " : "lost. ";
// Ternary operator
System.out.println("you " + result + "Would you like to play again? Yes or No?");
playAgain = scan.next().charAt(0);
// another ternary operator
r = String.valueOf(playAgain).equalsIgnoreCase("y") ? 1 : 2;
}
}
public static void main(String[] args) {
Main prog = new Main();
prog.runProgram();
}
}
Like khelwood suggested, you can combine the play again messages outside of the win/loss if statement.
if (userTotal > compTotal) {
System.out.println("You won!");
} else {
System.out.println("Sorry, you lost.");
}
System.out.println("Would you like to play again? Yes or No?");
playAgain = scan.next().charAt(0);
if ((String.valueOf(playAgain)).equalsIgnoreCase("y")) {
r = 1;
} else {
r = 2;
}
One thing that I would say could be improved with this code is avoiding copying and pasting code. Don't ever repeat yourself.
Second thing to improve is you could make your loop while((String.valueOf(playAgain)).equalsIgnoreCase("y")) instead of your weird for loop. That way you don't have a confusing r variable that is based on whether or not playAgain is 'y'.
public void runProgram()
{
playAgain = 'y';
//this will run the roll of the dice for the user and the computer
while ((String.valueOf(playAgain)).equalsIgnoreCase("y") == true)
{
System.out.println("Your turn:");
userOne = gen.nextInt(6)+1;
System.out.println("Your first roll was: " + userOne);
userTwo = gen.nextInt(6)+1;
System.out.println("Your second roll was: " + userTwo);
userTotal = userOne + userTwo;
System.out.println("Your total of the two rolls was: " + userTotal);
System.out.println("Computers turn:");
compOne = gen.nextInt(6)+1;
System.out.println("The computers first roll was: " + compOne);
compTwo = gen.nextInt(6)+1;
System.out.println("The computers second roll was: " + compTwo);
compTotal = compOne + compTwo;
System.out.println("The computers total of the two rolls was: " + compTotal);
//This determines win or loss and lets the user choose if they want to play again
if (userTotal > compTotal)
{
//winning- statement to ask if the user wants to play again
System.out.println("You won! Would you like to play again? Respond with Yes or No: ");
}
else
{
//losing- statement to ask if the user wants to play again
System.out.println("Sorry, you lost. Would you like to play again? Yes or No?");
}
playAgain = scan.next().charAt(0);
}
}
Making these changes make your code a little more clear about what you're intending the program to do.
Just moves duplicated stuff out of the if-else statement.
Also, == true can be removed from if() since it already returns a boolean value.
if (userTotal > compTotal){
//winning- statement to ask if the user wants to play again
System.out.println("You won! Would you like to play again? Respond with Yes or No: ");
}else{
//losing- statement to ask if the user wants to play again
System.out.println("Sorry, you lost. Would you like to play again? Yes or No?");
}
playAgain = scan.next().charAt(0);
if ((String.valueOf(playAgain)).equalsIgnoreCase("y")){
r=1;
}else{
r=2;
}

why is my program displaying the array wrong?

I am having a problem with my program. When I compile and run my program everything runs great until it's time to display the guesses back to the user. when that happens the last guess always gets displayed as 0.
My assignment is to develop a program that simulates the high-low game. For each execution of the program, the game will generate a random number in the inclusive range of 1 to 100. The user will have up to 10 chances to guess the value. The program will keep track of all the user’s guesses in an array. For each guess, the program will tell the user if his/her guess was too high or too low. If the user is successful, the program will stop asking for guesses, display the list of guesses, and show a congratulatory message stating how many guesses he/she took. If the user does not guess the correct answer within 10 tries, the program will display the list of guesses and show him/her the correct value with a message stating that he/she was not successful. Regardless of the outcome, the program will give the user a chance to run the program again with a new random number.
This is what I have so far:
import java.util.Random;
import java.util.Scanner;
/**
*
* #author jose
*/
public class Assignment7
{
/*
*/
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
int number;
String again = "y";
while (again.equalsIgnoreCase("y"))
{
int[] guesses = new int[10];
int tries = 0;
number = GetRandomNumber(1, 100);
System.out.println(number); // delete before submitting
int userGuess = GetUserGuess(1,100);
while (userGuess != number && tries < guesses.length - 1 )
{
guesses[tries] = userGuess;
LowOrHigh(number, userGuess);
userGuess = GetUserGuess(1, 100);
tries++;
}
if (tries != 10)
{
userGuess = guesses[tries];
tries++;
System.out.println("Congratulations! You were able to guess the correct number");
}
else
{
System.out.println("Sorry! You were not able to guess the correct number");
}
if (tries == 10)
{
System.out.println("Your guesses were incorrect");
System.out.print("You guessed: ");
for ( int i = 0; i < 10 ; i++)
{
System.out.print(guesses[i] + ", ");
}
System.out.println("The random number generated was " + number);
}
else
{
System.out.println("Well done! You were able to guess the "
+ "correct number in under 10 tries");
System.out.print("You guessed: ");
for ( int i = 0; i < tries; i++)
{
System.out.print(guesses[i] + " ");
}
System.out.println("The random number generated was "
+ number + ", it only took you " + tries + " tries.");
}
System.out.println("");
System.out.print("Do you wish to try again with a different "
+ "number? (Enter y or n ): ");
again = input.next();
System.out.println("");
}
}
/*
METHOD 1
Description
A method that generates the random number to be guessed returns the
random number to main. Two parameters are the two numbers needed to generate
the random number (1 and 100 in this case).
*/
public static int GetRandomNumber (int rangeLow, int rangeHigh)
{
Random gen = new Random();
int number;
number = gen.nextInt(rangeHigh) + rangeLow;
return number;
}
/*
METHOD 2
This method tells the user if the guess is too low or too high. It will have
2 parameters one for the random number and the second is the user guess.
*/
public static void LowOrHigh (int number, int userGuess )
{
if (userGuess > number )
{
System.out.println("The value that you guessed is too high, "
+"Try guessing a lower number. ");
System.out.println("");
}
else if (userGuess < number )
{
System.out.println("The value that you guessed is too low, "
+"Try guessing a higher number. ");
System.out.println("");
}
}
/*
METHOD 3
This method will get the user guess. It has 2 parameters which will be the
valid range the user should guess between (in this case 1 and 100). It will
return the users guess as an integer. This method should validate that the
users guess is between the two parameters.
*/
public static int GetUserGuess(int rangeLow, int rangeHigh)
{
Scanner scan = new Scanner(System.in);
int userGuess;
System.out.print("Enter a number between " + rangeLow + " and " + rangeHigh + ": ");
userGuess = scan.nextInt();
while (userGuess > rangeHigh || userGuess < rangeLow)
{
System.out.println("The number given was not within the range, Try again ");
System.out.println("");
System.out.print("Enter a number between " + rangeLow + " and " + rangeHigh + ": ");
userGuess = scan.nextInt();
}
return userGuess;
}
}
I'm sorry if its obvious im still pretty new to programming.
Whenever you store a guess, you always store it in guesses[tries], and then immediately afterwards, you increment tries. Your while condition then checks if tries is less than guess.length - 1.
More generally, to program you need to know how to debug. Debugging is generally the act of following along with the code and checking what it actually does vs. what you wanted it to do. You can use a debugger for this, alternatively, you can add a boatload of System.out statements to follow along.
Do that, and you'll find the error in your logic. I've already given you quite a sizable hint in the first paragraph ;)

Stack Overflow on Random Integers

Where the commented section is, it says that there is a StackOverflowError - null. I am trying to get it to make random numbers to match up with an inputted value. The goal of this code is to do the following:
Accept a top number (ie 1000 in order to have a scale of (1-1000)).
Accept an input as the number for the computer to guess.
Computer randomly guesses the first number and checks to see if it is correct.
If it is not correct, it should go through a loop and randomly guess numbers, adding them to an ArrayList, until it guesses the input. It should check to see if the guess is already in the array and will generate another random number until it makes one that isn't in the list.
In the end, it will print out the amount of iterations with the count variable.
Code:
import java.util.*;
public class ArrNumGuess
{
public static Integer top, input, guess, count;
public static ArrayList <Integer> nums;
public static void main ()
{
System.out.println("Please enter the top number");
top = (new Scanner(System.in)).nextInt();
System.out.println("Please enter the number to guess (1 - " + top + ")");
input = Integer.parseInt(((new Scanner(System.in)).nextLine()).trim());
nums = new ArrayList<Integer>(); //use nums.contains(guess);
guess = (new Random()).nextInt(top) + 1;
nums.add(guess);
System.out.println("My first guess is " + guess);
count = 1;
if(guess != input)
{
guesser();
}
System.out.println("It took me " + count + " tries to find " + guess + " and " + input);
}
public static void guesser()
{
boolean check = false;
while(!check)
{
guess = (new Random()).nextInt(top) + 1; //Stack Overflow - null
if(nums.contains(guess) && !(guess.equals(input)))
{
count--;
guesser();
}
else if(guess.equals(input))
{
check = true;
System.out.println("My guess was " + guess);
// nums.add(guess);
count++;
}
else
{
System.out.println("My guess was " + guess);
nums.add(guess);
count++;
}
}
}
}
In guesser() method, you're invoking itself:
if(nums.contains(guess) && !(guess.equals(input)))
{
count--;
guesser();
}
There is quite a possibility it will never end. But all that is in while loop, so why not get rid of recurrence and do this in an iterative style?
OK - a different approach to your guesser for fun. Enumerate a randomized sequence of numbers in specified range (1 to 'top') and find the guess in the list whose index is effectively the number of "attempts" and return.
(BTW - #Andronicus answer is the correct one.)
/** Pass in 'guess' to find and 'top' limit of numbers and return number of guesses. */
public static int guesser(int guess, int top) {
List<Integer> myNums;
Collections.shuffle((myNums = IntStream.rangeClosed(1, top).boxed().collect(Collectors.toList())), new Random(System.currentTimeMillis()));
return myNums.indexOf(guess);
}
You are making it more complicated than it needs to be and introducing recursion unnecessarily. The recursion is the source of your stack overflow as it gets too deep before it "guesses" correctly.
There is a lot of sloppiness in there as well. Here's a cleaned up version:
import java.util.*;
public class Guess {
public static void main(String args[]) {
System.out.println("Please enter the top number");
Scanner scanner = new Scanner(System.in);
int top = scanner.nextInt();
System.out.println("Please enter the number to guess (1 - " + top + ")");
int input = scanner.nextInt();
if (input < 1 || input > top) {
System.out.println("That's not in range. Aborting.");
return;
}
ArrayList <Integer> nums = new ArrayList<>();
Random rng = new Random(System.currentTimeMillis());
while(true) {
int guess = rng.nextInt(top) + 1;
if (!nums.contains(guess)) {
nums.add(guess);
if (nums.size() == 1) {
System.out.println("My first guess is " + guess);
} else {
System.out.println("My guess was " + guess);
}
if (guess == input) {
System.out.println("It took me " + nums.size() + " tries to find " + guess);
break;
}
}
}
}
}

Why does my code exit and not accept the "yes" pulled in with a Scanner or the one hardcoded in? [duplicate]

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 5 years ago.
It looks like the Scanner is being used correctly here and being assigned to a variable correctly but I Cannot figure out what is going on. When I play this game in the code, the INT gets pulled in just fine. The strings will not get pulled in for some reason and even if I hardcode "yes" for the string it still exits the code.
package testTraining;
import java.util.Scanner;
public class GuessingGame {
static int gamesPlayed; // The number of games played.
static int gamesWon; // The number of games won.
public static void main(String[] args) {
gamesPlayed = 0;
gamesWon = 0; // This is actually redundant, since 0 is
// the default initial value.
System.out.println("Let's play a game. I'll pick a number between");
System.out.println("1 and 100, and you try to guess it.");
String yesno = "yes";
Scanner yesScan = new Scanner(System.in);
do {
playGame(); // call subroutine to play one game
System.out.print("Would you like to play again? ");
yesno = yesScan.next();
} while (yesno == "yes");
System.out.println();
System.out.println("You played " + gamesPlayed + " games,");
System.out.println("and you won " + gamesWon + " of those games.");
System.out.println("Thanks for playing. Goodbye.");
} // end of main()
static void playGame() {
Scanner guessScan = new Scanner(System.in);
int computersNumber; // A random number picked by the computer.
int usersGuess; // A number entered by user as a guess.
int guessCount; // Number of guesses the user has made.
gamesPlayed++; // Count this game.
computersNumber = (int)(100 * Math.random()) + 1;
// The value assigned to computersNumber is a randomly
// chosen integer between 1 and 100, inclusive.
guessCount = 0;
System.out.println();
System.out.print("What is your first guess? ");
while (true) {
usersGuess = guessScan.nextInt(); // Get the user's guess.
guessCount++;
if (usersGuess == computersNumber) {
System.out.println("You got it in " + guessCount
+ " guesses! My number was " + computersNumber);
gamesWon++; // Count this win.
break; // The game is over; the user has won.
}
if (guessCount == 6) {
System.out.println("You didn't get the number in 6 guesses.");
System.out.println("You lose. My number was " + computersNumber);
break; // The game is over; the user has lost.
}
// If we get to this point, the game continues.
// Tell the user if the guess was too high or too low.
if (usersGuess < computersNumber)
System.out.print("That's too low. Try again: ");
else if (usersGuess > computersNumber)
System.out.print("That's too high. Try again: ");
}
System.out.println();
} // end of playGame()
} // end of class GuessingGame
You need to compare strings with .equals("yes") instead of == "yes"

Converting JOptionPane input to integer

I'm trying to write a simple program that will ask for the user to enter a number in-between 1 and 10, then display the number. Now I have gotten part to work where if the number is outside of the range it asks again, but I can't seem to get it to ask again if anything aside from a number is inputted, such as % or hello.
The source code: (Cut out the top)
public static void main(String[] args){
int number; //For holding the number
String stringInput; //For holding the string values until converted
//------------------//
//Introducing the user
JOptionPane.showMessageDialog(null, "This is a program that will ask \n"
+ "you to enter a number in-between \n"
+ "1-10, if the number is not within \n"
+ "the parameters, the program will repeat.");
//---------------------//
//Get input from the user
stringInput = JOptionPane.showInputDialog("Enter number.");
number = Integer.parseInt(stringInput);
//-----------------//
//Checking the number
while (number > 10 || number < 0){
stringInput = JOptionPane.showInputDialog("That number is not within the \n"
+ "allowed range! Enter another number.");
number = Integer.parseInt(stringInput);
}
//-------------------//
//Displaying the number
JOptionPane.showMessageDialog(null, "The number you chose is "
+ number
+ ".");
//-------------//
//Closing it down
System.exit(0);
}
The main problem is the:
number = Integer.parseInt(stringInput);
I can't seem to convert the data values properly. I already thought of something like using an if statement to determine if the number is an integer, but I couldn't figure out how to check. I wish I could do:
if (number == Integer)
As you can see I am still extremely new to Java, any help is appreciated, thanks for taking the time to read.
You need to surround the call to Integer.parseInt() with a try/catch block to detect invalid input, like:
try {
number = Integer.parseInt(stringInput);
} catch (NumberFormatException e) {
// Not a number, display error message...
}
Here is a solution:
String errorMessage = "";
do {
// Show input dialog with current error message, if any
String stringInput = JOptionPane.showInputDialog(errorMessage + "Enter number.");
try {
int number = Integer.parseInt(stringInput);
if (number > 10 || number < 0) {
errorMessage = "That number is not within the \n" + "allowed range!\n";
} else {
JOptionPane
.showMessageDialog(null, "The number you chose is " + number + ".");
errorMessage = ""; // no more error
}
} catch (NumberFormatException e) {
// The typed text was not an integer
errorMessage = "The text you typed is not a number.\n";
}
} while (!errorMessage.isEmpty());
I'm trying to write a simple program that will ask for the user to
enter a number in-between 1 and 10
please to read Oracle tutorial How to use Dialogs - JOptionPane Features, then code should be very short and simple, without parsing an Integer from String
.
import java.awt.EventQueue;
import javax.swing.Icon;
import javax.swing.JOptionPane;
import javax.swing.UIManager;
public class MyOptionPane {
public MyOptionPane() {
Icon errorIcon = UIManager.getIcon("OptionPane.errorIcon");
Object[] possibilities = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
Integer i = (Integer) JOptionPane.showOptionDialog(null,
null, "ShowInputDialog",
JOptionPane.PLAIN_MESSAGE, 1, errorIcon, possibilities, 0);
// or
Integer ii = (Integer) JOptionPane.showInputDialog(null,
"Select number:\n\from JComboBox", "ShowInputDialog",
JOptionPane.PLAIN_MESSAGE, errorIcon, possibilities, "Numbers");
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
MyOptionPane mOP = new MyOptionPane();
}
});
}
}

Categories

Resources