Guessing Game Help :) - java

Ok, so my computer teacher has asked us to make a simple game that asks the user to guess a radomly generated number, but I want to take it one step further and make it so that it display error messages when the user tries certain things. The problem here is that I am new to booleans and well, I am having a bit of trouble using java.util.Scanner and booleans. So, if anyone could take a quick look at this I would appreciate it.
import java.util.Scanner;
import java.util.Random;
public class MoreGuessing{
//Instantiation
Scanner reader = new Scanner(System.in);
Random number = new Random();
//Variables
int randomnumber = number.nextInt(10) + 1;
int cntr = 1;
static String decimalguessed;
String error1 = "Error001: Decimal found, please enter a whole number between 1-10." + "\n" + "Program terminated......";//Decimal portion error.
String error2 = "Please enter a positive number." + "\n" + "Program terminated......"; //Negative number error.
String error3 = "Unknown character entered." + "\n" + "Program terminated......"; //Unknown character error.
//Verifier
public static boolean verifyLetters() {
if (decimalguessed.matches("[a-zA-Z]+")){
return true;
}else{
return false;
}
}
public static void main(String [] args){
//Input and display
System.out.print("Please enter a whole number between 1-10: ");
decimalguessed = reader.nextLine();
//Process and Errors
while (decimalguessed != randomnumber) {
if (verifyLetters() != false){
System.out.println(error3);
System.exit(1);}
if (decimalguessed % 1 != 0) {
System.out.println(error1);
System.exit(1);}
if (decimalguessed < 0) {
System.out.println(error2);
System.exit(1);}
if (randomnumber != decimalguessed){
System.out.println("You've lost, please make another attempt.");}
System.out.print("Please enter a whole number between 1-10: ");
decimalguessed = reader.nextDouble();
cntr++;
}
if (cntr == 1) {System.out.println("Congratulations! You've guessed the number on your first attempt!");;
}
else {System.out.println("Congratulations! You've guessed the number, it took you " + cntr + " tries");}
}
}

You need to parse your input. decimalguessed is a string, and so you can't do comparisons like decimalguessed % 1.
You can convert it to an integer like this:
int guess = 0;
try {
guess = Integer.parseInt(decimalguessed);
} catch (NumberFormatException e) {
System.out.println("Your guess was not an integer: " + e.getMessage());
System.exit(1);
}
This will handle both cases where decimalguessed contains letters, and where it contains decimal points/fractions. decimalguessed is still a string, but guess now contains the integer version of it, so you can compare it to randomnumber properly. (Your loop would have never exited before, because a string is never == an integer)
Some other notes:
You should never have:
if (condition) {
return true;
} else {
return false;
}
This can always be simply replaced with
return condition;

It feels like you're very new to this. Welcome to programming!
So first, in Java generally you're not going to have all of that instantiation and variables stuff outside of your main function, unless you're going to make everything static. I would move all of that into your main function, un-static the decimalguessed variable and setup your verifyLetters function to take an argument of String decimalguessed. It may also be wise to check if the value is a number, rather than seeing if it is not a letter. There a lot of non-number, non-letter characters.
Once you've figured out that the guess is a number, you need to tell java it is one (cast it) to a decimal, then do you further comparisons against that decimal.
Darth Android also makes some good points, especially about booleans. You should never have the only result of an if/else be to return a boolean, just return the boolean. Also avoid comparisons to true/false, just do the if on the function/variable alone, or negate it with an '!' to check for false.
Good luck!

Related

Character.isDigit parameters and line unavailable errors within the isDigit method (clarification)

