Java - Cannot get loop to recognize newly generated array values - java

I am creating a program for class where I can bet on a horse race. The winners are determined by a method given to us by our professor. here is the method:
void readySetGo() {
System.out.println(array.length);
int length = array.length;
Random rgen = new Random();
for (int i = 0; i < array.length; i++) {
int randomValue = i + rgen.nextInt(length - i);
int randomElement = array[randomValue];
array[randomValue] = array[i];
array[i] = randomElement;
}
}
I created a string-based menu using a while loop. In order to make things easier on myself, I created a cheat box that displays the winners before you place your bet.
System.out.print("Cheat: ");
System.out.println(Arrays.toString(racer.getArray()));
Here is the main method:
public static void main(String[] args) {
race racer = new race();
wallet balance = new wallet();
Scanner input = new Scanner(System.in);
double pick1;
double pick2;
String response;
balance.setUSDbalance(200);
racer.readySetGo();
System.out.print("Cheat: ");
System.out.println(Arrays.toString(racer.getArray()));
System.out.println("Welcome to Charlie's Horse Racing Bets!");
System.out.println("\nType one of the strings below and add your horse numbers after:");
System.out.println("Example: 'Exacta Box 2 3'");
System.out.println("\n=> Exacta");
System.out.print("\nEnter your choice: ");
response = input.nextLine();
String words[] = response.split(" ");
while (true) {
if (words[0].equalsIgnoreCase("Exit")) {
System.out.println("Thanks for playing! \nSee you soon!");
} else if (words[0].equalsIgnoreCase("Exacta")) {
pick1 = Double.parseDouble(words[1]);
pick2 = Double.parseDouble(words[2]);
boolean way1 = (pick1 == racer.first()) && (pick2 == racer.second());
boolean way2 = (pick1 == racer.second()) && (pick2 == racer.first());
if (way1 || way2) {
System.out.println("You won the exact box");
System.out.print("The winning order was: ");
System.out.println(Arrays.toString(racer.getArray()));
System.out.print("\nCheat for next round: ");
racer.readySetGo();
System.out.println(Arrays.toString(racer.getArray()));
System.out.print("\nEnter your new choice: ");
response = input.nextLine();
} else {
System.out.println("You chose the wrong order. Play again?");
System.out.print("\nEnter your new choice: ");
response = input.nextLine();
}
}
}
}
The problem is that the system recognizes the correct user input the first time, but doesn't work at all the second time. Example:
Cheat: [4, 1, 3, 2]
Welcome to Charlie's Horse Racing Bets!
Type one of the strings below and add your horse numbers after:
Example: 'Exacta Box 2 3'
=> Exacta
Enter your choice: exacta 4 1
You won the exact box
The winning order was: [4, 1, 3, 2]
Cheat for next round: [3, 1, 4, 2]
Enter your new choice: exacta 3 1
You chose the wrong order. Play again?

As your code currently stands, you're only parsing the user's input the first time. Inside the loop you're reading the user's input again, but you're not updating the words variable based on the new input.
You should move this line inside your loop:
String words[] = response.split(" ");

Related

Adding all inputs into an array

