If statement skipping right to else after being called once? - java

I'm making a simple coin toss game, and I wrote several methods to call and make my main class short and simple. After the game is played once, the first If/Else statement to ask users for input is jumping right to the Else statement without prompting for input.
package cointoss;
import java.util.Random;
import java.util.Scanner;
public class Game {
int money;
int result;
int bet;
Random rn = new Random();
Scanner in = new Scanner(System.in);
String playerPick;
String aResult;
public void setMoney(int a)
{
money = a;
}
public int getMoney()
{
return money;
}
public void getBet()
{
System.out.println("How much would you like to bet?");
bet = in.nextInt();
do{
if(bet > money)
{
System.out.println("You cannot bet more than you have!");
System.out.println("You have bet " + (bet - money) + " too many coins.");
continue;
}
else
System.out.println("You have bet " + bet + " coins.");
}
while(bet > money);
}
public void getInput()
{
System.out.println("Pick Heads or Tails");
playerPick = in.nextLine();
playerPick.toLowerCase();
if(playerPick.contains("heads"))
playerPick ="heads";
else if(playerPick.contains("tails"))
playerPick ="tails";
else
System.out.println("Invalid Selection");
}
public void flipCoin()
{
result = rn.nextInt(2);
if(result == 0)
{
aResult = "heads";
}
else
aResult = "tails";
}
public void checkResult()
{
if(playerPick.equals(aResult))
{
System.out.println("You have won!");
money += bet;
System.out.println("You now have " + money + " coins");
}
else{
System.out.println("You have lost!");
money -= bet;
System.out.println("You now have " + money + " coins");
}
}
}
My Tester Class:
package cointoss;
public class GameTest {
public static void main(String[] args)
{
Game coinToss = new Game();
coinToss.setMoney(100);
while(coinToss.getMoney() > 0)
{
coinToss.getInput();
coinToss.getBet();
coinToss.flipCoin();
coinToss.checkResult();
}
}
}

The method toLowerCase() does not change the contents of the string; String is an immutable class in Java. The toLowerCase() method returns the result. You need to change
playerPick.toLowerCase();
to
playerPick = playerPick.toLowerCase();

Your problem is that you are not reinitializing "in" as a new Scanner every time you run the tester loop. The single scanner reads a line of input and accepts that as the full answer, without acknowledging that there could be further input.

The problem is that when the user enters a line, the input buffer will contain characters followed by a "newline" (end-of-line) character. When you use nextInt, the Scanner will find and skip over an integer. But it won't skip over the end-of-line. So when you next call nextLine in getInput(), it will then find what's left of the previous line, i.e. an empty string, and return that. Some things you'll need to do:
(1) In getBet, add in.nextLine() at the end of the method, to skip past the end-of-line. nextLine will return a string but you can ignore it. See also Scanner issue when using nextLine after nextXXX
(2) getInput needs to have a loop so that if the user enters an invalid input, you go back and ask him to enter a valid string. Otherwise, it will display "Invalid Selection" but then ask for a bet, which isn't what you want.
(3) See the other answers with regard to toLowerCase.

When you use
playerPick.toLowerCase();
It does nothing because the value is not being assigned to anything. In order to change a value of an object you must assign a value to it, as below:
playerPick = Pick.toLowerCase();
This assigns the value, rather than calling an empty method
Hope this helps :)

Related

Repeat a loop already satisfied in java