I'm currently working on a small project for an introductory java class. We're supposed to make a program which can take in an integer from the user and output the number of odds, evens, and zeroes present within the code. This seemed pretty easy to me, and I managed to implement the code, but a class mate, after I criticized his code for incorrectly following the prompt, noted that my code would crash if anything but digits was input.
Out of spite I've tried to go beyond the prompt and have the program output an error message if it encounters characters aside from digits (instead of having my compiler return an error). However I'm returning multiple errors within the Eclipse compiler when using the isDigit method in the Character class.
I don't know exactly what's causing this, and I feel I must be missing something crucial, but my teacher quite frankly isn't qualified enough to understand what's causing the error, and none of my classmates can seem to figure it out either.
package ppCH5;
import java.util.Scanner;
public class PP5_3
{
public static void main(String[]args)
{
int even = 0;
int odd = 0;
int zero = 0;
int num = 0;
int count = 0;
boolean inputError = false;
System.out.println("please provide some integer");
Scanner scan = new Scanner(System.in);
String numbers = scan.next();
scan.close();
Scanner intSeperate = new Scanner(numbers);
intSeperate.useDelimiter("");
while(intSeperate.hasNext())
{
if(Character.isDigit(numbers.charAt(count)))
{
count++;
num = intSeperate.nextInt();
if((num % 2)==1)
odd++;
if((num % 2)==0)
if(num==0)
zero++;
else
even++;
}
else
{
count++;
inputError = true;
}
}
intSeperate.close();
if(!inputError)
{
System.out.println("There are " + even + " even digits.\n" + odd + " odd digits.\nAnd there are " + zero + " zeros in that integer.");
}
else
{
System.out.println("You have provided a disallowed input");
}
}
}
Any help would be appreciated, I'm currently at a loss.
When you enter a single non-digit character, say a, the else branch inside the while loop will get executed, incrementing count, right? And then the loop will start a new iteration, right?
In this new iteration, intSeparator.hasNext() still returns true. Why? Because the input a is never read by the scanner (unlike if you have entered a digit, intSeparator.nextInt would be called and would have consumed the input).
Now count is 1 and is an invalid index for the 1-character string. Therefore, numbers.charAt(count) throws an exception.
This can be avoided if you break; out of the loop immediately in the else block:
else
{
inputError = true;
break;
}
Also, don't close the scan scanner. scan is connected to the System.in stream. You didn't open that stream, so don't close it yourself.

Wondering what is wrong with my code; it gets hung up on the while if loop

I've looked around and can't seem to find an answer as to what exactly the problem is. It executes fine up until the loop and then it seems to ignore the loop and gets hung up so I am rather confused.
package classGame;
import java.util.*;
public class GameTwo {
static int randomNumber;
static int numOfGuess = 5;
static Scanner GameTwo = new Scanner(System.in);
public static void main(String[] args) {
System.out.println("Frank: Hello there! My name is Frank. This is the introduction to the game.");
System.out.print("Frank: Please tell me what you would like to be called: ");
if(GameTwo.hasNextLine()) {
String userName =GameTwo.nextLine();
System.out.println(userName + ": My name is: " + userName);
System.out.println("Frank: Well " + userName + ", it's nice to meet you. ");
System.out.println("Frank: Lets play a little game, I want you to guess a number, It's already" +
" in my head and it's between 1-10.");
int guessResult = 1;
int randomGuess = 0;
while(guessResult != -1) {
randomGuess = GameTwo.nextInt();
guessResult = checkGuess(randomGuess);
}
while (randomGuess != guessResult) {
System.out.println(userName + ":Is the number: ");
randomGuess = GameTwo.nextInt();
if(randomGuess < 1 || randomGuess > 10 || randomGuess > guessResult || randomGuess < guessResult) {
System.out.println("Frank: Thats not right "+ userName);
} else if (randomGuess == guessResult) {
System.out.println("Frank: Hey...Thats pretty good...You got it!");
}
}
}
}
public static int getRandomNum () {
randomNumber = (int) (Math.random()*10);
return randomNumber;
}
public static int checkGuess(int guess) {
if(guess == randomNumber) {
return -1;
} else {
return guess;
}
}
}
here is what it prints out up to the loop
Frank: Hello there! My name is Frank. This is the introduction to the game.
Frank: Please tell me what you would like to be called: T
T: My name is: T
Frank: Well T, it's nice to meet you.
Frank: Lets play a little game, I want you to guess a number, It's already in my head and it's between 1-10.
I think this is an issue with how Scanner.nextInt() works. nextInt() takes in the next Integer found but it does not clear the buffer like nextLine() does.
See this link for more info about this issue: How does input.nextInt() work exactly?
Try this and see if your loop continues properly:
while(guessResult != -1) {
randomGuess = GameTwo.nextInt();
guessResult = checkGuess(randomGuess);
GameTwo.nextLine();
System.out.println("Random Guess: " + randomGuess); //Try here
}
I think the reason the loop is getting hung up is because nextInt() keeps finding the randomGuess number still in the input buffer and executing over and over again. To test that, simply put System.out.println("Random Guess: " + randomGuess); in the loop and see if it is printing with the same number over and over again.
Otherwise, I would need to see the output of your program to further diagnose the issue.
Edit: Can you post the input/output of your program up to the point it crashes? This will help. Also, did you have the System.out.println() in your loop beginning with while(guessResult != -1) or the second one?
Edit 2: I tested this code with my edits and it seems to work as intended (ish). The initial while loop does not do what is intended. The "game" aspect of guessing the correct number all happens in the first loop. I am "playing" the game and guess numbers but once I get it correct, it moves to the second loop, presumably where you actually wanted to "play". The correct number is gotten in the first loop and then the guessResult variable gets set to -1. Then when the user tries to guess where they are supposed to, the "correct" number is now -1.
I don't think the game was ever "hung up", it was just silently waiting for your input in the first loop. To solve this:
Simply remove the first while loop (and its contents) and the game works as intended.

