I am having problems with nesting some if-else statements, at least that is what I think the problem is. I have butchered this code several times trying to figure it out, so I decided to put it back to the original state and ask for some help. A user is asked to input an odd number between 3 and 15. I need to validate that input and if it is not between 3 and 15, output an error message. Same goes if it is not an odd number, it needs to output a different number. When running the code below, if I enter an even number, letter, or number <3 or >15 I get both error messages. If the input is an odd number between 3 and 15, it works fine. I know I have to differentiate between the two errors, just have not been able figure out how to do it and make the code run/work properly. Have also tried else if with no luck. Sure it is something silly, since most of my mistakes seem to be on the silly side. Thanks for your help!
public static void main(String[] args) {
// Declare variables
String inputString;
boolean done = false;
int numRows = 0;
// Prompt for user input
do
{
inputString = JOptionPane
.showInputDialog("Enter number of rows (odd number between 3 and 15): ");
// Validating input
try
{
numRows = Integer.parseInt(inputString);
}
catch (NumberFormatException e)
{
done = true;
}
if(numRows % 2 == 0) // Validating input is an odd number
done = true;
if((numRows < 3) || (numRows > 15))// Validating input is between 3 and 15
done = true;
else
done = false;
if(done)
JOptionPane.showMessageDialog(null, "Error, not an ODD number. Re-enter odd number between 3 and 15",
"Error", JOptionPane.ERROR_MESSAGE);
if(done)
JOptionPane.showMessageDialog(null, "Error, number not between 3 and 15. Re-enter odd number between 3 and 15",
"Error", JOptionPane.ERROR_MESSAGE);
}
while(done);
}
The interesting thing here is, you don't need the if statements. You can greatly simplify (and fix) your boolean expressions.
First, let's establish the behavior of (numRows < 3) || (numRows > 15). For this to be true, either numRows has to be strictly less than 3, or strictly greater than 15. This does not validate a range of numbers - you need to switch this to an AND statement. But even just doing that doesn't validate the correct range - you'll be validating everything that isn't between 3 and 15!
To fix that, you need to flip your inequalities.
You now have (numRows >= 3) && (numRows <= 15). For this to be true, numRows must be between the bounds of 3 and 15, inclusive.
Now, let's combine that with the check for odd/even, and you arrive at this:
done = (numRows % 2 == 0) || ((numRows >= 3) && (numRows <= 15));
The behavior of this statement is as such:
Either numRows is an even number, OR
numRows is bound between 3 and 15, inclusive.
I've also got some thoughts on you combining your JOptionPane statements as well, but that's more of a presentation issue than a code issue - I'll leave that as an exercise for the reader.
Related
This question already has answers here:
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed last month.
I need to create a method for my OOP lab, the details are as the following:
A ThreeWayLamp class models the behavior of a lamp that uses a
three-way bulb. These bulbs have four possible states: off, low light, medium
light, and high light. Each time the switch is activated, the bulb goes to the next
state (from high, the next state is off, from off to low etc). The ThreeWayLamp
class has a single method called switch() which takes a single int parameter
indicating how many times the switch is activated. (you need to throw an
exception if its negative). The Switch() method should simply print out to
System.out a message indicating the state of the bulb after it has changed.
public class ThreeWayLamp {
public String[] States = {"Off","LowLifght", "MediumLifght", "HighLight"}; // an array of the 4 states
public void Switch(int switchState){
//used an if condition to determine what to print based on the parameter switchState
if ((switchState <= States.length) && (switchState >= 0)){
System.out.println(States[switchState]);
}else if (switchState < 0 ){
System.out.println("Wrong input, try again with diffrent number");
}else if (switchState >= States.length){
} //This condition is the issue, how to form a condition that will solve this problem
}
If the parameter is larger than the array's length, an error will occur, so the issue is how to form a condition that will make the array loop again around itself when it reaches its last index.
For example, if the input was 5, then the method should print LowLight.
Is there a possible condition or function that could solve this issue, or should I change the entire structure of the code?
You can solve this problem by using a modulo operator:
System.out.println(States[switchState % States.length]);
Instead of using the less than condition, you can try using mod to repeat the indexes of your String array.
Try below code:
public class ThreeWayLamp {
public String[] States = {"Off","LowLifght", "MediumLifght", "HighLight"}; // an array of the 4 states
public void Switch(int switchState){
if ((switchState > 0){
System.out.println(States[switchState % States.length]); // states.length = 4 in your case
} else {
System.out.println("Wrong input, try again with diffrent number");
}
}
Using modulo you can ensure the index will always be within the size of the array
4 % 4 = 0
5 % 4 = 1
6 % 4 = 2
7 % 4 = 3
8 % 4 = 0
9 % 4 = 1
...
public void Switch(int switchState){
if ((switchState < States.length) && (switchState >= 0)){
System.out.println(States[switchState]);
} else if (switchState < 0 ){
System.out.println("Wrong input, try again with diffrent number");
} else {
Switch(switchState % 4);
// or
// System.out.println(States[switchState % 4]);
}
}
Also, variable and method names should start with a lower case
Sorry for lack of details, I made a few edits.
I've got a problem in my java class that I can't wrap my head around.
I need to make a program that draws random numbers which are formations in a 10 round competition.
In this competition judges score you based on the formations you draw.
You can only have 5 or 6 points per round. You can only have 6 points if you draw 3 - 2 point formations.
The range of formations is 1-38.
Formations 1-16 are worth 1 point.
The rest are worth 2 points.
I tried this.
int formation;
int points;
int round;
boolean isOnePoint;
int maneuvers = 0;
public void main(String args[]){
while(points < 5){
getRandomFormation();
if(points < 5 && isOnePoint){
points++;
}
else if(points == 4 && !isOnePoint && maneuvers < 3){
points +=2;
} maneuvers++;
}
}
public void getRandomFormation(){
formation = rand.nextInt(38);
if(formation < 17){ isOnePoint = true; } else isOnePoint = false;
}
The problem I am facing is with this code that I came up with I am still able to get something like:
// example of output round with points recieved
Round 6: 1, 2, 1, 2
The problem however, is that you cannot get 6 points with anything other than getting three random 2 point combinations...
What am I overlooking / missing in my code to be able to get it right?
Based off what you have posted you seem to only want three numeric values.
Change your while(points<5) to while(maneuver<3) and increment maneuver at the end of the loop.
That would be the quickest way to solve your problem. The logic in your if statements are quite convoluted. You only check to see the number of maneuvers in the second if statement which means that you can still meet the parameters for the first if.
for(int i=0;i<3;i++){
getRandomFormation();
if(isOnePoint)
points++;
else
points +=2;
}
I currently have java homework that I would appreciate some help with. We are to calculate a team record scenario.
We are given the following numbers:
Team1 Points
{23,45,65,20}
Opponent Points
{20,30,20,18}
I threw these into an array. I also created a public boolean. Basically, you are to pull these points from the array to the boolean? And let the boolean decide which team won? Obviously team1 has won, but we are supposed to let the computer decide, not the human.
Here is my code:
public class TeamScore {
public static boolean Winner(int team1Points, int opponentPoints) {
if (team1Points > opponentPoints) {
return true;
} else {
return false;
}
}
public static void main(String[] args) {
// Scanner in = new Scanner(System.in);
int[] team1Points = { 23, 45, 65, 20 };
int[] opponentPoints = { 20, 30, 20, 18 };
int team1 = 1;
int opponent = 1;
for (int i = 0; i < 5; i++) {
if (Winner(team1Points[i], opponentPoints[1])) {
team1 += 1;
} else {
opponent += 1;
}
}
for (int i = 0; i < 5; i++) {
if (team1 > 0 && opponent == 0) {
System.out.println("Team 1 has the perfect record!");
} else {
System.out.println("Win" + Arrays.toString(team1Points));
System.out.println("Loss" + Arrays.toString(opponentPoints));
}
}
}
Could anyone possibly help me? I am currently in programming II, but I did not have the best teacher in programming I. Any help would be appreciated!
EDIT:
I do not think this is a duplicate question because I already can fix it by changing the variable i-->1. My problem is that the computer thinks that team1 has already won regardless of the score.
When I run the code I am getting an java.lang.ArrayIndexOutOfBoundsException error. However when I change team1Points[i] to team1Points[1] then it goes okay and tells me that "Team 1 has the perfect record!". However, if I change some of the array values for team1Points to be less than opponentPoints then it still says "Team 1 has the perfect record!".
Not sure why you have a method Winner (also as Kevin said, it should be winner because of naming conventions) which turns ´(a > b)´ into a large if-statement. Similar stuff appear elsewhere in your code.
Your variables ´team1, opponent = 1´ inexplicably start with the value 1, am I to understand this as a way for your code to imply to a reader that both teams initialize at a win? Using 0 would probably make more sense.
Your game ought to crash from an indexoutofboundsexception at ´team1Points[i]´, as you have arrays of length 4, but your loops runs 5 times (the currently used range is [0-4], inclusive). Changing your loops to i=1 won't help, as the issue is that you eventually encounter team1Points[4] due to the i < 5 statement.
I don't know what game you are modelling or how it works, but the comparison ´Winner(team1Points[i],opponentPoints[1])´ looks like a blatant error to me (you always look at the opponents score for their second round).
Why are you printing your results 5 times? If you want to print the first message only when team1 won all rounds and the point for each round otherwise, you would need to use the loops counter as an index to the arrays in second case. First case should break loop so its not written five times, in addition you don't need to check team1>0 && opponent==0 as it's enough to only check if ´opponent==0´ (speaking of this conditional, it only works if you initialize the variables at 0 as I mentioned before). You could have checked if team1 equals size of the array instead, but imo thats more of a hassle than opponent==0.
Lastly, please fix your indenting. use the preview system so you can make double sure before posting.
Edit: Kevin also brings up a good point that you should be using the length of the array in your loops second statement.
Okay, this is part of the full code of a guessing game.
public static void Game(){ //Second page of game with option of continue playing when guessed close enough to answer.
Scanner scan = new Scanner(System.in);
GuessingGame testgame=new GuessingGame();
testgame.Generator();
int num = testgame.GetGenNum();
//Produces a random number between 1 and 100 inclusive of 1 and 100
System.out.println("Guess the target integer which is between 1 and 100 inclusive");
int guess=scan.nextInt();
int difference=(guess-num);
while(guess!=num){
int yesCounter=0;
System.out.println("Guess again " +num+" "+difference);
guess=scan.nextInt();
difference=(guess-num);
///something wrong here, shouldnt repeat if difference too big
if(difference<=5||difference>=-5){ //something wrong with the condition, it says its close enough even tho it isnt.
while(yesCounter<1){
System.out.println("Close enough, do you want to keep Guessing? Y/N ");
yesCounter++;
String play = scan.nextLine();
//play=play1;
while(!(play.equalsIgnoreCase("y")))
{
if(play.equalsIgnoreCase("n")){
System.exit(1);
}
else{
if((play.equalsIgnoreCase("y"))){
invalid();
guess=scan.nextInt();
}
else{
Game(); ///TAKE note as it might restart the game with new random integer
}
}
}
}
}
}
output is:
.........................
Play? Y/N
y
Guess the target integer which is between 1 and 100 inclusive
50
Guess again 44 6
44
Close enough, do you want to keep Guessing? Y/N
Guess the target integer which is between 1 and 100 inclusive
..........................
the problem is, when user guess a number, the condition is if the difference between the guess and the generated number is 5 or smaller, tell user that its close enough, and ask if user wants to continue guessing, but the condition wasn't fulfilled and yet still runs, can someone help?
while(!(play.equalsIgnoreCase("y")))
{
if(play.equalsIgnoreCase("n")){
System.exit(1);
}
else{
if((play.equalsIgnoreCase("y"))){
invalid();
guess=scan.nextInt();
....
That isn't right, if((play.equalsIgnoreCase("y"))) can never be true, since the loop it is in, explicitely cannot be entered if it is true. That's where your problem is, it will always restart the game because it calls Game() in the else-branch. In short, this is what you do:
boolean _true = true;
while(! _true) {
if(_true) {
//impossible
}
else {
Game(); //ALWAYS
}
}
Since you tagged your question with homework, I will not give the full correction, but now you know where it goes wrong, you should be able to figure out what you need to change in order to advance :)
You mixed or and and (Note: The condition you used (difference<=5||difference>=-5) is always true.). You may use any of the following
if (difference<=5 && difference>=-5) { ... } # difference is 5 or less
or
if (difference<=-5 || difference>=5) { ... } # difference is 5 or more
Better readable if you use Math.abs(...) instead:
if (Math.abs(difference)<=5) { ... } # difference is 5 or less
and
if (Math.abs(difference)>=5) { ... } # difference is 5 or more
resp.
if(difference<=5||difference>=-5) This says if the difference is less than 5 or greater than -5. All numbers are less than 5 or greater than -5, so this is always true.
I'm assuming what you want is something like if(Math.abs(difference)<=5). This will tell you if the absolute value of your difference variable is less than or equal to 5.
I am making a lottery program where I am asking if basically they would like a quick pick ticket. The numbers for their ticket of course would be random since it is a quick pick but the first four numbers range from 0-9 while the fifth number only goes up to 0-4. I am trying to ask them to input a button such as either "1" for no or "2" for yes if they don't want one then it would skip this step. But I am doing the boolean part incorrectly though. Could someone help me out?
Here is an example
System.out.println("Do you want Quick pick, 1 for no or 2 for yes? The first four numbers is from a separate set of 0 to 9 and the fifth number is from a set of 0 to 4.");
QuickPick=keyboard.nextInt();
if((QuickPick==1)){
return false;
}
if((QuickPick==2)){
return true;
int n = (int)(Math.random()*9+0);
System.out.println("Your QuickPick numbers are: " + kickerNumbers + kickerPowerball);
}
I still haven't gotten around to making the line of code for the final number of 0-4, just the first four numbers, so I haven't forgotten that.
Your code for case 2 immediately does a return true; which ends the method (I assume this is in a method) right then and there. Your other lines don't get execute at all.
Consider using a switch() statement here, it'll make it easier to read:
switch(QuickPick)
{
case 1:
return false;
case 2:
int n = (int)(Math.random()*9+0); // Why is n here? You don't do anything with it?
System.out.println("Your QuickPick numbers are: " + kickerNumbers + kickerPowerball);
return true;
default:
// Uh oh - someone did something bad maybe just return false?
return false;
}
Also your code for case 2 is definitely wrong, you need to generate a total of five numbers, using bounds 0-9 for the first 4 and 0-4 for the last one. You'll want to use Java's Random to do this (not Math.Random) something like:
Random rand = new Random();
int somethingRandom = rand.nextInt(10);
// Will give you an integer value where 0 < val < 10
// You can call rand.nextInt as many times as you want
To avoid doing your homework for you -- I'll follow the typical CS textbook line and say "Implementation left as an exercise."
The code after return true will not be executed - you need to put that prior to the return statement
Like Marvo said, you dropped a brace in your if.
But you also have faulty logic. I'm not quite sure what the purpose of the method you're in is (that returns a boolean value). But your last few lines will never be reached unless the user types in something like 3 or 42.
Assuming the method is supposed to a) Ask if the user wants a Quick Pick b) Calculate the Quick Pick, if desired c) Return true/false depending on whether the Quick Pick happened or not, you should have:
public boolean doQuickPick()
{
System.out.println("Do you want Quick pick, 1 for no or 2 for yes? The first four numbers is from a separate set of 0 to 9 and the fifth number is from a set of 0 to 4.");
QuickPick=keyboard.nextInt();
if((QuickPick==1)){
return false;
}
if((QuickPick==2)){
int n = (int)(Math.random()*9+0);
System.out.println("Your QuickPick numbers are: " + kickerNumbers + kickerPowerball);
return true;
}
}
As a separate issue, it'd be much better style to break that into several methods. boolean yesNoPrompt(String message), generateQuickPick(), etc.
Your question is kind of unclear, so I'm afraid I can't be much more help than that. Do post any clarifications / further questions if you have them.
if((QuickPick==2)){
return true;
int n = (int)(Math.random()*9+0);
System.out.println("Your QuickPick numbers are: " + kickerNumbers + kickerPowerball);
}
In the above copied code from your question, I see that you will be getting compilation errors in your IDE. Your IDE will complain about "Unreachable Code" for the line that is just below the return statement. So, you need to put the return statement at the end of the if block.