java: loop with switch only works sometimes - java

I'm really scratching my heard on this one. I'm new at java, and I'm having the strangest thing happen.
It's homework and I'm taking it one step at a time. My issue is the loop just keeps going and stops asking for input, just keeps looping until it terminates. My comments are largely for myself. I tried to extract what was causing my problem and post it here.
Look at the "hatColor" switch, you'll notice the way I'm making sure the user enter only from the options I have allotted. Should I be using a exception handler or something?
Anyway, in short, the problem is that if I enter something with spaces, the loop skips asking for my next input. Like, if I entered "y y y y y " to the scanner when first prompted, the program will terminate and not give me the chance to enter something else.
Please, anyone that understands this, I would really appreciate your help.
import java.util.Scanner;
public class Testing
{
static String hatColor;
public static void main(String[] args) {
gameStart();
}
public static void gameStart()
{
Scanner userInput = new Scanner(System.in);
boolean keepLooping = true;
int loopCounter = 0;
System.out.println("The game begins. You must choose between 3 different colored hats."
+ " You can type white, black, or gray.");
while (keepLooping == true)
{
hatColor = userInput.next();
switch(hatColor)
{
case "white":
System.out.println("You have chosen the path of well intentioned decisions.");
walletDrop();
//the two items below are only there in case the wallet drop somehow completes without calling another method
keepLooping = false; // stops the while loop from looping again.
break; // breaks out of the switch
case "gray":
System.out.println("You have chosen the path of free will.");
walletDrop();
keepLooping = false;
break;
case "black" :
System.out.println("You have chosen the path of personal gain.");
walletDrop();
keepLooping = false;
break;
default : //we could just copy this default chunk for later switch statements
if (loopCounter >= 3)//end program on them
{
System.exit(0);
}
System.out.println("You didn't enter a usable answer. Try again");
loopCounter++;
if (loopCounter == 3)
{
System.out.println("This program will self destruct if you enter another invalid response.");
}
}//end of switch
}//end of while
}//end of game start method
public static void walletDrop()
{
System.out.println("wallet drop successful");
}
}

So I have actually solved this right after posting. In case someone else needs to look here for help:
The issue I was experiencing was due to using the scanner method
variableToAssign = scannerName.next();
instead of
variableToAssign = scannerName.nextLine();

Related

Problem with Switch statement in for loop for turn based RPG battle in java

Essentially, I've put a switch statement in a for loop. It has not been working as intended. I think it has something to with the break statement.
What I want the loop to do is go to the first element in the array list, execute code based on the 'action' String, then go to the next until the list ends. However, it seems that whenever I run the program it only executes the code in the first index. Here is some code for the BattleManager class:
Scanner input = new Scanner(System.in);
String cmd;
String[] dtct;
Arraylist<BattleAction> turns = new ArrayList<BattleAction>();
public void handle() {
cmd = input.nextLine();
dtct = (cmd.split());
switch(dtct[0]) {
case "attack":
turns.add(new BattleAction("playerattack"));
getenemyaction();
turnsequence();
break;
case "defend":
getenemyaction();
turnsequence()
}
}
public void getenemyaction() {
turns.add(new BattleAction("enemyattack"));
}
public void turnsequence() {
Collections.sort(turns);
print("Size: " + turns.size())
for (int i = 0; i != turns.size(); i ++) {
switch(turns.get(i).action) {
case "playerattack":
playerattack();
break;
case "enemyattack":
enemyattack();
break;
}
}
}
public void playerattack() {
print("Player attack");
}
public void enemyattack() {
print("Enemy attack");
}
When I run the program here is the output I am getting with the attack command:
attack
Size: 2
Player Attack
However when I use the defend command the output is:
defend
Size: 1
Enemy Attack
The desired output would be for turnsequence() to go through turns and do check action for the desired code to be executed, like this:
attack
Size: 2
Player Attack
Enemy Attack
I have done my best to cut out as much unnecessary information at possible to prevent confusion. Thank you so much for reading my post! I really appreciate your help!

