I want my program to do the certain code only if the actors variable is <=5 && >0
else I want to go back and ask different question again:
System.out.println("\nEnter actors number(max.5): ");
int actorsNumber = scanner.nextInt();
scanner.nextLine();
if (actorsNumber <= 5 && actorsnumber>0) {
for (int i = 1; i <= actorsNumber; i++) {
System.out.println("\nEnter name and surname of the " + i + " actor: ");
String[] parts2 = scanner.nextLine().split("\\s+");
String actName = parts2[0];
String actSurname = parts2[1];
actorName.add(actName);
actorSurname.add(actSurname);
}
}
So when the condition is false for example actors number = 7 then I want to tell the user: "Enter the valid actors number(1-5)" and do the for loop again if the actorsnumber is 1-5 instead ask again "Enter the valid actors number(1-5)"
You need to ask user to enter number in a loop. The condition of the loop will be the condition of your if. Then after exiting the loop (which means user enter a correct number), enter your for loop.
This will look like that :
int actorsNumber = -1; //force a wrong value at the beginning
while(actorsNumber < 1 || actorsNumber > 5) {
//Ask user to enter a number between 1 and 5
//store this number in actorsNumber
}
//As we exited the while-loop, actorsNumber is between 1 and 5
//Put your for-loop here
while(!scanner.nextLine().equals("quit")) {
if (actorsNumber <= 5 && actorsnumber>0) {
for (int i = 1; i <= actorsNumber; i++) {
System.out.println("\nEnter name and surname of the " + i + " actor: ");
String[] parts2 = scanner.nextLine().split("\\s+");
String actName = parts2[0];
String actSurname = parts2[1];
actorName.add(actName);
actorSurname.add(actSurname);
}
}
}
Or something like that, point is, use a while loop on the scanner.
As #apexlol stated, your code should be in a loop. However, do-while loop is more convenient than while loop since that way, the loop executes at least once no matter what.
Related
I'm creating a basic word puzzle program as a personal project where a user sees a set of letters and has to create as many words from that set of letters (ie. I T E R; rite, tire, er). A score is added up for each time they get a correct word from one of the matches in a String array. If an incorrect guess is made (the guess does not appear in the array), a final score and the time it took are displayed. My problem is that after I input a value (re) and then enter another correct value (tire), the loop doesn't allow me to add another guess but exits the loop, and the score only gets updated to the first correct guess, not both. How can i change the logic so that i can enter any of the words from the array list in any order and get the correct score?
I tried to move the cont boolean outside the for loop. I tried to add the cont boolean in an else if statement when checking the if array item does not equal the input. Same issue persisted, i can enter re then tire and the program stops. Here is my code.
import java.sql.SQLOutput;
import java.time.Duration;
import java.time.Instant;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Instant starts = Instant.now();
String guess;
int score = 0;
Scanner input = new Scanner(System.in);
String seconds;
String[] puzzle1 = {"iter", "rite", "tier", "tire", "trie",
"ire", "rei", "ret", "rit", "tie", "er", "et", "re", "te", "ti"};
Boolean cont = true;
System.out.println("How many words can you create with the following letters:" +
"\n T I E R");
System.out.println("Enter a guess: ");
String userInput = input.nextLine();
int k= 0;
while (cont) {
for (int i = 0; i < puzzle1.length; i++) {
if (puzzle1[i].equals(userInput)) {
score += 100;
System.out.println("Good! Enter another guess: ");
userInput = input.nextLine();
}
}
cont = false;
}
Instant ends = Instant.now();
long mins = Duration.between(starts, ends).toMinutes();
long time = Duration.between(starts, ends).toSeconds();
long actual = time % 60;
if (time <= 9) {
seconds = "0" + actual;
} else {
seconds = String.valueOf(time);
}
System.out.println("Your time was " + mins + ":" + seconds + " and with a score of " + score + " points.");
}}
here is the output
How many words can you create with the following letters:
T I E R
Enter a guess:
re
Good! Enter another guess:
tire
Your time was 0:05 and with a score of 100 points.
It seems like you just need to figure out your logic around cont = false, as in, what would you want to make this program terminate, a wrong answer maybe?
Keep cont = true until you're ready to leave the loop. Also, you may want to consider using a List<String> instead of String[], this allows you to remove the nested for-loop in favor of the contains method.
e.g. replace
for (int i = 0; i < puzzle1.length; i++) {
if (puzzle1[i].equals(userInput)) {
score += 100;
System.out.println("Good! Enter another guess: ");
userInput = input.nextLine();
}
}
with simply
if(puzzle.contains(userInput)) {
score += 100;
System.out.println("Good! Enter another guess: ");
userInput = input.nextLine();
} else {
System.out.println("Terrible!: ");
cont = false;
}
Introduction
The code I am going to present now is part of a loop for a game. I am having problems with a error handling (not through exceptions).
Problem
This next function takes 4 int variables (row_1, col_1, row_2, col_2) which have to be checked if they are less than (size-1).
The reason behind is that we are working with a matrix and the range is from 0 to (size-1).
So if the user inputs less than 0 or more than (size-1) it should be asking again for an input
Code
public static void gameLoop()
{
//While you still play (true) or if (false) -> end game
showMatrix(gameMatrix);//Cheat
while(play == true)
{
showMatrix(displayMatrix);
System.out.println("--------------------");
System.out.println("Input first row and col press enter between inputs");
System.out.print("First row: ");
row_1 = scan.nextInt();
System.out.print("First column: ");
col_1 = scan.nextInt();
System.out.println("Input second row and col press enter between inputs");
System.out.print("Second row: ");
row_2 = scan.nextInt();
System.out.print("Second column: ");
col_2 = scan.nextInt();
if (row_1 == row_2 && col_1 == col_2)
{
System.out.println("I tested this!");
showMatrix(displayMatrix);
System.out.println("--------------------");
System.out.println("[ERROR] Input not valid! Try again");
System.out.println("Input first row and col press enter between inputs");
System.out.print("First row: ");
row_1 = scan.nextInt();
System.out.print("First column: ");
col_1 = scan.nextInt();
System.out.println("Input second row and col press enter between inputs");
System.out.print("Second row: ");
row_2 = scan.nextInt();
System.out.print("Second column: ");
col_2 = scan.nextInt();
}
else if ((row_1 > size || row_1 < 0) && (row_2 > size || row_2 < 0) && (col_1 > size || col_2 < 0) && ((col_2 > size || col_2 < 0)))
{
System.out.println("I tested that!");
showMatrix(displayMatrix);
System.out.println("--------------------");
System.out.println("[ERROR] Input not valid! Try again");
System.out.println("Input first row and col press enter between inputs");
System.out.print("First row: ");
row_1 = scan.nextInt();
System.out.print("First column: ");
col_1 = scan.nextInt();
System.out.println("Input second row and col press enter between inputs");
System.out.print("Second row: ");
row_2 = scan.nextInt();
System.out.print("Second column: ");
col_2 = scan.nextInt();
}
Turn(row_1, col_1, row_2, col_2, gameMatrix);
check = checkEndgame(gameMatrix, displayMatrix);
if(check == false)
{
System.out.println("Would you like to play again? Y/N");
game_option = scan.next();
if ("Y".equals(game_option) || "y".equals(game_option))
{
createGame();
gameLoop();
}
else if ("N".equals(game_option) || "n".equals(game_option))
{
play = false;
}
}
}
}
Part of the code with the problem
if (row_1 == row_2 && col_1 == col_2){}
else if ((row_1 > size || row_1 < 0) && (row_2 > size || row_2 < 0) && (col_1 > size || col_2 < 0) && ((col_2 > size || col_2 < 0))){}
Question
I do not understand where I did go wrong with this logic after testing numbers which should trigger it.
Notes
Feel free to judge the code and help me with design or error handling
Those System.out.println("I tested that!"); && System.out.println("I tested this!"); are debug stdout.
Suggestions:
Console applications are unforgiving and unless handled carefully at the development stage can lead to an application no one wants to use because of its inability to handle input Errors or simple typing mistakes. How many times are you willing to restart an application.
People do make entry mistakes and the more informative your application is the less mistakes a User will make. For example, if you only want Users to input a value from 0 to let's say 10 then let them know what the requirements are, constantly:
Please enter the numerical values for FIRST Row and Column:
First Row (0 to 10): 7
First Column (0 to 10): |
You will always need to validate input so as to ensure that what is provided will actually process without any errors being generated. As you well know the keyboard is a pretty big input device with an awful lot of buttons on it and any one of then can be accidentally struck during input without the User even being aware of it. After all, everyone that owns a keyboard is automatically a typing master and can pump out 400 words per minute without looking at the screen. Well....so it seems and to be quite honest, I'm am by no means any exception to that.
Allow the User to carry out a re-entry should an error occur. Don't be afraid to utilize while loops for this, even nested ones. If handled correctly, there will be no issues with them.
Although this portion of your application is small, allow the User to quit at any time unless of course the current point needs to be completed in order to accomplish a clean exit. It's nasty when you can't get out of an application unless you finish it. especially when you just don't want to.
Where you can, use Methods or Classes to reduce or eliminate code duplication. Sometimes it is easier to read code when its long and drawn out with lots of duplication but in most cases it doesn't take long to get sick of looking at it. It can make you dizzy after a while. The old excuse "I just do it to get it working then I clean it up" really doesn't fly, well for the most part. If you can eliminate code duplication right away that way you don't have to code your application twice...or three times...or maybe more. Yes, we all do it in one form or another and again, I'm no exception to this.
By removing most code duplication and adding a small method or two your particular code segment might look something like this:
Scanner scan = new Scanner(System.in); // Declare Scanner (here for sake of this demo)
String LS = System.lineSeparator(); // System line Separator.
boolean play = true; // Play flag
int size = 8; // 8 is used for sake of this demo
String range = "(0 to " + (size - 1) + ")"; // Range so we don't have to keep typing it.
String[] rowCol; // Array to hold Row and Column string numerical values
String border1 = String.join("", Collections.nCopies(72, "-")); // Text Border 1 (-)
String border2 = String.join("", Collections.nCopies(42, "=")); // Text Border 2 (=)
while (play) {
String input = ""; // Input from scanner goes in this variable
rowCol = new String[4]; // Initialize Array
// Declare & init int variables to hold input integer values (if desired)
// Un-comment the below line if you want this...
// int row_1 = -1, col_1 = -1, row_2 = -1, col_2 = -1;
// Inform of what is required...
System.out.println(border1);
System.out.println("Please enter the numerical values for FIRST and "
+ "SECOND Rows and Columns." + LS + "Follow the provided prompts. "
+ "You can Enter 'q' or 'quit' at any time to" + LS + "end the game.");
System.out.println(border1);
// Get Input from User
for (int i = 0; i < rowCol.length; i++) {
// Set up current prompt...
String prompt = LS;
switch (i) {
case 0:
prompt += "Enter First Row Value " + range + ": ";
break;
case 1:
prompt += "Enter First Column Value " + range + ": ";
break;
case 2:
prompt += "Enter Secomd Row Value " + range + ": ";
break;
case 3:
prompt += "Enter Second Column Value " + range + ": ";
break;
}
input = ""; // Clear input variable
// Get the actual input from User and validate.
while (input.equals("")) {
System.out.print(prompt); // Display prompt
input = scan.nextLine(); // Get keyboard input from User
// Validate input...
if (!validateUserRowColInput(0, (size - 1), input)) {
input = ""; // Input was invalid so clear input variable
continue; // Re-prompt the User for proper input
}
rowCol[i] = input; // All is good so add input to Array element at index i.
}
}
// Display what was provided.
System.out.println(border2);
System.out.println("Row 1/Column 1 = " + rowCol[0] + "/" + rowCol[1] + LS
+ "Row 2/Column 2 = " + rowCol[2] + "/" + rowCol[3]);
System.out.println(border2 + LS);
}
The rest of your game loop code you can add yourself. In the above code a simple String Array (named rowCol) is utilized to hold the values supplied by a User. This allows us to use a single for loop nested within the main play while loop to prompt for all 4 inputs from the User therefore eliminating some duplicate code and carrying out input validation all in one house so to speak.
If you want to convert the inputs to Integer (int's) then you could do something like this instead (directly after the for loop):
/* Array index 0 and 1 now contains the string numerical
values for First Row and First Column. Array index 2 and
3 now contains the string numerical values for Second Row
and Second Column. If you just can't wrap your head around
dealing with Arrays and indexes from this point then do
something like the following: */
// Convert String Array elements to integers
row_1 = Integer.parseInt(rowCol[0]);
col_1 = Integer.parseInt(rowCol[1]);
row_2 = Integer.parseInt(rowCol[2]);
col_2 = Integer.parseInt(rowCol[3]);
// Display what was provided.
System.out.println(border2);
System.out.println("Row 1/Column 1 = " + row_1 + "/" + col_1 + LS
+ "Row 2/Column 2 = " + row_2 + "/" + col_2);
System.out.println(border2 + LS);
The validateUserRowColInput() method which as it implies, validates the Users input to respect the desired rules for the code segment above. It is called directly after the User supplies input. The validation rules are basically what you had laid out within your post and the validation is done upon each input supplied rather than waiting for all four inputs to be provided:
Validation Rules:
No Blank entries allowed;
Only numerical characters can be supplied, no alpha characters other
than q or the word quit are accepted (not case sensitive);
If q or the word quit is supplied the program ends;
Row 1 and or Row 2 can not be Less Than 0;
Column 1 and or Column 2 can not be less than 0;
Row 1 and or Row 2 can not be Greater Than (size - 1);
Column 1 and or Column 2 can not be Greater than (size - 1);
The User is of course informed if a rule is broken and given the opportunity to make a correct entry. Here is the validateUserRowColInput() method:
/**
* Validates the User's Row and Column values input. This method checks to
* ensure only numerical characters were entered. It also ensures the the
* numerical value entered is between and or equal to the supplied minValue
* and maxValue.
*
* #param minVal (Integer) The minium Allowable integer value to be
* entered.
* #param maxVal (Integer) The maximum allowable integer value to be
* entered.
* #param inputString (String) String representation of the integer value
* supplied.
*
* #return (Boolean) True if the entry is valid and false if it is not.
*/
private static boolean validateUserRowColInput(int minVal, int maxVal, String inputString) {
String LS = System.lineSeparator();
if (inputString.equals("")) {
System.out.println("Invalid Entry! You must supply a numerical "
+ "value from " + minVal + " to " + maxVal + ".");
return false;
}
if (inputString.equalsIgnoreCase("q") || inputString.equalsIgnoreCase("quit")) {
System.out.println("We hope you had fun. Bye Bye");
System.exit(0);
}
if (!inputString.matches("\\d+")) {
System.out.println("Invalid input supplied (" + inputString + ")! "
+ "You can not supply alpha characters, only" + LS
+ "numerical values are allowed!. Please try again...");
return false;
}
int num = Integer.parseInt(inputString);
if (num < minVal || num > maxVal) {
System.out.println("Invalid input supplied (" + inputString + ")! "
+ "The numerical value you supply can not be" + LS + "less "
+ "than " + minVal + " and no greater than " + maxVal + ". "
+ "Please try again...");
return false;
}
return true;
}
Yes....this can all be reduced even more.
You should use a do...while loop to make sure the inputs are valid. It takes a boolean argument:
do {
// All the System.out.println and Scanner stuff...
} while(!checkAnswers(row_1, row_2, col_1, col_2));
Now we have to write the function checkAnswers that will return the boolean to state whether the user is allowed to quit the do...while loop:
public static boolean checkAnswers(int row_1, int row_2, int col_1, int col_2) {
// I don't know why you needed that condition, but I let it there
if(row_1 == row_2 || col_1 == col_2) return false;
// check if the rows and colls are in the range 0...(size - 1)
int[] rowsAndCols = {row_1, row_2, col_1, col_2};
for(int i : rowsAndCols)
if(i < 0 || i >= (size - 1)) return false;
// If everything is good we can quit the do...while loop
return true;
}
My program is supposed to make sure each value the user enters is between 10-100. The value is then stored in the array. That part works fine. The other condition is that the value the user enters has to be different from all the other arrays. ie...array[0]=20 so all of the other arrays can no longer equal to be set to 20. I've been trying to solve this but I'm just not sure where to go. I tried setting statements after my while(userInput < 10 || userInput > 100) to check for any repeats and that worked. The problem was then the user could enter values less than 10 and greater than 100. Any help would be greatly appreciated!
public static void main(String[] args) {
//Creating scanner object
Scanner input = new Scanner(System.in);
int[] array = new int[5];
int counter = 0;
while(counter < 5)
{
for(int x = 0; x < array.length; x++)
{
System.out.print("Enter number between 10 & 100: ");
int userInput = input.nextInt();
while(userInput < 10 || userInput > 100)
{
System.out.print("Please enter number between 10 & 100: ");
userInput = input.nextInt();
}
array[x] = userInput;
System.out.println(array[x]);
counter++;
}
}
System.out.println();
System.out.println("The value of Array[0]: " + array[0]);
System.out.println("The value of Array[1]: " + array[1]);
System.out.println("The value of Array[2]: " + array[2]);
System.out.println("The value of Array[3]: " + array[3]);
System.out.println("The value of Array[4]: " + array[4]);
}
}
You should get rid of the for and second while loop, and check if the value entered is in the desired range.
If it is, you verify for duplicates, store it in the array and increment the counter. If it’s not, you show the bad input message.
Either way, it continues to ask for an valid input until the counter gets to 5.
I hope it helps!
I changed your logic a little bit, see if you can understand it
(There are better ways of doing this, but I think this is more understandable)
public static void main(String[] args) {
//Creating scanner object
Scanner input = new Scanner(System.in);
int[] array = new int[5];
int counter = 0;
while(counter < 5)
{
System.out.print("Enter number between 10 & 100: ");
int userInput = input.nextInt();
if(userInput < 10 || userInput > 100)
{
System.out.print("Please enter number between 10 & 100.\n");
}
else {
//This is a valid input, now we have to check whether it is a duplicate
boolean isItDuplicate = false;
for(int i = 0; i < counter; i++)
{
if(userInput == array[i])
{
isItDuplicate = true;
}
}
if(isItDuplicate == true)
{
System.out.print("Please enter a number that is not a duplicate.\n");
}
else
{
array[counter] = userInput;
System.out.println(array[counter]);
counter++;
}
}
}
System.out.println();
System.out.println("The value of Array[0]: " + array[0]);
System.out.println("The value of Array[1]: " + array[1]);
System.out.println("The value of Array[2]: " + array[2]);
System.out.println("The value of Array[3]: " + array[3]);
System.out.println("The value of Array[4]: " + array[4]);
}
Don't use variable counter when var x does the same thing for you.
Don't use nested loops when the limiting condition of both loops need to be checked together in each iteration. Merge those loops into one wherever possible.
First of all, get rid of your nested loops. They're redundant. Let's look at your problem's specification. Your input needs to fulfill 3 requirements:
Be greater than or equal to 10
Be less than or equal to 100
Be a unique element inside the array
The first two conditions are simple enough to check. For the final condition, you need to search the values inside the array and see if there are any matches to your input. If so, the input is invalid. A simple way to approach this is to check every member of the array and to stop if a duplicate is found. There are better, more efficient ways to do this. Don't be afraid to search the internet to learn a searching algorithm. Below is a simple solution to your problem. It's far from ideal or efficient, but it's easy enough for a beginner to understand.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int[] array = new int[5];
int counter = 0;
int userInput;
while(counter < 5) {
System.out.print("Enter a number between 10 & 100: ");
userInput = in.nextInt();
if( (userInput >= 10 && userInput <= 100) && !searchDuplicates(array, userInput) ) {
array[counter] = userInput;
counter++;
} else {
System.out.println("Invalid value entered");
}
}
for(int i = 0; i < array.length; i++)
System.out.println("Value " + (i + 1) + ": " + array[i]);
}
private static boolean searchDuplicates(int[] array, int input) {
for(int i = 0; i < array.length; i++)
if(array[i] == input)
return true;
return false;
}
}
I am having a problem with my while loop. It is compiling but it isn't entering while loop and it skips to next condition.
public class Tr {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String name = "";
while(name.length() > 1) {
System.out.print("Enter name : ");
name = in.nextLine( );
if(name.length() > 1) {
System.out.println("It needs to be greater than 1");
}
}
}
}
That's because the name has 0 length and hence, the control never enters while. You need to use do..while loop so that it executes at least once, e.g.:
do{
System.out.print("Enter name : ");
name = in.nextLine( );
if(name.length() <= 1){
System.out.println("It needs to be greater than 1");
}
}while(name.length() <= 1);
It appears that the logic you want is to prompt the user for a name, and keep prompting until a name with length greater than one is entered. A do loop would seem to fit well here:
Scanner in = new Scanner(System.in);
String name;
do {
System.out.print("Enter name with length > 1: ");
name = in.nextLine();
// you can print an optional feedback message
if (name.length() <= 1) {
System.out.println("length needs to be greater than 1");
}
} while (name.length() <= 1);
Your variable name gets initialized to name = "";, so name.length() == 0;.
Your while condition checks whether the length greater than 1, and it isn't so it skips.
Because name.length() always returns 0 so your condition won't ever be true.
(name.length() < 1)
change this condition in our while and if conditions.
You have defined an empty string called name and the condition for your while loop condition checks if the length of name is greater than 1 or not.
This is the code I have right now
for (int i = 0; i <= listOfPeople.length; i++){
String name = scnr.nextLine();
System.out.println("Person " + (i + 1) + ": ");
listOfPeople[i] = name;
}
List of people is a properly declared list of Strings with the length of a value the user sends in. The error that is happening is that when I run the program, I get this:
Person 1:
Jordan
Person 2:
Jordan
Person 3:
Jordan
Person 4:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
at RGG.main(RGG.java:20)
I am not quite sure what is wrong, but I have tried removing the = in the for loop declaration, then I get this output:
Person 1:
Jordan
Person 2:
Jordan
Person 3:
After the third prompt, the code moves on and I cant type in anything there.
Does anyone know what might be happening? Thanks in advance!
Remove the = in this expression i <= listOfPeople.length;. Its causing you to access an element of the array that does not exist.
for (int i = 0; i < listOfPeople.length; i++){
String name = scnr.nextLine();
System.out.println("Person " + (i) + ": ");
listOfPeople[i] = name;
}
Full Example:
public class PersonArrayTest {
public static void main(String[] args) {
String[] listOfPeople = new String[5];
assign(listOfPeople);
System.out.println(Arrays.toString(listOfPeople));
}
public static void assign(String[] listOfPeople) {
Scanner scnr = new Scanner(System.in);
for (int i = 0; i < listOfPeople.length; i++) {
String name = scnr.nextLine();
System.out.println("Person " + (i) + ": ");
listOfPeople[i] = name;
}
}
}
With this line
for (int i = 0; i <= listOfPeople.length; i++){
You are advancing one beyond the end of the array, length 3, which has valid indices 0-2. 3 is an invalid index.
When you remove the =, you get the corrected version:
for (int i = 0; i < listOfPeople.length; i++){
which stops after the 2 iteration, which is the end of the array, before you run off the end of the array.
change this the <= sign in forloop
for (int i = 0; i < listOfPeople.length; i++)
I am make an educated guess that you are using Scanner#nextInt to get the input for the length of the array. Something along the lines of this:
String[] listOfPeople = new String[scnr.nextInt()];
I've garnered this because your loop code looks like this:
take input for i == 0
print prompt #1
take input for i == 1
print prompt #2
take input for i == 2
print prompt #3
But your output shows this:
print prompt #1
take input for i == 1
print prompt #2
take input for i == 2
print prompt #3
So what actually must be happening is this:
silently advance past whatever scnr is still retaining for i == 0
print prompt #1
take input for i == 1
print prompt #2
take input for i == 2
print prompt #3
nextInt orphans a new line character. (So will any calls to next_ besides nextLine.) That's why your first input is skipped. Calling scnr.nextLine in the first iteration of the loop just advances the Scanner past the last line.
Change the loop to this:
// skip the last new line
scnr.nextLine();
// < not <=
for (int i = 0; i < listOfPeople.length; i++) {
// prompt before input
System.out.println("Person " + (i + 1) + ": ");
// you don't need that extra String
listOfPeople[i] = scnr.nextLine();
}