how to make a nested loop break if string.contains() is correct

I'm having issues understanding nested loops and their behavior. On the first loop the script asks for 10 digit number otherwise it will keep looping, this works fine. on the second loop, i'm trying to get the program to keep running until users enters "999" anywhere in the phone number. I have some idea but i'm not able to put it together. so if the user enters a 10 digit number but it doesnt contain 999, then it will keep asking to reenter phone number.
import javax.swing.JOptionPane;
import java.lang.*;
public class FormatPhoneNumber {
public static void main(String[] args) {
final int numLength=10;
String phoneNum = null;
String nineS="999";
phoneNum=JOptionPane.showInputDialog(null, "Enter your telephone number");
while (phoneNum.length()!=numLength)
{phoneNum=JOptionPane.showInputDialog(null, "You must re-enter 10 digits as your telephone number.");
}
StringBuffer str1 = new StringBuffer (phoneNum);
str1.insert(0, '(');
str1.insert(4, ')');
str1.insert(8, '-');
JOptionPane.showMessageDialog(null, "Your telephone number is " +str1.toString());
while (phoneNum.contains(nineS))// THIS IS THE ISSUE
{
}
}
}
Use
if (phoneNum.contains(nineS))
{}
don't use
while (phoneNum.contains(nineS))
or U can do it this way
if (!(phoneNum.contains(nineS)))
{
JOptionPane.showMessageDialog(null,"Invalid Input");
}
Nesting is when one loop is inside another loop. The code you have provided does not have one.
Typical example of nesting:
while( some_condition )
{
do_something..
while( more_condition )
{
do_something_more..
}
}
If I understand correctly, you want to keep on entering numbers and do something with them. But once the user enters a number which has '999' in it, the control has to come out of the loops.
As someone already pointed out, you do not need nested loop to achieve this at all.
while( phoneNumber has 10 digits )
{
do_something..
if( phoneNumber has '999' anywhere )
{
break;
}
}
while (phoneNum.length()!=numLength)
{
phoneNum=JOptionPane.showInputDialog(null, "You must re-enter 10 digits as your telephone number.");
StringBuffer str1 = new StringBuffer (phoneNum);
str1.insert(0, '(');
str1.insert(4, ')');
str1.insert(8, '-');
JOptionPane.showMessageDialog(null, "Your telephone number is " +str1.toString());
if(phoneNum.contains(nineS))// THIS IS THE ISSUE
break;
}
hope this helps.

Continually Validating Integers