I'm looking to repeat a "game" if it is already satisfied in my case where user has to guess the random number. I can't understand where to to get back to the main game unless i have to create another "do - while" loop inside it and retype the game again in the section where it says: System.out.println("you have tried: " + count + " times. Would you like to play again? y/n"). Is there a way to just bring back to the actual guess loop rather than create another one?
Hopefully makes sense.
import java.util.Scanner;
import java.util.concurrent.ThreadLocalRandom;
public class pass {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String pass = "password123";
String input;
int guess;
int count;
count = 0;
int num;
do {
System.out.print("Enter your password: ");
input = scanner.next();
} while (!input.equals(pass));
System.out.println("Correct! Now play the guess game! Guess a number between 1 - 10.");
do {
num = ThreadLocalRandom.current().nextInt(1,10);
guess = scanner.nextInt();
count++;
if (guess == num) {
System.out.println(" Well done!");
**System.out.println("you have tried: " + count + " times. Would you like to play again? y/n");**
}
else if (guess < num) {
System.out.println("your number is smaller than the number given");
}
else {
System.out.println("your guess is too high");
}
} while (guess != num);
}
}
The simplest solution would be to move the entire "guess loop" into a separate method. Then in the case when you want it to repeat, just call the method recursively.
If you want to reuse code you can make functions (or methods here, because we are inside a class). They can be used to encapsulate code and call it from anywhere to use it.
You can define a methods like that:
public static void methodName() {
// code go here
}
Then, you can call it from anywhere like that :
pass.methodName(); // It will execute the code inside methodName()
In reality, this is a lot more complex than that, you can give methods values and return others, change the scope of it to make it internal only or reachable by other classes. But I presume that you are a beginner so I keep it simple. I strongly recommend you to make a quick research about Object Oriented Programmation!
For your code, you can put the game's while loop in a method and call it at the beginning and each time the player wants to restart the game. Good luck with your game!
I manage to do this way. It seems working but one thing is letting me down at the very last when I key in "n" or other key than "y". Exception in thread "main" java.util.InputMismatchException. Is there a more softer way to finish it?
import java.util.Scanner;
import java.util.concurrent.ThreadLocalRandom;
public class pass {
public static void randomnum(){
Scanner scanner = new Scanner(System.in);
int guess;
int count;
count = 0;
int num;
do {
num = ThreadLocalRandom.current().nextInt(1,10);
guess = scanner.nextInt();
count++;
if (guess == num) {
System.out.println(" Well done!");
System.out.println("you have tried: " + count + " times.");
String answer;
do{
System.out.println("Do you want to play again? y/n");
answer = scanner.next();
if (answer.equals("y")) {
System.out.println("let's play again");
randomnum();
System.out.println("Correct! Now play the guess game! Guess a number between 1 - 10.");
}
else {
System.out.println("you are logout!");
break;
}
}while (answer.equals("Y"));
randomnum();
}
else if (guess < num) {
System.out.println("your number is smaller than the number given");
}
else {
System.out.println("your guess is too high");
}
} while (guess != num);
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String pass = "password123";
String input;
do {
System.out.print("Enter your password: ");
input = scanner.next();
} while (!input.equals(pass));
System.out.println("Correct! Now play the guess game! Guess a number between 1 - 10.");
randomnum();
}
}

How to get scanner input to not trigger third method?