I am making a turn based combat thing in Java just to see if I can figure it out myself, But I have a problem

So, I am making a turn based combat class in java for when I try to make an rpg. I will provide the code below. I have a public static String called state and a Scanner called sc, and a switch statement for state. Before the switch statement, state = "0". case "0" of the switch statement prints out "A Slime appears\n(1)Attack\n(2)Defend" and makes state = "1".
case "1" has another switch statement in it for sc.nextLine. in this switch statement, case "1" generates damage for me and the slime, subtracts them from our hp, and prints out a message for the attacks, and makes state = "2". case "2" generates the half damage of the slime and prints out a message for the slimes damage, being half what it would be, with you defending inside of attacking and makes state = "2". So, either attack or defend, it makes state = "2". Then for the first switch statement, case "2" prints out the options of attack and defend again and makes state = "1".
When I run the code, it prints the first message sayinjg the slime appears and either attack or defend, but I cant type anything in to console and the code is terminated. I am using Eclipse.
package dfguy;
import java.util.Random;
import java.util.Scanner;
public class Main {
public static String state;
public static int cmhp = 40;
public static int cchp = 40;
public static int smhp = 20;
public static int schp;
public static Random dmg = new Random();
public static Scanner sc = new Scanner(System.in);
public static void main(String[] args) {
state = "0";
switch(state) {
case "0":
System.out.println("A Slime appears!\n(1)Attack\n(2)Defend");
schp = smhp;
state = "1";
break;
case "1":
switch(sc.nextLine()) {
case "1":
int cdmg = (dmg.nextInt(6) + 5);
int sdmg = (dmg.nextInt(5) + 4);
System.out.println("You attack the Slime for " + cdmg + "damage!\nThe Slime attacks "
+ "you for " + sdmg + "damage!");
schp = schp - cdmg;
cchp = cchp - sdmg;
state = "2";
break;
case "2":
int sbdmg = (dmg.nextInt(3) + 2);
cchp = cchp - sbdmg;
System.out.println("You defend against attack! The Slme attacks for " + sbdmg + "damage!");
state = "2";
break;
}
break;
case "2":
System.out.println("(1)Attack\n(2)Defend");
state = "1";
break;
}
}
}
There is no loop around the switch to run it more than once - so you go through with state=0, flip it to state=1 and then you're done.
For now you can get away with while(true) { /*your switch*/ } but eventually you probably want while(!dead) { ... }. Also perhaps put your whole switch into a different method rather than doing it all in main.
You are writing a proper state machine, but one key thing about a state machine is that it needs to be called over and over repeatedly. The first time through the state is one thing and later it changes to something else.
The thing is, each state may run over and over. So you have to ask your question in one state, and wait for the response in the next. If you leave it in that state it's just going to keep spamming the question. So state 0 should ask the question, then state 1 just loops waiting for a response and the response sends you to state 2 or 3 for more text.
Or you can even have state machines within state machines. The point is that looping code keeps reaching the same point until it's time to do something else.
The whole thing has to be inside a while loop. You can use while(true) or while(1), or even for(;;) but I like to have a boolean value that I can use so that if I ever want to end the program I can just set it to false and the program ends.
Pseudo-code:
boolean running = true;
while(running){
switch(state){
// etc. etc. for the state machine.
// if you want to end the program somewhere then set running to false
}
}

Make a method run in a method java for my game?

