Scanner + switch use - java

I'm a new to Java.
I'm currently doing a side project; making a text based game. and I realized that using Switch-statement would be very useful for this type of game.
So it is basically how it works.
I ask User, what would you like to do?
Eat
Walk
etc.
So, what would be the best way to build a switch-statement and Scanner together along with "default statement that asks User again"?
I've been doing this way(my code down here), but it seems it has so many potential problems.
Could you guys give me some hints on how to make a best switch-statement with Scanner?
Thank you very much in advance.
public static void ask() {
Scanner sc = new Scanner(System.in);
System.out.println("What do you want to do?");
while (!sc.hasNextInt()) {
sc.next();
}
select = sc.nextInt();
switch (select) {
case 1:
eat();
break;
case 2:
walk();
break;
case 3:
sleep();
break;
default:
System.out.println("choose from 1 to 3");
ask(); //would you re call itself again here? or is there any otherway to do without recalling itself?
}

Your code seems ok but I would refactor it. Also add while loop to ask again:
public static void ask() {
Scanner sc = new Scanner(System.in);
boolean isWrongAnswer;
do {
isWrongAnswer = false;
System.out.println("What do you want to do?");
switch (sc.nextInt()) {
case 1:
eat();
break;
case 2:
walk();
break;
case 3:
sleep();
break;
default:
System.out.println("choose from 1 to 3");
isWrongAnswer = true;
}
} while (isWrongAnswer);
}

It is good to check first that scanner has something or not then check for whether it is int value. To do that can use sc.hasNext() & sc.hasNextInt() like below,
public static void ask() {
Scanner sc = new Scanner(System.in);
System.out.println("What do you want to do?");
while (sc.hasNext()) {
int select = 0;
if (sc.hasNextInt()) {
select = sc.nextInt();
}
switch (select) {
case 1:
System.out.println("call eat()");
break;
case 2:
System.out.println("call walk()");
break;
case 3:
System.out.println("call sleep()");
break;
default:
System.out.println("choose from 1 to 3");
ask();
}
}

I advise you to use String in this case. To improve the readability of the code, and to avoid errors.(http://www.oracle.com/technetwork/java/codeconventions-150003.pdf)
private static final String EAT = "1";
private static final String WALK = "2";
private static final String SLEEP = "3";
public void ask() {
Scanner sc = new Scanner(System.in);
System.out.println("What do you want to do?");
switch (sc.next()) {
case EAT:
eat();
break;
case WALK:
walk();
break;
case SLEEP:
sleep();
break;
default:
System.out.println("choose from 1 to 3");
ask(); // as described above via "do while", but there is nothing wrong with recursion. The garbage collector works.
}
}

Related

Scanner inputMismatch

This is my code (simplified).
public class A {
int num;
public void method () {
Scanner scanner = new Scanner(System.in);
num = scanner.nextInt();
switch (num) {
case 1:
System.out.println("Hello 1");
scanner.close();
break;
case 2:
System.out.println("Hello 2");
scanner.close();
break;
case 3:
System.out.println("Hello 3");
scanner.close();
break;
default:
System.out.println("\nPlease try again.");
method();
}
}
}
I want any non-integer input like Strings to also run the default case and sysout the "Please try again" instead of getting an inputMismatch error, but i have no idea how to do it.
Basically any input that is not a 1,2 or 3 should jump to the default case.
You can't do this through this code as you are taking user input as integer and if you will enter a string it will through inputMismatch error as the compiler is expecting integer but getting string or character input.
Now what you can do is take a string as the user input. Here the complete code for you:
public class A {
String num;
public void method () {
Scanner scanner = new Scanner(System.in);
num = scanner.nextLine();
switch (num) {
case "1":
System.out.println("Hello 1");
scanner.close();
break;
case "2":
System.out.println("Hello 2");
scanner.close();
break;
case "3":
System.out.println("Hello 3");
scanner.close();
break;
default:
System.out.println("\nPlease try again.");
method();
}
}
}
This is what you want. It will work for every input.
Use scanner.hasNextInt() to check if the input is an integer. If not, assign zero to num which then results in matching the default.
You can't get strings by num = scanner.nextInt();. But, I have an idea.
value = scanner.nextLine();
//Now, check it is string or int
boolean numeric = true;
try {
Double num = Double.parseDouble(value);
} catch (NumberFormatException e) {
numeric = false;
}
if(numeric){
Integer.parseInt(value)
}else{
//you can write value= value. Or, you can left it empty also. Or, you can remove else statement also.
}
switch (num) {
case 1:
System.out.println("Hello 1");
scanner.close();
break;
case 2:
System.out.println("Hello 2");
scanner.close();
break;
case 3:
System.out.println("Hello 3");
scanner.close();
break;
case "Hello":
System.out.println("Hello 3");
scanner.close();
break;
default:
System.out.println("\nPlease try again.");
method();
}
#Badal is correct also. And, I did it with keeping int value. And, I don't remember is there any other way to check is it string or not. So, Sorry.

How do I write a general user input statement to be used multiple times with different values?

I'm new to Java so I didn't really know how to word my question. I am trying to write a text adventure with lots of different options for the user to input. I have progressed quite far but am getting very confused with all the user inputs and options for them to take. Notice I created a short way of entering System.out.println before main that allows me to just enter text instead. I am wondering if I can do something similar with the user input block of code.
import java.util.Scanner;
public class AdventureTest {
static void text(String body){
System.out.println("" + body);
}
public static void main(String[] args) {
char direction;
Scanner input = new Scanner(System.in);
System.out.print("Go: (n/e/s/w)? ");
direction = input.nextLine().charAt(0);
switch( direction )
{
case 'n':
text("You go North");
break;
case 'e':
text("You go East");
break;
case 's':
text("You go South");
break;
case 'w':
text("You go West");
break;
default:
text("You fall down a hole!");
System.exit(0);
}
text("Program continues");
}
}
That is your solution my man!
I put your switch in a do...while loop, so after every user choice you can ask him/her if they want to choose another step, and it perfectly run after the user doesn't want to continue.
import java.util.Scanner;
public class AdventureTest {
private static Scanner input = new Scanner(System.in);
private static void text(String body) {
System.out.println("" + body);
}
public static void main(String[] args) {
char direction,answer = 0;
do{
System.out.print("Go n,e,s or w?: ");
direction = input.nextLine().charAt(0);
switch( direction )
{
case 'n': {
text("You go North");
System.out.println("Do you want to continue? (y/n)");
answer = input.nextLine().charAt(0);
}
break;
case 'e': {
text("You go East");
System.out.println("Do you want to continue? (y/n)");
answer = input.nextLine().charAt(0);
}
break;
case 's':{
text("You go South");
System.out.println("Do you want to continue? (y/n)");
answer = input.nextLine().charAt(0);
}
break;
case 'w':{
text("You go West");
System.out.println("Do you want to continue? (y/n)");
answer = input.nextLine().charAt(0);
}
break;
default:
text("You fall down a hole!");
System.exit(0);
}
}while(answer == 'y');
text("Program continues");
}
}
I don't know if I understood properly. Do you want a shorcut for reading input?
I thing, the most generic way to handle diferent inputs from a central function, is to return a string and then convert it to the type you need like this:
public static String read(){
return (new Scanner(System.in)).nextLine();
}
But I dont recommend you to do that as you are creating a new Scanner every time you read user input.
You could also create versions for this for every type you need like in this situation.
public static String readChr(){
return (new Scanner(System.in)).nextLine().charAt(0);
}
But you would end up making the wheel again.
Please clarify me what you meant.
What you want to do is loop, asking the same question, but then you will need some way to stop looping.
Here I have put in a do .. while (condition) loop.
I create a boolean done which starts as false -- you are not "done".
When q is entered instead of a nesw direction, done is set to true so the while condition changes and the program stops looping.
import java.util.Scanner;
public class AdventureTest {
static void text(String body) {
System.out.println("" + body);
}
public static void main(String[] args) {
char direction;
boolean done = false; // <----- Added This
Scanner input = new Scanner(System.in);
System.out.println("Enter q to quit");
do {
System.out.print("Go: (n/e/s/w)? ");
direction = input.nextLine().charAt(0);
switch( direction )
{
case 'n':
text("You go North");
break;
case 'e':
text("You go East");
break;
case 's':
text("You go South");
break;
case 'w':
text("You go West");
break;
case 'q': // <---- new case, for quit
text("You have quit");
done = true;
break;
default:
text("You fall down a hole!");
System.exit(0);
}
if (!done) text("Program continues");
}
while (!done);
}
}

How to switch order of output?

How do I switch the order of the outcome? I would liked to be asked to enter output after the menu.
Welcome to the Library! Please make a selection from the menu:
1. View.
2. Show.
Enter a choice: 1
However, I am made to enter input first, and I see:
Enter a choice: 1
Welcome to the Library! Please make a selection from the menu:
1. View.
2. Show.
This is my code:
import java.util.*;
public class Store {
public static void main(String[] args) {
new Store().use();
}
public void use() {
char choice;
while ((choice = readChoice()) != 'X') {
switch (choice) {
case 1: view(); break;
case 2: show(); break;
default: help(); break;
}
}
}
private char readChoice() {
return In.nextChar();
}
private String view() {
return "";
}
private String show() {
return "";
}
}
private void help() {
System.out.println("Welcome! Please make a selection from the menu:");
System.out.println("1. View.");
System.out.println("2. Show."); }
Just add help() on top of the use() method:
public void use() {
help();
char choice;
while ((choice = readChoice()) != 'X') {
switch (choice) {
case 1: view(); break;
case 2: show(); break;
default: help(); break;
}
}
}
You also need to change 1 and 2 into '1' and '2' respectively, because you are switching over a char. The fact that this compiles is because the compiler applies a narrowing primitive conversion to convert int to char.
I think there are three reasons that the code does not do what you expect.
You are made to enter input first, because before printing anything on the console, the readChoice() function is called. Which waits until it reads one character from the console and then returns. So you must call Help() function once before the while loop.
I guess the switch-case will not do what you expect. I mean the view() and show() functions are not called when you enter 1 or 2. The reason is that you read 1 and 2 as characters not integers. So the switch-case should change to this:
switch (choice) {
case '1': view(); break; //1 changed to '1'
case '2': show(); break; //2 changed to '2'
default: help(); break;
}
I think you might have forgotten to print "Enter a choice:" before reading the character. (I used System.out.print() rather than System.out.println() because it seems that "Enter a choice:" and the choice entered should be in the same line)
private char readChoice() {
System.out.print("Enter a choice:");
return In.nextChar();
}
this is the entire code, hope it works correctly (I put comments so you see what changes I made):
import java.util.*;
public class Store {
public static void main(String[] args) {
new Store().use();
}
public void use() {
char choice;
help();//called help() once before the loop
while ((choice = readChoice()) != 'X') {
switch (choice) { //cases changed
case '1': view(); break;
case '2': show(); break;
default: help(); break;
}
}
}
private char readChoice() {
//printing "Enter a choice:"
System.out.print("Enter a choice: ");
//I used Scanner class to read the next char, because I don't have 'In' class to use.
//you might write "return In.nextChar();" insead of the following lines
Scanner reader = new Scanner(System.in);
char c = reader.next().charAt(0);
return c;
}
private String view() {
System.out.println("you selected view"); //to see this function is called
return "";
}
private String show() {
System.out.println("you selected show"); //to see this function is called
return "";
}
private void help() {
System.out.println("Welcome! Please make a selection from the menu:");
System.out.println("1. View.");
System.out.println("2. Show.");
}
};

Java hardcoded repeating process

I am making a basic hardcoded game that has 2 users that will fight each other. All my methods are set and work as expected. I am now trying to figure out a way after looping through the main hardcode, to give the option to fight again and continue the game, instead of just stopping after 1 fight.
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.print("What is your name: ");
String myName = in.nextLine();
Fighter a = new Warrior();
Fighter b = new Dragon();
a.pickOpponent(b);
a.setName(myName);
b.setName("Onyxia");
System.out.print(getWelcome());
while(in.hasNextLine())
{
switch(in.nextLine())
{
case "no":
System.out.println("Wow, you are not even gonna try, you have lost!");
break;
case "yes":
System.out.println("Let the fight begin! ");
while(a.isAlive() && b.isAlive())
{
System.out.println("Do you want to punch, kick, or headbutt the other fighter? ");
switch(in.nextLine())
{
case "punch":
System.out.println(a.getPunch(b));
System.out.println(b.getOpponentAttack(a));
break;
case "kick":
System.out.println(a.getKick(b));
System.out.println(b.getOpponentAttack(a));
break;
case "headbutt":
System.out.println(a.getHeadbutt(b));
System.out.println(b.getOpponentAttack(a));
break;
default :
System.out.println(invalidInput());
break;
}
}
default:
System.out.println(a.getWinner(b));
break;
}//end of first switch statement
}//end of first while loop
}//end of main
Try moving all of the code in main into a new function.
You can put that function into a while loop in your main method, like so:
while(playGame()) {}
and have playGame() return true if the came should be played again, and false if it should end.
Sample:
public static boolean playGame() {
Scanner in = new Scanner(System.in);
System.out.print("What is your name: ");
String myName = in.nextLine();
Fighter a = new Warrior();
Fighter b = new Dragon();
a.pickOpponent(b);
a.setName(myName);
b.setName("Onyxia");
System.out.print(getWelcome());
while(in.hasNextLine())
{
switch(in.nextLine())
{
case "no":
System.out.println("Wow, you are not even gonna try, you have lost!");
break;
case "yes":
System.out.println("Let the fight begin! ");
while(a.isAlive() && b.isAlive())
{
System.out.println("Do you want to punch, kick, or headbutt the other fighter? ");
switch(in.nextLine())
{
case "punch":
System.out.println(a.getPunch(b));
System.out.println(b.getOpponentAttack(a));
break;
case "kick":
System.out.println(a.getKick(b));
System.out.println(b.getOpponentAttack(a));
break;
case "headbutt":
System.out.println(a.getHeadbutt(b));
System.out.println(b.getOpponentAttack(a));
break;
default :
System.out.println(invalidInput());
break;
}
}
default:
System.out.println(a.getWinner(b));
break;
}//end of first switch statement
}//end of first while loop
}//end of playGame
public static void main(String[] args) {
while(playGame()) {}
}
I'd put while(true) above System.out.print(getWelcome()); and closing it right before you close main. Then you can ask the user something like
System.out.println("Dare yie try again?");
String answer = in.nextLine();
if(answer.equals("yes"))
break; //which would break out of the while loop.

Error handling with strings java

I'm trying to add error handling to my java program if anything but the options and String/char are entered. I mainly need it for if a String is entered. I've tried to do the while(true) but I don't really understand that. I also added !(kb.hasNextInt()) to my line while (choice < 1 && choice > 4 ) but that didn't work either. So I just need help adding error handling to my program. Thanks!
here's my code
import java.util.*;
public class HeroesVersusMonsters
{
private static Hero hero;
private static Monster monster;
private static Random rand = new Random();
public static void main(String[] args)
{
Scanner kb = new Scanner(System.in);
do
{
System.out.println("---------------------------------------");
System.out.println("\tChoose your type of hero");
System.out.println("---------------------------------------");
System.out.println("\t1. Warrior");
System.out.println("\t2. Sorceress");
System.out.println("\t3. Thief");
System.out.println("\t4. Snake");
System.out.println();
System.out.print("Choice --> ");
int choice = kb.nextInt();
kb.nextLine();
while (choice < 1 && choice > 4 )
{
System.out.println("\n" + choice + " is not an option. Please try again.");
System.out.print("Choice --> ");
choice = kb.nextInt();
kb.nextLine();
System.out.println();
}
switch (choice)
{
case 1:
hero = new Warrior();
break;
case 2:
hero = new Sorceress();
break;
case 3:
hero = new Thief();
break;
case 4:
hero = new Snake();
break;
}
switch (rand.nextInt(3))
{
case 0:
monster = new Ogre("Shrek the Ogre");
break;
case 1:
monster = new Skeleton("Bones the Skeleton");
break;
case 2:
monster = new Gremlin("Dobby the Gremlin");
break;
}
System.out.println();
System.out.println(hero.name + ", you will be fighting against " + monster.getName() + "!!!");
System.out.println();
while (hero.getHits() > 0 && monster.getHits() > 0)
{
hero.attack(monster);
monster.attack(hero);
}
System.out.print("Would you like to play again? (yes / no) ");
String play = kb.nextLine().toLowerCase();
play = play.trim();
if (play.equals("no"))
break;
else
System.out.println();
}
while (true);
}
}
Please look closly to your condition of inner while loop.
while (choice < 1 && choice > 4 )
Means loop will work until choice<1 and choice>4 remains true.
Is it exactly what you want?
I think No because what if input is 5 it is true for >4 but false for <1 what you want is you need to loop things until user enters correct input.
Am I right?
So what you need to do is just change condition like this
while(choice<1 || choice>4)
As Jared stated.
One more thing I want to suggest you don't you think you should break; external loop while user enters wrong input.(No problem)
You can do one this also.
ArrayList<Integer> ar=new ArrayList<Integer>(4);
ar.add(1);
ar.add(2);
ar.add(3);
ar.add(4);
while(true)
{
if(ar.contains(choice))
{
//Go On
}
else
{
//Print old stuff
}
}
Here is what your main method should look like:
public static void main(String ...args){
final Scanner scanner = new Scanner(System.in);
while(true){
final Hero hero = promptHero(scanner);
final Monster monster = getRandomMonster();
fight(hero, monster);
if(!playAgain(scanner))
break;
}
}
Now write the static methods promptHero, getRandomMonster, fight, and playAgain (which should return true if you want to play again).
Here is what your promptHero method should look like (to properly handle bad input):
private static Hero promptHero(final Scanner scanner){
while(true){
System.out.println("---------------------------------------");
System.out.println("\tChoose your type of hero");
System.out.println("---------------------------------------");
System.out.println("\t1. Warrior");
System.out.println("\t2. Sorceress");
System.out.println("\t3. Thief");
System.out.println("\t4. Snake");
System.out.println();
System.out.print("Choice --> ");
try{
final int choice = scanner.nextInt();
if(choice < 1 || choice > 4)
System.out.println("\n" + choice +
" is not an option. Please try again.");
else
return getHero(choice); //return the hero
} catch(InputMismatchException ime){
final String line = scanner.nextLine();// need to advance token
System.out.println("\n" + line +
" is not an option. Please try again.");
}
}
}
private static Hero getHero(final int choice){
switch (choice){
case 1:
return new Warrior();
case 2:
return new Sorceress();
case 3:
return new Thief();
case 4:
return new Snake();
}
return null;
}
You should check out the Java regex:
if(choice.toString().matches("[0-9]+"))
{
//continue
}
else
{
//error message
}

Categories

Resources