Intended Function: User should ender 1,2 or 3. 1 should allow the user to add a number to the array, 2 should allow the user to access the number at that point in the array, 3 should exit the program.
Problem: When the user is asked for a number and chooses 'yes' to add another, only the last number entered is added to the array. All numbers inputed should be added. Why is only the last one added?
import java.util.Scanner;
public class PhoneBookV2 {
public static void main(String[] args){
String[] numbers = {};
String[] moreNumbers = new String[numbers.length + 1];
numbers = moreNumbers;
print(numbers);
task(numbers, moreNumbers);
}
public static void task(String[] numbers, String[] moreNumbers){
Scanner scan = new Scanner(System.in);
System.out.println("Please Pick A Task: \n 1:Add A Number to Speed Dial \n 2:Speed Dial A Number \n 3:Exit");
String choice = scan.nextLine();
switch(choice){
case "1":
AddNumber(numbers , moreNumbers);
break;
case "2":
CallNumber(numbers);
break;
case "3":
System.out.println("Goodbye!");
System.exit(0);
break;
}
}
private static String[] AddNumber(String[] numbers,String[] moreNumbers) {
Scanner scanner = new Scanner(System.in);
boolean cont = false;
do{
System.out.print("Please Enter The Number You Wish To Save Under Speed Dial: ");
moreNumbers[moreNumbers.length - 1] = scanner.nextLine();
System.out.print("Would you like to add another? Yes or No: ");
String answer = scanner.nextLine().toLowerCase();
if(answer.equals("yes")) continue;
else if(answer.equals("no")) {
print(numbers);
cont = true;
}
}while(!cont);
System.arraycopy(numbers, 0, moreNumbers, 0, numbers.length);
return moreNumbers;
}
public static void printPhoneBook(String[][] keys){
for(String[] row : keys){
for(String s : row){
System.out.print(s);
}
System.out.println();
}
}
public static void print(String[] numbers){
for(int i = 0; i< numbers.length; i++){
System.out.println((i+1) + ") " + numbers[i]);
}
}
}
That's because an array in Java is fixed size. Let's look at your code:
String[] numbers = {};
String[] moreNumbers = new String[numbers.length + 1];
You are creating a String array numbers of length 0 and another String array moreNumbers with the length of numbers added to 1 (e.g, length 1).
Then, you pass these arrays to the task method, where you add a number to the moreNumbers array.
moreNumbers[moreNumbers.length - 1] = scanner.nextLine();
Here, you're setting a value (scanner.nextLine()) to the index 0 of moreNumbers (since moreNumbers has length 1). When you fetch another value, it's set to the same index 0 since moreNumbers did not change its size.
You can use the add method of ArrayList, which can resize:
import java.util.ArrayList;
// ...
private static ArrayList<String> AddNumber() {
// Create a new ArrayList to store the numbers
final ArrayList<String> numbers = new ArrayList<>();
Scanner scanner = new Scanner(System.in);
boolean cont = false;
do {
System.out.print("Please Enter The Number You Wish To Save Under Speed Dial: ");
// Add the next number to the ArrayList
numbers.add(scanner.nextLine());
System.out.print("Would you like to add another? Yes or No: ");
String answer = scanner.nextLine().toLowerCase();
if (answer.equals("yes")) continue;
if (answer.equals("no")) {
print(numbers);
cont = true;
}
} while (!cont);
return numbers;
}

Java lottery Machine Task

My task is to allow a user to input their lottery numbers and check if
they have won the jackpot.
The user should be given the chance to enter 4 numbers. Each number should be in the range 1-99. If
the user enters a number that is less than 1, or greater than 99, then the programme should prompt
them to enter a number in the correct range. You should use a while loop to ensure that the user inputs
the correct number. What should the exit condition of the while loop be?
I have tried making a while loop as the task asks me to do. this did not work. I am completely and utterly stuck.
String password = "MyNameJeff";
Scanner dave = new Scanner(System.in);
System.out.println("lottery numbers");
int UserInput = dave.nextLine();
while (!password.equals(UserInput)) {
System.out.println random math command <----
UserInput = dave.nextLine();
}
System.out.println("Lottery numbers here?");
This while loop will take the first userInput and check its range between 1 and 99 inclusive.
while(userInput < 1 || userInput > 99){
System.out.println("Please re-enter another lottery number: ");
userInput=dave.nextInt();
}
If it is not in the range 1 to 99, it will request the user to re-enter another lottery number.
the condition is when you want to stop the while loop. for example
you may want to stop when you have 4 numbers
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
class Scratch {
public static void main(String[] args) {
List<Integer> choices = new ArrayList<>();
Scanner scanner = new Scanner(System.in);
boolean done = false;
//we set done to false, and the condition is "while !(not) done"
while (!done) {
try {
System.out.println("write lottery numbers:");
String userInput = scanner.nextLine();
Integer result = Integer.parseInt(userInput);
// compareTo is a bit tricky, read the javadoc for information
if (result.compareTo(0) < 0) {
System.out.println("dont add number less then 0");
continue;
}
if (result.compareTo(99) > 0) {
System.out.println("dont add number more then 99");
continue;
}
//adding more result is the only way done will be eventually true
choices.add(result);
//set to done when the size of the list is 4
done = choices.size() == 4;
} catch (NumberFormatException e) {
System.out.println("Only add number");
}
}
System.out.println("Lottery numbers here?");
choices.forEach(System.out::println);
}
}
Check this code
public static void main (String[]args) throws IOException, ParseException {
int [] winNumbers = new int[4];
int [] numbers = new int[4];
int indx=0;
System.out.println("Enter Lottery Numbers");
while (indx<4) {
System.out.println("Enter number: ");
Scanner dave = new Scanner(System.in);
try {
String in = dave.nextLine().trim();
int inNum = Integer.parseInt(in);
if (inNum>0 && inNum<100) {
numbers[indx] = inNum;
indx++;
continue;
}
}
catch (NumberFormatException | NullPointerException nfe) {
}
System.out.println("Please enter a number in the range 1-99");
}
Random rand = new Random();
for (int i=0; i<winNumbers.length; i++){
int r = rand.nextInt(98);//will get a random number between 0-98
r +=1; // for the number to be on the space 1-99
winNumbers[i]=r;
}
System.out.println("User entered: " + Arrays.toString(numbers));
System.out.println("Lottery numbers here: " + Arrays.toString(winNumbers));
}
Two int arrays are used with size 4.
One is filled using Scanner. There are some checks:
trim(): will remove any whitespace that the user might enter
catch: will catch a numberFormatException or null. It will print nothing.
If the code does not enter the if(inNum>0 && inNum<100) then the indx counter will not increment and the code will print the error message: Please enter a number...
The second part of the code generates 4 random numbers and stores them in the second array.
Finally, it prints the two arrays.