I'm struggling with dealing of inventory scan for my game, it basically search for the user inventory if "Flying Broom" if present(it was collected in another method and upload the code is too long), if not it will run the method challengedragon() again; else, it will proceed to the next challenge if the item is present.I was think of inserting method as parameter but it is not possible. This is what I have now. :
public class Main {
String Flyingbroom = "Flying broom";
public static void main(String[] args) {
Player_inventory p = new Player_inventory();
challengedragon();
}
public void challengedragon() {
System.out.println("a Hungarian Horntail dragon! Let's start the battle! You have four options to beat the dragon: ");
System.out.println("1: Fly away with your broom");
System.out.println("2: Fight the dragon");
System.out.println("3: Just run to the egg and get it");
System.out.println("4: Hide behind a rock");
System.out.println("5: Go back to Hogwart");
System.out.println("Your choice is: ");
Scanner in = new Scanner(System.in);
int dragonfightchoice = in .nextInt();
if (dragonfightchoice == 1) {
{
p.Scanitem(Flyingbroom,
"Good choice! You managed to kill the Hungarian Horntail dragon and to get the golden egg",
"You dont have the broom. Try to search for the broom",
playerHP);
proceedtonextchallengelake();
} else if (dragonfightchoice == 2) {
System.out.println("The Hungarian Horntail dragon fired you. - 70HP. ");
playerHP -= 70;
challengedragon();
} else if (dragonfightchoice == 3) {
System.out.println("Bad idea... You lose 100 HP");
playerHP -= 100;
challengedragon();
} else if (dragonfightchoice == 4) {
System.out.println("The dragon found you. You lose 30 HP");
playerHP -= 30;
challengedragon();
} else if (dragonfightchoice == 5) {
Hogwart();
} else {
invalid();
challengedragon();
}
}
For my inventory class:
public void Scanitem(String item, String trueouputext, String textifconditionisnotmet) {
if (inv.contains(item) == true) {
System.out.println(trueouputext);
} else if (inv.contains(item) == false) {
System.out.println(textifconditionisnotmet);
}
public static ArrayList<String> inv = new ArrayList<String>();
Do you guys have any recommendation?
Are there additional steps to populate the inventory (variable inv)?
Also, wouldn't you want ScanItem to answer true or false, depending on whether the item was found? Then you would have something like this:
public boolean scanitem(String item) {
return ( inv.contains(item) );
}
if ( p.scanItem(flyingBroom) ) {
System.out.println("Good choice! You managed to kill the Hungarian Horntail dragon and to get the golden egg");
} else {
System.out.println("You dont have the broom. Try to search for the broom");
}
That will get you closer to what you want. However, there are two other issues which you'll need to put into your code:
You will need a loop of some sort, instead of calling challengeDragon from inside of itself.
Somehow, the return value from scanItem must be used to decide whether to loop.
Currently, you do a nested call of a method each time the player does something, this means that sooner or later you'll run out of the stack. A better idea for the framework for your text-based adventure is to have some kind of a description of the current game's state. The state could be represented as an object that contains the following information:
where's the player currently at (on which step, at which "crossing" etc.)
the player's stats (HP, available skills etc.)
the contents of the player's inventory
some previously made choices affecting the game
Then, the code could be written as a simple loop that does the following:
process player's input
change the state according to the player's input
present the player with available options according to the new state
wait for the next input
repeat

Java help regarding looping (do loops)

I'm trying to make a very basic game where you guess a number between 1-1000 using a do loop. Everything works, except when I finally make the correct guess, I am still prompted to make another guess, and when I enter the same correct guess again, the program terminates like it's suppose to.
Why do I have to make that extra guess to finally get my program to work? Am I looping around an extra time? Also, if I make a correct guess (the compiler will say I am correct then still prompt me), then a wrong guess (the compiler will tell me I'm wrong), then the correct guess again, the program will only terminate after I make the correct guess a second time.
The second do loop at the bottom is what I put in my main method. Everything above is in a method I wrote called play.
public static boolean play()
{
boolean c;
int n = 0;
do {
String input = JOptionPane.showInputDialog("Enter a number between 1-1000");
n = Integer.parseInt(input);
if (n == guess)
{
System.out.println("Correct");
c = true;
}
else if (n < guess)
{
System.out.println("Not Right");
c = false;
}
else
{
System.out.println("Not Right");
c = false;
}
guess++;
} while (c == false);
return c;
}
In main method:
do {
game1.play();
} while (game1.play() != true);
This loop runs the play method twice in each iteration of the loop :
do {
game1.play(); // first call
} while (game1.play()!=true); // second call
You are not testing the value returned by the first call, so even if it returns true, you would still call game1.play() again, which will display "Enter a number between 1-1000" again.
Replace it with:
boolean done = false;
do {
done = game1.play();
} while (!done);
This would only call play() one time in each iteration of the loop.
That said, I'm not sure why you need the outer loop.
You can just replace in with one call to game1.play(), since game1.play() will loop until the correct number is entered.

How to write code that if something happens nothing else happens afterward?

Lets say if the last level of a game is beaten then you dont show a dialog box asking if the player wants to go on to the next level, but rather to the mainmenu. SO basically if something happens the things that are supposed to happen afterward dont.
private void submitButtonActionPerformed(java.awt.event.ActionEvent evt) {
final ImageIcon pokeballIcon = new ImageIcon("C:\\Users\\bacojul15\\Pictures\\pokeball5.gif");
final ImageIcon pokemoneggIcon = new ImageIcon("C:\\Users\\bacojul15\\Pictures\\nidoking.gif");
final ImageIcon pokemonredIcon = new ImageIcon("C:\\Users\\bacojul15\\Pictures\\red.gif");
String userAnswer = answertextArea.getText().trim();
if (userAnswer.equalsIgnoreCase(answers.get(questionNumber))) {
answerLabel.setText("Correct");
levelScore ++;
triviagui.totalScore ++;
} else {
answerLabel.setText("Incorrect");
}
answertextArea.setText("");
questionNumber++;
if(questionNumber == questions.size()){
JOptionPane.showMessageDialog(null, "Your score for this level was : " + levelScore + " out of 10. \n Your total score is " + triviagui.totalScore, "Scores",JOptionPane.INFORMATION_MESSAGE, pokeballIcon );
if(difficulty == 3){
JOptionPane.showMessageDialog(null, "Good job you beat the game! \n Your total score was " + triviagui.totalScore + " out of 30.", "Thanks for playing!", JOptionPane.INFORMATION_MESSAGE, pokemonredIcon);
triviagui.questionFrame.setVisible(false);
triviagui.mainFrame.setVisible(true);
}
int leveloptionPane = JOptionPane.showConfirmDialog(null,"Would you like to go on to the next level?" , "Next Level?", JOptionPane.YES_NO_OPTION, levelScore, pokemoneggIcon);
if(leveloptionPane == JOptionPane.YES_OPTION){
difficulty++;
triviagui.questionFrame.setVisible(false);
triviagui.questionFrame=new QuestionFrame(difficulty);
triviagui.questionFrame.setVisible(true);
}
if(leveloptionPane == JOptionPane.NO_OPTION){
triviagui.questionFrame.setVisible(false);
triviagui.mainFrame.setVisible(true);
}
return;
}
updateQuestionScore();
}
You simply want to do:
if(something happens) {
return;
}
If you want to jump out from method use
return;
example of something like that:
public void myMethod(){
if(mynumber==5){
doThis();
}else{
return;
}
/*
*do something else <- this wont be executed if number doesnt equal 5
*cause we are already out of method.
*/
}
If you dont want to jump out from whole method bud only form part of it for instance loop.
break;
example of that:
public void myMethod(String[] stringArr){
for(String s:stringArr){
if(s.equals("hello")){
break; //get me out of this loop now !
}else{
s+="alriight";
}
}
}
doSomethingElse();//this will be executed even if you go thru break; you are still inside method dont forget.You are just out of loop
}
There are better uses for that maybe examples aint best bud you will understand how to use it form this:).
When you use break or return.In eclipse for instance you will be shown Where you actually exit. it will highlight "}"
There are several ways to do this:
You can return from a method.
You can break to exit a loop or continue to start the next iteration of the loop.
You can use an 'else' to only execute other code if the first section did not execute.
You can set a boolean flag variable and then check for that elsewhere in your code.
Depending on what you are trying to do each of these is sometimes the best way, sometimes not the best way.

Categories