I'm working on an assignment and I mostly have it finished but I am having an issue with the last method. I'm trying to write a continueGame() method that will ask the user if they want to continue to play, and accept "y" or "n". If answered "y", the program starts again. If answered "n", the program stops and a message is shown. The problem is I need it to trigger the continueGame() method only when userChoice == answer. This is a number guessing game with an object oriented approach.
I've tried to call the continueGame() method inside my else if(userChoice == answer) statement but it doesn't seem to work. Even when my other if/else if statements are triggered, it continues to the continueGame() method.
Here is the main driver for the game
import java.util.Scanner;
public class NumberGame
{
public static void main(String[] args)
{
Scanner input = new Scanner (System.in);
GameOptions opt = new GameOptions(); // Your created class
int userChoice = -1234;
int answer = -1234;
boolean keepPlaying = true;
System.out.println("Guess the Number Game\n");
while (keepPlaying == true) {
answer = (int) (Math.random() * 10)+1;
//Create a getChoice method in your class and make sure it accepts a Scanner argument
userChoice = opt.getChoice(input);
//Create a checkAnswer method in your class. Make sure it accepts two integer arguments and a Scanner argument
opt.checkAnswer(userChoice, answer, input);
// Create a continueGame method in your class and make sure it accepts a Scanner argument
keepPlaying = opt.continueGame(input);
}
System.out.println("Thanks for playing.");
}
}
Here is the class that I am working on for the methods. Note that I can not make any modifications to the main driver file.
import java.util.InputMismatchException;
import java.util.Scanner;
import java.lang.NumberFormatException;
public class GameOptions {
int count = 0;
boolean cont = true;
//getChoice Method for NumberGame
public int getChoice(Scanner scnr) {
System.out.println("Please choose a number between 1 and 10: ");
int userGuess = 0;
String input = scnr.next();
try {
userGuess = Integer.parseInt(input);
if (userGuess < 1 || userGuess > 10) {
throw new IllegalArgumentException("Invalid value. Please enter a number between 1 and 10: ");
}
}
catch(NumberFormatException e) {
System.out.println("Error - Enter Numerical Values Only");
return userGuess;
}
catch (IllegalArgumentException ex) {
System.out.println(ex.getMessage());
}
return Integer.parseInt(input);
}
public void checkAnswer(int userChoice, int answer, Scanner scnr) {
if (userChoice > answer && userChoice < 11) {
System.out.println("Too high. Try again.");
count++;
} else if (userChoice < answer && userChoice > 0) {
System.out.println("Too low. Try again.");
count++;
} else if (userChoice == answer) {
System.out.println("You got it! Number of tries: " + count);
System.out.println("Would you like to play again? (y/n)");
}
}
public static boolean continueGame(Scanner scnr) {
String input = scnr.nextLine();
if (input.toLowerCase().equals("y")){
return true;
} else if (input.toLowerCase().equals("n")){
return false;
} else {
System.out.println("Invalid entry. Please enter either y or n: ");
return continueGame(scnr);
}
}
}
So I should be able to enter a number, and if its lower than the answer it will tell me I am too low, if its higher than the answer it will tell me that its too high, if its equal it will tell me I won and prompt me to press "y" or "n" if I want to continue. Another issue I am running into is that I am getting "Would you like to play again? (y/n)" no matter whether I guess the right number or not and my only option is to hit "y" or "n"
The driver class is calling continueGame() inside the while loop. If you're not allowed to modify that class then presumably asking at every iteration is the intended behaviour.
You should move System.out.println("Would you like to play again? (y/n)"); into the continueGame() method so that it only asks when that method is called.
The way the driver is written (I guess) is coming from your instructor/lecturer/professor, right?
With the driver (as it is), you don't need to call continueGame method from checkAnswer method. The driver is going to call it.
Just run the driver and it will work. If you have a proper IDE (eclipse or Netbeans), trace through and see what the input accepted is (I think there is line-feed in the accepted answer).
Try this (I just changed the loop structure; yours is also valid):
public static boolean continueGame(Scanner scnr) {
while (true) {
String input = scnr.nextLine().trim(); // to remove white spaces and line-feed
if (input.toLowerCase().equals("y")){
return true;
} else if (input.toLowerCase().equals("n")){
return false;
} else {
System.out.println("Invalid entry. Please enter either y or n: ");
}
}
}
Added for checkAnswer method to keep the user guess the answer until he gets correct:
public static checkAnswer(/*three arguments*/) {
boolean correct = false;
while (! correct) {
// accept input
if (answer.equals(input)) {
correct = true;
// print required correct/congrats messages here
} else {
// print required input/try again messages here
}
}
// print would you like to play again with new answer y/n message here.
}
In my opinion, printing "play again with new answer y/n message" should go into continueGame method (from last portion of checkAnswer) method to stick to encapsulation concepts.

How to keep the program running if the user entered Y?