How can i input several integer or another types?

I want to enter several numbers for some operations. But i need to add this numbers without stopping. I mean, for example i wanna that program asks me how many integer i want to enter, after for example i yped 5 and click enter, it should give me opportunity to enter my 5 numbers (For example, 12, 34, 54, 23, 9) in the lines. Then i will use this numbers for something in my program.
i am using Scanner class for entering the number. But i wanna to enter several numbers in once input.
package frlr;
import java.util.Scanner;
public class Frlr {
public static void main(String[] args) {
System.out.println("Please enter your numbers: ");
Scanner in = new Scanner(System.in);
int myNumbers = in.nextInt();
System.out.println(myNumbers);
}
}
I need, when program asks me "Please enter your numbers:" if i enter 5 , it should be the count of the numbers which i will enter in the next steps.
You can use for loop, for loop allows you enter the amount of numbers you entered in your first scanner.
For example:
1) you scan the amount of number you want to enter
2) in for loop you use that number as an endpoint
so your for loop is gonna look like this:
for(initialization; condition(your condition is your scan) ; increment/decrement)
{
statement(s);
}
3) you statement is going to be another scan, or as you refer to it as entering several numbers
If you want to use the numbers later you can save them in an Array. First you ask the user how big the array has to be (quantity). Then you initialize an Array with the user input size. You need to watch out that the number is positive. After that you make a for loop, that has the input quantity times of iterations. After each step you save the number in the proper spot. In the end you can output the numbers.
Validation of user inputs can be done with Regular Expressions. Here is a good tutorial on RegEx: http://www.vogella.com/tutorials/JavaRegularExpressions/article.html
import java.util.Arrays;
import java.util.Scanner;
public class VariableInputs
{
private Scanner scanner;
private String input;
private boolean isInputBad;
public VariableInputs()
{
this.scanner = new Scanner(System.in);
this.isInputBad = false;
}
public void startInteraction()
{
System.out.println(
"How many Integers would you like to enter? Enter a positive number that is smaller than 100.");
int quantity;
do
{
if (isInputBad) System.out.println("Enter a valid number."); // this gets printed if the user entered a wrong input (f.e. "abc").
input = scanner.next();
isInputBad = true;
}
while (!input.matches("\\d{1,2}")); // this checks if the input contains only number 0-9. The input has to have atleast 1 and max 2 numbers.
isInputBad = false;
quantity = Integer.parseInt(input); // because of the regular expression we know for sure that the input string is a number. So we can parse it.
int[] numbers = new int[quantity]; // init array with input quantity.
System.out.println("Good job my friend. You have entered " + quantity
+ ". Go ahead and enter those numbers.");
for (int i = 0; i < quantity; i++)
{
do
{
if (isInputBad) System.out.println("Enter a valid number.");
input = scanner.next();
isInputBad = true;
}
while (!input.matches("\\d"));
numbers[i] = Integer.parseInt(input);
isInputBad = false;
}
System.out.println("Good job my friend. You have entered " + quantity
+ " numbers.");
System.out.println("The numbers are: " + Arrays.toString(numbers));
scanner.close();
}
public static void main(String[] args)
{
VariableInputs vi = new VariableInputs();
vi.startInteraction();
}
}
You can try this code and see if its useful:
import java.util.Scanner;
import java.util.Arrays;
public class ScannerIn {
public static void main(String[] args) {
System.out.print("Please enter how many numbers (between 1 and 10)? ");
Scanner in = new Scanner(System.in);
int numbersCount = in.nextInt();
System.out.println(numbersCount);
if (numbersCount <= 0 || numbersCount > 10) {
System.out.println("Numbers count must be between 1 and 10. Exit program!");
System.exit(0);
}
int [] myNumbers = new int [numbersCount];
for (int i = 0; i < numbersCount; i++) {
System.out.print("Please enter your number: ");
in = new Scanner(System.in);
myNumbers[i] = in.nextInt();
}
System.out.println("Numbers input: " + Arrays.toString(myNumbers));
}
}

