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.
Related
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.
}
}
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 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.");
}
};
How do I break out of a void method and get back to the switch method?
public static void decrypt() throws FileNotFoundException {
Scanner kbrd = new Scanner(System.in);
System.out.println("Enter Key-file name: ");
String filename = kbrd.nextLine();
System.out.println("Enter Message-filename: ");
String mssgFilename = kbrd.nextLine();
String[] keyArray = loadMessage(filename);
String[] message = loadMessage(mssgFilename);
String[] cipher = xor2(message, keyArray);
String readable = showText(cipher);
System.out.println("The text:" + readable);
return;
}
and then here is the switch method
System.out.println("Encrypt 1.");
System.out.println("Decrypt 2.");
System.out.println("Make Key 3.");
System.out.println("Quit 4.");
Scanner scan = new Scanner(System.in);
String choice = scan.nextLine();
do {
switch (choice) {
case "1":
encrypt();
break;
case "2":
decrypt();
break;
case "3":
makeKey();
break;
}
} while (choice != "4");
Problem is, whatever I choose it stays in that method despite the return statement at the end , shouldn't that bring me back to the switch method?
Put the ability to add another choice into the loop. You're currently entering into an infinite loop because choice does not change.
String choice;
do {
choice = scanner.nextLine();
switch (choice) {
case "1":
encrypt();
break;
case "2":
decrypt();
break;
case "3":
makeKey();
break;
}
} while (!choice.equals("4"));
Observe that this has nothing to do with the methods being called; this is entirely regulated by the do...while loop.
You have a loop that goes in infinite loop as the choice is read only once. You enter 3 once and it goes into a loop with the condition choice != '4', and it is always true, as you dont change your choice. So your function is called over and over again. (It does break out of the function but it is called over and over again) Put the input lines inside the loop.
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
}