Here is my code:
import java.util.*;
class Main {
public static void main(String[] args) {
Scanner Keyboard = new Scanner(System.in);
{
System.out.println("What is the answer to the following problem?");
Generator randomNum = new Generator();
int first = randomNum.num1();
int second = randomNum.num2();
int result = first + second;
System.out.println(first + " + " + second + " =");
int total = Keyboard.nextInt();
if (result != total) {
System.out.println("Sorry, wrong answer. The correct answer is " + result);
System.out.print("DO you to continue y/n: ");
} else {
System.out.println("That is correct!");
System.out.print("DO you to continue y/n: ");
}
}
}
}
I'm trying to keep the program to continue but if the user enters y and closes if he enters n.
I know that I should use a while loop but don't know where should I start the loop.
You can use a loop for example :
Scanner scan = new Scanner(System.in);
String condition;
do {
//...Your code
condition = scan.nextLine();
} while (condition.equalsIgnoreCase("Y"));
That is a good attempt. Just add a simple while loop and facilitate user input after you ask if they want to continue or not:
import java.util.*;
class Main
{
public static void main(String [] args)
{
//The boolean variable will store if program needs to continue.
boolean cont = true;
Scanner Keyboard = new Scanner(System.in);
// The while loop will keep the program running unless the boolean
// variable is changed to false.
while (cont) {
//Code
if (result != total) {
System.out.println("Sorry, wrong answer. The correct answer is " + result);
System.out.print("DO you to continue y/n: ");
// This gets the user input after the question posed above.
String choice = Keyboard.next();
// This sets the boolean variable to false so that program
// ends
if(choice.equalsIgnoreCase("n")){
cont = false;
}
} else {
System.out.println("That is correct!");
System.out.print("DO you to continue y/n: ");
// This gets the user input after the question posed above.
String choice = Keyboard.next();
// This sets the boolean variable to false so that program
// ends
if(choice.equalsIgnoreCase("n")){
cont = false;
}
}
}
}
}
You may also read up on other kinds to loop and try implementing this code in other ways: Control Flow Statements.

How do you prompt a user for an input in java