How can I verify the int length of scanner input?

I was able to get the program to run and work with error checking to make sure that the user input is in fact an int. The issue I ran into is that I only want it to be a 3-digit int. I'm having trouble getting that into the right place:
import java.util.*;
public class listMnemonics
{
public static void main(String[] args)
{
//Defines the "keypad" similar to that of a phone
char[][] letters =
{{'0'},{'1'},{'A','B','C'},{'D','E','F'},{'G','H','I'},{'J','K','L'},
{'M','N','O'},{'P','Q','R','S'},{'T','U','V'},{'W','X','Y','Z'}};
//Creates the Scanner
Scanner scan = new Scanner(System.in);
Right here is where I need to implement that and I am running into the issue. I'm sure it's maybe only a line out of place or missing that I need, I just don't know what or where. As it sits, it will constantly ask me to enter a 3-digit number, no matter the length. Error checking for a string entered does currently work:
//Gives instructions to the user to enter 3-digit number
//Any amount of numbers will work, but instructions help
//System.out.println("Please enter a 3-digit number: ");
int j;
do
{
System.out.println("Please enter a 3-digit number: ");
while (!scan.hasNextInt()) {
System.out.println("That's not a 3-digit number! Try again!");
scan.next(); // this is important!
}
j = scan.nextInt();
}
//while (j <= 0); This works while not checking digit length
while (j != 3);
int w = (int) Math.log10(j) +1; //Found this, but not sure if it helps or not
String n = Integer.toString(w);
And here is the rest that get's it to do what I need it to:
//Determines char length based on user input
char[][] sel = new char[n.length()][];
for (int i = 0; i < n.length(); i++)
{
//Grabs the characters at their given position
int digit = Integer.parseInt("" +n.charAt(i));
sel[i] = letters[digit];
}
mnemonics(sel, 0, "");
}
public static void mnemonics(char[][] symbols, int n, String s)
{
if (n == symbols.length)
{
System.out.println(s);
return;
}
for (int i = 0; i < symbols[n].length; i ++)
{
mnemonics(symbols, n+1, s + symbols[n][i]);
}
}
}
Here's the output:
----jGRASP exec: java listMnemonics
Please enter a 3-digit number:
2345
Please enter a 3-digit number:
12
Please enter a 3-digit number:
123
Please enter a 3-digit number:
motu
That's not a 3-digit number! Try again!
With the help of MvG and pingul, this is what is currently working the way I was hoping:
import java.util.*;
import java.util.regex.Pattern;
public class listMnemonics
{
public static void main(String[] args)
{
// Defines the "keypad" similar to that of a phone
char[][] letters =
{{'0'},{'1'},{'A','B','C'},{'D','E','F'},{'G','H','I'},{'J','K','L'},
{'M','N','O'},{'P','Q','R','S'},{'T','U','V'},{'W','X','Y','Z'}};
// Creates the Scanner
Scanner scan = new Scanner(System.in);
// Gives instructions to the user to enter 3-digit number
// This 'Pattern' also guarantees that only 3 digits works.
Pattern threeDigitNumber = Pattern.compile("[0-9]{3}");
int j;
do
{
System.out.println("Please enter a 3-digit phone number: ");
// If it's not a 3-digit int, try again
while (!scan.hasNext(threeDigitNumber))
{
System.out.println("That's not a 3-digit number! Try again!");
// This is important!
scan.next();
}
j = scan.nextInt();
}
while (j <= 0);
String n = Integer.toString(j);
// Determines char length based on user input
char[][] sel = new char[n.length()][];
for (int i = 0; i < n.length(); i++)
{
// Grabs the characters at their given position
int digit = Integer.parseInt("" +n.charAt(i));
sel[i] = letters[digit];
}
mnemonics(sel, 0, "");
}
// Here is where the magic happens and creates the possible
// letter combinations based on the user input and characters
// selected in previous steps.
public static void mnemonics(char[][] symbols, int n, String s)
{
if (n == symbols.length)
{
System.out.println(s);
return;
}
for (int i = 0; i < symbols[n].length; i ++)
{
mnemonics(symbols, n+1, s + symbols[n][i]);
}
}
}
Condensed and reformatted your code reads
Scanner scan = new Scanner(System.in);
int j;
do {
System.out.println("Please enter a 3-digit number: ");
while (!scan.hasNextInt()) {
System.out.println("That's not a 3-digit number! Try again!");
scan.next(); // this is important!
}
j = scan.nextInt();
} while (j != 3);
Comparing that to the Scanner documentation we can see that the scan.next() call will read (and discard) the non-int token. Otherwise j will be the integer you read. And you continue doing so while the number you read is different from 3. Not the length of the number, but the number itself. So if you want to end the loop, enter 3. If you want to do so while following the prompt, enter 003.
If that's not what you want to check, then change the end of loop condition. Or perhaps change the way you test for three-digit numbers, by using regular expressions to match these.
Scanner scan = new Scanner(System.in);
Pattern threeDigitNumber = Pattern.compile("\\d\\d\\d");
int j;
System.out.println("Please enter a 3-digit number: ");
while (!scan.hasNext(threeDigitNumber)) {
if (scan.hasNext()) {
System.out.println(scan.next() + " is not a 3-digit number! Try again!");
} else {
System.out.println("Input terminated unepxectedly");
System.exit(1);
}
}
j = scan.nextInt();
As comments correctly indicate, the pattern "\\d\\d\\d" could just as well be written as "[0-9]{3}", or as "\\d{3}" or "[0-9][0-9][0-9]". Using {…} might be useful in situations where the number of digits is a variable.
The documentation for Scanner.hasNext(Pattern) requires the pattern to match the input. This apparently follows the Matcher.matches() semantics of matching the whole string against the pattern, as opposed to Matcher.find() which checks whether the string contains any part matching the pattern. So the input does not have to be enclosed in ^ and $, as I assumed at first, and in fact should not be using these unless the pattern is compiled with the Pattern.MULTILINE flag.
You may want to call Scanner.useDelimiter to delimit using line breaks only.
Scanner.useDelimiter("[\\r\\n]+")