I have a method I'm using to validate user-inputted values in a program. Whenever the user inputs a string into a JOptionPane, I call this method and pass in the inputted string, plus the maximum and minimum values I need their input to be between. First I check if the input is an integer by trying to parse the input string and catching exceptions, then I check if the integer is between the min and max. My problem is that if the user inputs another incorrect non-integer value after being prompted, I don't know how to check if the new value is correct or not. Here is the method, can anybody help?
int checkInput(String input, int min, int max) {
Boolean isInteger = false;
Boolean inputAccepted = false;
int userInput = 0; //will be set later
while (!isInteger) {
try
{
userInput = Integer.parseInt(input);
}
catch (NumberFormatException e)
{
userInput = Integer.parseInt(JOptionPane.showInputDialog("Please enter only integers between " + min + " and "+ max + "."));
isInteger = true; //the problem here is that it assumes the user inputted a correct value after being prompted... what if they enter another incorrect value?
}
}
while (!inputAccepted) {
if (userInput < min || userInput > max)
{
userInput = Integer.parseInt(JOptionPane.showInputDialog("Please enter only integers between " + min + " and "+ max + "."));
}
else
{
inputAccepted = true;
}
}
return userInput;
}
I believe the main problem is that you have a method whose job isn't simple and well-defined. It looks like you have a statement outside this method that inputs a number; but checkInput has two jobs: making sure the number is valid, and inputting more numbers until it is. This is a problem in two ways: your code that does the input is duplicated in two places, and you have a method whose responsibility isn't clear.
Instead, try writing a method that just checks whether the input is valid, and returns true or false. I'd change the name to isValidInput. The caller would then have a loop that would perform the input, make sure it's valid, and go back if it isn't.
Usually I wouldn't answer a question like this by pointing to flaws in your design. But I think that in this case, if you rethink your design, your question will answer itself. (That's often the case when you design things correctly--things fall into place.)
Your checkInput() function should throw its own exception if the input is not correct. Spliting the code into a validator and a parser would result in parsing the input twice.

check string for integers?