So I just started learning Java, its literally like my 1st day and I wanted to try to make a coinflip game. I already know a decent amount of Javascript and so i was trying to apply that knowledge to java. So everything has been working so far except one thing: Prompting a user for a choice. So read online that i have to import a scanner so i did that as you can see from my code. I also tried some code where you can have the user import a string but you can see a bit later in my program i change the variable userChoice into a number. So basically i just need help with this. If there is some way to have a variable type that can store both numbers or strings that would be best. But im tottaly open to other ways of doing this! Thanks in advanced! Here is the code:
package test;
import java.util.Scanner;
public class testclass {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("hi");
int bob;
bob = (int) Math.floor(Math.random()*2);
System.out.println(bob);
System.out.println("Enter heads or tails?");
System.out.println("You entered "+ userChoice);
if (bob == 0) {
System.out.println("Computer flipped heads");
}
else {
System.out.println("Computer flipped tails");
}
if(userChoice == "Heads") {
userChoice = 0;
}
else {
userChoice = 1;
}
if (userChoice == bob) {
System.out.println("You win!");
}
else {
System.out.println("Sorry you lost!")
}
}
}
Use a scanner, as you said:
Scanner in = new Scanner(System.in);
Then, prompt the user to enter something in:
String userChoice = in.nextLine();
Also, when you compared strings:
if(userChoice == "Heads") {...
that's bad to do for none-primitive objects. It's best to only use the == to compare values that are ints or enums. If you compare a String like this, it won't work, because it's checking if the objects are the same. Instead, compare like this:
if(userChoice.equals("Heads")) {...
Also, to convert to an int (NOTE: You can't convert one type of object to another that aren't related in any way! You'll have to create a new object if you're wanting to do that), do this:
int myInt = Integer.parseInt(myString); // NOTE: Can throw NumberFormatException if non-number character is found.
So your program should look somewhat like:
package test;
import java.util.Scanner;
public class testclass {
public static void main(String[] args) {
//System.out.println("hi");
Scanner in = new Scanner(System.in);
int bob;
int userChoice;
String input;
bob = (int) Math.floor(Math.random()*2);
System.out.println(bob);
System.out.println("Enter heads or tails?");
input = in.nextLine(); // waits for user to press enter.
System.out.println("You entered "+ input);
if (bob == 0) {
System.out.println("Computer flipped heads");
}
else {
System.out.println("Computer flipped tails");
}
if(input.equals("Heads")) {
userChoice = 0;
}
else {
userChoice = 1;
}
if (userChoice == bob) {
System.out.println("You win!");
}
else {
System.out.println("Sorry you lost!");
}
in.close(); // IMPORTANT to prevent memory leaks
}
}
You've already imported the Scanner class so you can now create a variable of the type Scanner for taking inputs.
Scanner in = new Scanner();
userChoice = in.nextLine();
nextLine() can be used to input a character or a string from the user.
To convert the string into a integer, You can assign the integer value to the string in the following way.
if(userChoice == "Heads") {
userChoice = "" + 0;
}
else {
userChoice = "" + 1;
}
"String" datatype in Java can hold both numbers and strings (as you asked). You can get user input using Scanner utility as below:
Scanner input = new Scanner();
userChoice = input.nextLine(); // if it is a string
//userChoice = input.nextInt(); // if it's integer choice
If your string is an integer then you can also parse it to get its integer value. For parsing:
int value = Integer.parseInt(userChoice);
Also for comparing String values you should use "equals" function rather than "==".
if(userChoice.equals("Heads")){...} //rather than if(userChoice == "Heads"){...}
Having imported java.util.Scanner, to get input from the user as a String, create a Scanner object that parameterizes System.in and assign userChoice the value of nextLine() invoked by the Scanner object:
Scanner input = new Scanner(System.in);
String userChoice = input.nextLine();
A few things about your code. The relational operator, ==, is used for comparing primitive data - not objects. Use string1.equals(string2) to see if two strings are equal.
Also, bob = (int) Math.floor(Math.random()*2); is really bob = (int)(Math.random() * 2);
because casting a double as an integer truncates the double to the highest integer less than or equal to it.
It might help you to get the ideas.
public static void main(String[] args) {
Random rd = new Random();
//Enter 1 0R 0
int bob = rd.nextInt(2);
String userChoice;
Scanner sc = new Scanner(System.in);
System.out.println("Please enter a number");
userChoice = sc.nextLine();
System.out.println("You entered " + userChoice + " and bob is " + bob);
int uc = Integer.parseInt(userChoice);
if (uc == bob) {
System.out.println("Hehe");
} else {
System.out.println("Sorry");
}
}

Guessing game adding a method

I need to add a method to my guessing game that i made a while ago. The method should return the value they enter but should use a loop to require re-entry until one of those two values has been specified.
Also if the user inputs a word and not an int, it should ask for a number. I know that I will need to use a string instead of an int. I'm just having trouble figuring this out. Here is what I have so far:
import java.util.Random;
import java.util.Scanner;
class GuessNumber {
static Random rand = new Random();
static Scanner scan = new Scanner(System.in);
static int number;
public static void main(String[] args) {
playGame();
}
public static void playGame() {
number = rand.nextInt(100) + 1;
System.out.println("Guess the number between 1 and 100");
while (true) {
int guess = scan.nextInt();
if (guess < number) {
System.out.println("Higher!");
} else if (guess > number) {
System.out.println("Lower!");
} else if (guess == number) {
System.out.println("Correct!");
Scanner scan2 = new Scanner(System.in);
System.out.println("do you wanna play again?[Y/N]");
String val = scan2.next();
if (val.equalsIgnoreCase("Y")) {
playGame();
} else {
break;
}
}
}
}
}
There might be a better way to do it but try something along the lines of:
String input = scan.next();
int guess;
try{
guess = Integer.parseInt(input);
//rest of the code inside while(true) loop
}
catch(Exception e){
System.out.println("You need to enter a valid number.");
}
and then for the Y/N validation:
String val = "No";
Scanner scan2 = new Scanner(System.in);
do{
System.out.println("do you wanna play again?[Y/N]");
val = scan2.next();
}
while(!val.equalsIgnoreCase("Y") && !val.equalsIgnoreCase("N"))
if (val.equalsIgnoreCase("Y")) {
playGame();
break;
} else {
break;
}
Reasoning: You will get an error if they do not enter a valid number so you need to catch the error and let them know what is wrong. I like to get input as string and try to convert it to integers. As for the do/while section... Unless they enter Y or N it will keep asking them. Once out of the loop, if the input was "Y" it will call the playGame() again and then break after it finishes (basically whenever the user types n in the next game). If it wasn't "Y" then it had to be "N" and needs to break.
Let me know if this helps. I have the full code that will work but this should be easy enough for you to implement.
When you declare your static variables, put:
static int number, guess;
To declare both numbers at the same time. Then, inside the main loop, do the following:
while (true) {
while (true) {
try {
guess = Integer.parseInt(scan.nextLine());
break;
} catch (Exception e) {
System.out.println("Not a valid number!");
continue;
}
}
//Rest of your if's, else if's, etc
}
I've tested it, and it works for me.
If you need me to I can paste in all the code, but you should be able to just nest that second while loop inside the first, before the if statements, easily enough.

Categories