Trouble splitting data in Java program

I'm trying to split my variables and enter my student data in so I can move on with my grade calculation program, but my second time splitting the entered string, there is a problem and I cannot figure out what is the cause of it.
Users will enter information in that looks like this
John Denver: e100 q70 q50 h100 e100 e90 h80 q60 h100
The program needs to split apart all of this data and get the name entered into an array, and then the exam scores, quiz scores and homework scores represented by the "e", "q" or "h" in the entered data.
import java.util.Scanner;
public class GradeCalcWithArrays { /*
* Daniel The purpose is to calculate
* entered grades
*/
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
boolean done = false;
boolean quit = false;
int choice = 0;
int maxstudents = 200;
int[] examstats = new int[3]; /*
* Array created to store the information
* entered for exams
*/
int[] quizstats = new int[3]; /*
* Array created to store the information
* entered for quizzes
*/
int[] homeworkstats = new int[3]; /*
* Array created to store the
* information entered for homework
*/
String[] studentnames = new String[maxstudents]; /*
* Array created to
* store the student
* name information
* entered
*/
System.out.println("Welcome to GradeBook!");
System.out.println("Please provide grade item details");
System.out.print("Exams (number, points, weight):");
examstats[0] = s.nextInt(); // inputs exam number
examstats[1] = s.nextInt(); // inputs exam points
examstats[2] = s.nextInt(); // inputs exam weight
System.out.print("Quizzes (number, points, weight):");
quizstats[0] = s.nextInt(); // inputs quiz number
quizstats[1] = s.nextInt(); // inputs quiz points
quizstats[2] = s.nextInt(); // inputs quiz weight
System.out.print("Homework (number, points, weight):");
homeworkstats[0] = s.nextInt(); // inputs homework number
homeworkstats[1] = s.nextInt(); // inputs homework points
homeworkstats[2] = s.nextInt(); // inputs homework weight
double[] examscores = new double[examstats[0]];
double[] quizscores = new double[quizstats[0]];
double[] hwscores = new double[homeworkstats[0]];
System.out.println("--------------------");
do {
System.out.println("What would you like to do?");
System.out.println(" 1 Add student data");
System.out.println(" 2 Display student grades & statistics");
System.out.println(" 3 Plot grade distribution");
System.out.println(" 4 Quit");
System.out.print("Your choice:");
choice = s.nextInt(); /*
* Choice will determine what the next course of
* action will be with the program
*/
if (choice == 1) {
System.out.println("Enter student data:");
for (int i = 0; i <= maxstudents; i++) {
System.out.print("Data>");
String dataentry = s.nextLine();
String[] firstsplit = dataentry.split(":");
studentnames[i] = firstsplit[0];
String[] secondsplit = firstsplit[1].split(" ");
for (int j = 0; j <= maxstudents; j++) {
String c;
c = secondsplit[j].substring(0, 1);
if (c == "e") {
secondsplit = secondsplit[j].split("e");
examscores[i] = Double.parseDouble(secondsplit[j]);
}
if (c == "q") {
secondsplit = secondsplit[j].split("q");
quizscores[i] = Double.parseDouble(secondsplit[j]);
}
if (c == "h") {
secondsplit = secondsplit[j].split("h");
hwscores[i] = Double.parseDouble(secondsplit[j]);
}
if (dataentry.equals("done")) {
break;
}
}
}
}
if (choice == 2) {
}
if (choice == 3) {
}
if (choice == 4) {
quit = true;
System.out.println("Good bye!");
}
} while (quit == false);
}
}
I get an error that says: Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
at GradeCalcWithArrays.main(GradeCalcWithArrays.java:83)
Can someone help me fix this and tell me if my program is going to work?
One thing that is wrong is that you have maxstudents set to 200, you allocate the studentnames array with size 200, but that means that the valid subscripts are 0 through 199, but your for loop uses a less than or equal test against 200:
`for (int i = 0; i <= maxstudents; i++)`
That means that i is 200 on the last iteration, so in that iteration your code will effectively execute studentnames[200] = firstsplit[0]; and that will cause an ArrayIndexOutOfBoundsException.
The above, however, will be a problem if you reach the 200th iteration without breaking out of the for loop. Looking at the code, I do see that you are attempting to break if the input is "done", however that break statement is actually inside the nested for loop, so it does not break out of the outer loop. That test really should happen before you do the first split. There's no reason to even try to split if the input was "done", so also no reason to go into the nested for loop.
There are additional problems as well: The nested for loop should not be testing against maxstudents because it's the number of grades that you care about. I'll leave the rest of them for you to figure out - with a hint about one of them: you should be checking your input for errors.

Categories

Resources