Ok, I posted once earlier but it was locked due to not demonstrating a basic understanding, and the answers I did get before it was locked didn't help me. I'm at a super beginner level of java and this is what I want my program to do (will post code at end). I want the user to input anything they want. Then, if it is not a number, I want it to display that they need to input a number. Then, after they input a number, I want it to display whether or not that number is even or odd. I read about parseInt and parseDouble but i can't figure out how to get it to work how I want. I am not sure any more if parsing is what i want to do. I dont want to instantly convert it to numbers, just to check if it IS a number. then i can proceed to do things after the program has determined if it is a character or number. thanks for any help and let me know if you need more information!
ok i changed some things and used a lot of code from no_answer_not_upvoted. here is what i have now. it runs fine and works with negative and positive whole numbers as specified in the directions. the only thing that bugs me is after all is said and done, i get this error in the compile box at the bottom of eclipse. the program does what is intended and stops appropriately but i dont understand why i am getting this error.
Exception in thread "main" java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Scanner.java:1585)
at monty.firsttry2.main(firsttry2.java:21)
public static void main(String[] args) {
System.out.print("Enter a character or number. This program will run until you enter a whole number, then it will"
+ "tell you if it was even or odd.");
while (true) {
Scanner in=new Scanner(System.in);
int num;
while(true) {
String input=in.nextLine();
try {
num=Integer.parseInt(input);
break;
}
catch (NumberFormatException e) {System.out.print("That wasn't a whole number. Program continuing.");}
}
if (num==0) {System.out.print("Your number is zero, so not really even or odd?");}
else if (num%2!=0){System.out.print("Your number is odd.");}
else {System.out.print("Your number is even");}
in.close();
}
}
}
Assumption
A String is to be considered a number if it consists of a sequence of digits (0-9), and no other characters, except possibly an initial - sign. Whereas I understand that this allows Strings such as "-0" and "007", which we might not want to consider as numbers, I needed some assumptions to start with. This solution is here to demonstrate a technique.
Solution
import java.util.Scanner;
public class EvensAndOdds {
public static final String NUMBER_REGEXP = "-?\\d+";
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
for(;;) { // Loop forever
System.out.println("Enter a number, some text, or type quit");
String response = input.nextLine();
if (response.equals("quit")) {
input.close();
return;
}
if (response.matches(NUMBER_REGEXP)) { // If response is a number
String lastDigit = response.substring(response.length() - 1);
if ("02468".contains(lastDigit)) {
System.out.println("That is an even number");
} else {
System.out.println("That is an odd number");
}
} else {
System.out.println("That is not a number");
}
}
}
}
Justification
This solution will match a number of ANY length, not just one that will fit into an int or a long; so it is superior to using Integer.parseInt or Long.parseLong, which both fail if the number is too long. This approach can also be adapted to more complicated rules about what constitutes a number; for example, if we decided to allow numbers with comma separators (such as "12,345" which currently will be treated as not a number); or if we decided to disallow numbers with leading zeroes (such as "0123", which currently will be treated as a number). This makes the approach more versatile than using Integer.parseInt or Long.parseLong, which both come with a fixed set of rules.
Regular expression explanation
A regular expression is a pattern that can be used to match part of, or all of a String. The regular expression used here is -?\d+ and this warrants some explanation. The symbol ? means "maybe". So -? means "maybe a hyphen". The symbol \d means "a digit". The symbol + means "any number of these (one or more)". So \d+ means "any number of digits". The expression -?\d+ therefore means "an optional hyphen, and then any number of digits afterwards". When we write it in a Java program, we need to double the \ character, because the Java compiler treats \ as an escape character.
There are lots of different symbols that can be used in a regular expression. Refer to http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html for them all.
this shows you how to do it
import java.util.Scanner;
public class EvenOdd {
public static void main(String[] args) {
System.out.print("Enter a character or number. Seriously, though, it is meant to be a number, but you can put whatever you want here. If it isn't a number however, you will get an error message.");
try (Scanner in = new Scanner(System.in)) {
int n;
while (true) {
String input=in.nextLine();
try {
n = Integer.parseInt(input);
break;
} catch (NumberFormatException e) {
System.out.println("you did not enter just an integer, please try again");
}
}
if (n % 2 == 0) {
System.out.println(n + " is even");
} else {
System.out.println(n + " is odd");
}
}
}
}
As is already mentioned in other answers, you will need to call parseDouble statically with
Double theNumber = Double.parseDouble(numberString);
Next you will want to look at wrapping this in a try/catch so that you can do the even/odd check if theNumber is created or set the error message if an exception is caught.
Since you are a beginner, you need to understand the difference between numbers (integers, double, strings, characters), so the following will guide you.
First, read input one line at a time,
Java read line from file)
Then scan line looking for characters that form what you consider to be an integer (allow leading spaces?, then '+' or '-', then digits 0-9, and then trailing spaces.
Here are the rules (for integers)
leading spaces ok (this is up to you) (how: How to check if a char is equal to an empty space?)
optional single '+' or '-'
one or more digits (how: How to check if a character in a string is a digit or letter)
optional trailing space(s) (again, this is up to you)
Anything other than this pattern violates the test for 'is this an integer'. Btw, Double is an extended precision real number.
import java.lang.*;
import java.util.Scanner;
public class read_int
{
public static boolean isa_digit(char ch) {
//left as exercise for OP
if( ch >= '0' && ch <= '9' ) return true;
return false;
}
public static boolean isa_space(char ch) {
//left as exercise for OP
if( ch == ' ' || ch == '\t' || ch == '\n' ) return true;
return false;
}
public static boolean isa_integer(String input) {
//spaces, then +/-, then digits, then spaces, then done
boolean result=false;
int index=0;
while( index<input.length() ) {
if( isa_space(input.charAt(index)) ) { index++; } //skip space
else break;
}
if( index<input.length() ) {
if( input.charAt(index) == '+' ) { index++; }
else if( input.charAt(index) == '-' ) { index++; }
}
if( index<input.length() ) {
if( isa_digit(input.charAt(index)) ) {
result=true;
index++;
while ( isa_digit(input.charAt(index)) ) { index++; }
}
}
//do you want to examine rest?
while( index<input.length() ) {
if( !isa_space(input.charAt(index)) ) { result=false; break; }
index++;
}
return result;
}
public static void main(String[] args) {
System.out.print("Enter a character or number. Seriously, though, it is meant to be a number, but you can put whatever you want here. If it isn't a number however, you will get an error message.");
Scanner in=new Scanner(System.in);
String input=in.nextLine();
if( isa_integer(input) ) {
System.out.print("Isa number.");
}
else {
System.out.print("Not a number.");
}
}
}

Categories