my program is a recreation of the game mastermind. I am trying to protect against an error when you enter three or less characters instead of the required four, but my try/catch just... isn't doing anything. Please help
/*
* AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
* AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
*/
package nowornever;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import javax.swing.JOptionPane;
import java.util.Scanner;
/**
*
* #author KK
*/
public class NowOrNever {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String code[] = new String[4];
String guessNum[] = new String[4];
String hint[] = new String[4];
String line;
String guess = null;
try {//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------PREVIOUS MATCH CLEAR
PrintWriter pw = new PrintWriter(new FileWriter("LastMatch.txt"));
pw.print("");
pw.close();
} catch (IOException ioe) {
System.err.println("Problem opening / writing to file");
}
int menu = Integer.parseInt(JOptionPane.showInputDialog("Would you like to read the rules? \n Enter 1 for yes or 2 for No."));
if (menu == 1) { //--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------RULES
JOptionPane.showMessageDialog(null, "The object of this game is to break a number code in six turns or less.\nHow to play:\n\n1. Enter four numbers you think could be the code, from 1 to 9.\n\n2. The machine will respond by indicating whether any of your numbers are a correct guess.\n- Correct number wrong location will be indicated with a dot '•'.\n- Correct number and correct location will be indicated with a reverse dot '◘'.\n- if both number and location are wrong, there will be a blank space' '.\n\n3. Use your logic and luck to crach the code and win the game within six tries or less!\n\nIf you play again, you can find a record of your most recent match saved in 'LastMatch.txt' in the root folder of this project.");
JOptionPane.showMessageDialog(null, " The game is starting in the output section");
} else {
JOptionPane.showMessageDialog(null, " The game is starting in the output section");
}
try { //--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------MENU PREPPER
PrintWriter pw = new PrintWriter(new FileWriter("LastMatch.txt", true));
pw.println("┌─────┬─────┐");
pw.close();
} catch (IOException ioe) {
System.err.println("Problem opening / writing to file");
}
for (int count = 0; count < 4; count++) { //-----------------------------------------------------------------------------------------------------------------------------------------------------AI LOOP
double randomValue = (double) (Math.random());
if (randomValue >= 0.0 && randomValue <= 0.1111111) {
code[count] = 1 + "";
} else if (randomValue >= 0.1111111 && randomValue <= 0.2222222222) {
code[count] = 2 + "";
} else if (randomValue >= 0.2222222 && randomValue <= 0.3333333) {
code[count] = 3 + "";
} else if (randomValue >= 0.33333333 && randomValue <= 0.44444444) {
code[count] = 4 + "";
} else if (randomValue >= 0.44444444 && randomValue <= 0.555555555) {
code[count] = 5 + "";
} else if (randomValue >= 0.55555 && randomValue <= 0.66666666) {
code[count] = 6 + "";
} else if (randomValue >= 0.6666666666 && randomValue <= 0.777777777) {
code[count] = 7 + "";
} else if (randomValue >= 0.777777777 && randomValue <= 0.88888888) {
code[count] = 8 + "";
} else if (randomValue >= 0.88888888 && randomValue <= 1) {
code[count] = 9 + "";
} else {
System.out.println("Issue with generating code; please try again.");
//System.exit(0);
}
}
for (int count = 0; count < 6; count++) { //-------------------------------------------------------------------------------------------------------------------------------------------BEGINNING OF PROCESSING LOOP
try {//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------INPUT TRY/CATCH
System.out.println("Please enter your guess of four numbers from 1-9. Please do not include spaces in your submission.");
guess = input.nextLine();
} catch(StringIndexOutOfBoundsException siobe){
System.out.println("Please enter four numbers");
}
if (guess.contains(" ")) { //-----------------------------------------------------------------------------------------------------------------------------------------------------------SPACE CHECKER
JOptionPane.showMessageDialog(null, "Try again, and Please do not enter spaces in between the characters.");
System.exit(0);
}
for (int countInternal = 0; countInternal < 4; countInternal++) { //-----------------------------------------------------------------------------------------------------------------TAKING GUESS APART
guessNum[countInternal] = guess.substring(countInternal, countInternal + 1);
}
if (guessNum[0].equals(code[0])) {//--------------------------------------------------------------------------------------------------------------------------------------------------CORRECT CHECKER 1
hint[0] = "◘";
} else if (guessNum[0].equals(code[1])) {
hint[0] = "•";
} else if (guessNum[0].equals(code[2])) {
hint[0] = "•";
} else if (guessNum[0].equals(code[3])) {
hint[0] = "•";
} else {
hint[0] = " ";
}
if (guessNum[1].equals(code[1])) {//--------------------------------------------------------------------------------------------------------------------------------------------------CORRECT CHECKER 2
hint[1] = "◘";
} else if (guessNum[1].equals(code[2])) {
hint[1] = "•";
} else if (guessNum[1].equals(code[3])) {
hint[1] = "•";
} else if (guessNum[1].equals(code[0])) {
hint[1] = "•";
} else {
hint[1] = " ";
}
if (guessNum[2].equals(code[2])) {//--------------------------------------------------------------------------------------------------------------------------------------------------CORRECT CHECKER 3
hint[2] = "◘";
} else if (guessNum[2].equals(code[3])) {
hint[2] = "•";
} else if (guessNum[2].equals(code[0])) {
hint[2] = "•";
} else if (guessNum[2].equals(code[1])) {
hint[2] = "•";
} else {
hint[2] = " ";
}
if (guessNum[3].equals(code[3])) {//--------------------------------------------------------------------------------------------------------------------------------------------------CORRECT CHECKER 4
hint[3] = "◘";
} else if (guessNum[3].equals(code[0])) {
hint[3] = "•";
} else if (guessNum[3].equals(code[1])) {
hint[3] = "•";
} else if (guessNum[3].equals(code[2])) {
hint[3] = "•";
} else {
hint[3] = " ";
}
try {//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------PLAYER INPUT LINE PRINT
PrintWriter pw = new PrintWriter(new FileWriter("LastMatch.txt", true));
pw.println("│" + guessNum[0] + guessNum[1] + guessNum[2] + guessNum[3] + "│" + hint[0] + hint[1] + hint[2] + hint[3] + "│");
pw.close();
} catch (IOException ioe) {
System.err.println("Problem opening / writing to file");
}
try {//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------PLAYER INPUT LINE READ
BufferedReader br = new BufferedReader(new FileReader("LastMatch.txt"));
while ((line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
} catch (IOException ioe) {
System.err.println("Error reading from file");
}
if (guessNum[0].equals(code[0]) && guessNum[1].equals(code[1]) && guessNum[2].equals(code[2]) && guessNum[3].equals(code[3])) {//------------------------------------------------------WIN CONDITION
count = 6;
System.out.println("You Win!");
}
} //-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------END OF ENTERING AND PRCESSING LOOP
System.out.println("Game Over!");
try {
PrintWriter pw = new PrintWriter(new FileWriter("LastMatch.txt", true));
pw.println("└─────┴─────┘");
pw.close();
} catch (IOException ioe) {
System.err.println("Problem opening / writing to file");
}
System.out.println("Final Game Board:");
try {
BufferedReader br = new BufferedReader(new FileReader("LastMatch.txt"));
while ((line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
} catch (IOException ioe) {
System.err.println("Error reading from file");
}
try {//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------PLAYER INPUT LINE PRINT
PrintWriter pw = new PrintWriter(new FileWriter("LastMatch.txt", true));
pw.println("The code was:" + code[0] + code[1] + code[2] + code[3]);
pw.close();
} catch (IOException ioe) {
System.err.println("Problem opening / writing to file");
}
}
}
StringIndexOutOfBoundsException occurs when you try to access the character index which doesn't exists. e.g. String length is 3 and you are trying to access str.charAt(4) etc.
In your program, (which I believe isn't having the most optimum solution but respecting your logic), should handle it at below lines and not while taking input from user.
try {
guessNum[countInternal] = guess.substring(countInternal, countInternal + 1);
} catch(StringIndexOutOfBoundsException siobe){
System.out.println("Error");
}
Better solution would be, while taking the input, check length of a string
while(true) {
System.out.println("Please enter your guess of four numbers from 1-9. Please do not include spaces in your submission.");
guess = input.nextLine();
if(guess.length()==4) {
break;
}else{
System.out.println("Please enter four numbers");
}
}
The line that is currently wrapped inside your try block is guess = input.nextLine(); which will never throw a StringIndexOutOfBoundsException, rather the error is caused by using substring with an out of bounds index here guess.substring(countInternal, countInternal + 1);.
To make the exception work correctly you need to wrap the entire code block including the substring code inside the try bracers like the following, however, we also need to use a while loop to get the inputs if the exception is caught:
//We need to wrap any code that can have multiple attempts inside a while loop
//Variable to control the while loop
boolean waiting = true;
//Loop to get 4 inputs
while (waiting)
{
System.out.println("Please enter your guess of four numbers from 1-9. Please do not include spaces in your submission.");
guess = input.nextLine();
//Remove any spaces in the guess
guess = guess.replaceAll(" ", "");
try {
//Process the input INSIDE the try block
for (int countInternal = 0; countInternal < 4; countInternal++) {
guessNum[countInternal] = guess.substring(countInternal, countInternal + 1);
}
//Success, if the code reached here then no errors were thrown, and we can change the flag so that the loop stops after this cycle
waiting = false;
}
catch(StringIndexOutOfBoundsException siobe){
System.out.println("Please enter four numbers");
//Move to the next loop cycle and skip all code below
continue;
}
}
//Put code here to be done after storing the 4 inputs in guessNum
//...
However, the above is not a good solution, we should never rely on a try/catch block to run our code, rather we should work with absolute values. For example, we can use an if statement inside a while loop to check the length of the input. As before we need to wrap any code that can have multiple attempts inside a while loop:
//Variable to control the while loop
boolean waiting = true;
//Loop to get 4 inputs
while (waiting)
{
System.out.println("Please enter your guess of four numbers from 1-9. Please do not include spaces in your submission.");
guess = input.nextLine();
//Remove any spaces in the guess
guess = guess.replaceAll(" ", "");
if(guess.length() < 4)
{
System.out.println("Please enter four numbers");
//Do this: Move to the next loop cycle and skip all code below
continue;
}
//Or do this: Put any following code in an else block so that it is not exected unless the length is over 4
else {
//Success, change the flag so that the loop stops after this cycle
waiting = false;
//Process the input
for (int countInternal = 0; countInternal < 4; countInternal++) {
guessNum[countInternal] = guess.substring(countInternal, countInternal + 1);
}
}
}
//Put code here to be done after storing the 4 inputs in guessNum
//...
Related
I am banging my head to the wall but just can't figure out what is going wrong. Simple program but not working. I need to get 3 inputs(integers) from user. End the program on either array full or when user presses enter. Here is what i am trying without any luck. It works fine all the situtations EXCEPT it cant detect nextline.
Scanner sc = new Scanner(System.in);
int[] intArray = new int[3];
int counter = 0;
System.out.println("Start!!");
while (true) {
System.out.println("Enter int");
if (sc.hasNextInt() && counter <= 2) {
intArray[counter] = sc.nextInt();
counter++;
} else {
if (counter >= 3) {
System.out.println("Array is full");
System.out.println("Array ELemnets : " + Arrays.toString(intArray));
break;
}
if (sc.next().isEmpty() || sc.next().equals("\n")){
System.out.println("Its empty");
break;
} else {
System.out.println("wrong input.");
}
}
}
sc.close();
Please help me . Why is it not detecting next line. I have googled already and tried lot of solutions provided but none worked for me. Any HELP!!!
Thanks
Edited code :
Scanner sc = new Scanner(System.in);
int[] intArray = new int[3];
int counter = 0;
System.out.println("Start!!");
while (true) {
System.out.println("Enter int");
if (sc.hasNextInt() && counter <= 2) {
intArray[counter] = sc.nextInt();
counter++;
} else {
if (counter >= 3) {
System.out.println("Array is full");
System.out.println("Array ELemnets : " + Arrays.toString(intArray));
break;
}
String next = sc.next();
if (next.isEmpty() || next.equals("\n"))
{
System.out.println("Its empty");
break;
} else {
System.out.println("wrong input.");
}
}
}
sc.close();
}
int[] intArray = new int[3];
int counter = 0;
boolean enterPressed = false; // added boolean to test if they entered a blank line
try (
Scanner sc = new Scanner(System.in); // declaring in a try-with-resources, so it automatically closes.
) {
System.out.println("Start!!");
System.out.println("Enter int"); // Have to print this the first time
while (counter < 3 && !enterPressed) {
if (counter > 0) { System.out.println("Enter int"); }
String next = sc.nextLine(); // just grab a line (the user pressed enter)
if (next.isEmpty()) {
enterPressed = true;
} else {
try {
intArray[counter] = Integer.parseInt(next);
counter++;
} catch (NumberFormatException ex) {
System.out.println("wrong input.");
}
}
}
}
Your code is sticking because it's waiting on the conditional check for sc.hasNextInt(). The solution I propose below, manually parses the user-input string to see if it's an int, rather than using the Scanner's functionality to check if it's an int or not.
I left some comments in the code to hopefully add clarity. Let me know if anything doesn't make sense, and I'm happy to elaborate!
import java.util.Arrays;
import java.util.Scanner;
public class ScannerTestNew {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int[] intArray = new int[3];
int counter = 0;
System.out.println("Start!!");
// Variable used to hold the user's input via the Scanner.
String userInput = null;
while (true) {
System.out.print("Enter an integer: ");
userInput = sc.nextLine();
// Check to see if an empty string/enter/return has been input:
if (userInput.length() == 0) {
System.out.println("Input is empty!");
break;
}
// Checking to see if the input can be parsed into an int. If it can't, retry.
int intInput = 0;
try {
intInput = Integer.parseInt(userInput);
} catch (NumberFormatException e) {
System.out.println("Invalid input for type Integer. Please try again.");
continue;
}
// We know we have an int at this point. Checking that the array isn't already
// filled.
if (counter <= 2) {
intArray[counter] = intInput;
counter++;
// The array is filled, act accordingly.
} else if (counter > 2) {
System.out.println("Array is full.");
System.out.printf("Array Elements: %s", Arrays.toString(intArray));
break;
}
sc.close();
}
}
}
Good day, i'm stuck figuring out correct way to implement a function, the function has the following functionality.
1. When program starts, text is displayed to enter a key or leave field empty.
2. If text was entered , do A.
3. If text wasn't entered do B.
This is what i've done so far.
System.out.println("Enter any key to get data or leave empty");
//Just give some value
int value = 0;
try {
for (int i = 5; i > 0; i--) {
System.out.println("Starting in " + i);
Thread.sleep(1000);
//If enter was pressed then theoretically value
//should be 1(Not working)
value = System.in.read();
}
if (value != 0) {
Database.getInstance().getAllStamps();
} else {
start();
}
} catch (Exception e) {
e.printStackTrace();
}
Scanner sc = new Scanner(System.in);
for (int i = 5; i > 0; i--) {
System.out.println("Starting in " + i);
Thread.sleep(1000); // Execution pauses
if(sc.hasNext())
// call your function
break;
}
}
or
boolean flag = false;
for (int i = 5; i > 0; i--) {
System.out.println("Starting in " + i);
Thread.sleep(1000); // Execution pauses
if(sc.hasNext())
flag = true;
}
}
if(flag) {
// call your function
}
One way to get raw input is to use a java.util.Scanner.
Use something like this:
Scanner sc = new Scanner(System.in);
if(sc.hasNext()){
//do stuff with input
}
else{
//handle stuff
}
I'm trying to make a text based rock paper scissors. I want the player to choose what they want to play to, for example "best (user response/2 + 1) out of (user response)" then it asks for verification if they would like to play to that number. If they say yes it continues the game with that score, if no it loops back up and lets them choose another number and I have an else that reminds them they can either select yes or no. When they are originally asked, letters don't effect and they are asked to try again. On the second loop around (when you say no) if you enter a String instead of an Int it crashes. Here what I have.
System.out.println("Best of:");
String line = userIn.nextLine();
while (true) {
if (line.length() > 0) {
try { //try catch to stop strings for a response
bestOf = Integer.parseInt(line);
break;
} catch (NumberFormatException e) {
}
}
System.out.println("Please enter a number");
line = userIn.nextLine();
}
System.out.println("Okay, so you want to play best " + (bestOf / 2 + 1) + " of " + bestOf + "?");
String response2 = userIn.nextLine();
while (true) {
if (response2.contains("n")) {
System.out.println("What do you wish to play to then, " + name + "?");
bestOf = userIn.nextInt();
response2 = "y";
} else if (response2.contains("y") || response2.contains("Y")) {
winScore = (bestOf / 2 + 1);
System.out.println("Okay, best " + (bestOf / 2 + 1) + " of " + bestOf + " it is!");
break;
} else {
System.out.println("That's not a valid response! Try again.");
response2 = userIn.nextLine();
}
}
Instead of using parseInt use the string, in other words the input take it as string (even if is a number) them use the function "isNumber" too check if the string the user put is a number if not, do a while
System.out.println("Best of:");
String line = userIn.nextLine();
String aux = line;
do{
if (line.length() > 0)
aux = line;
if(!isNumeric(aux)){
System.out.println("Please enter a number");
line = userIn.nextLine();
}
}while(!isNumeric(aux));
bestOf = Integer.parseInt(aux);
so
public static boolean isNumeric(String str) {
try {
double d = Double.parseDouble(str);
} catch (NumberFormatException nfe) {
return false;
}
return true;
}
You can extract your loop as a method and use it in second case as well.
private Integer readInt(Scanner scanner){
String line = scanner.nextLine();
while (true) {
if (line.length() > 0) {
try { //try catch to stop strings for a response
Integer result = Integer.parseInt(line);
return result;
} catch (NumberFormatException e) {
}
}
System.out.println("Please enter a number");
line = scanner.nextLine();
}
}
or even better:
private Integer readInt(Scanner scanner){
Integer result;
do{
try{
return scanner.nextInt();
} catch (InputMismatchException e){
scanner.nextLine();
System.out.println("Please enter a number");
}
} while (true);
}
You are given a text file (customer.txt) in which name, lastname and age of customers are stored:
Ali Aslan 25
Ayse Demir 35
Ahmet Gemici 17 .
.
.
You should process this file and find number of customers for each of the following ranges:
0 - 19
20 - 59
60 -
This is my code:
import java.io.*;
import java.util.*;
public class ass11 {
public static void main(String[] args) {
Scanner inputStream = null;
try {
inputStream = new Scanner(new FileInputStream("customer.txt"));
}
catch (FileNotFoundException e) {
System.out.println("file customer.txt not found");
System.exit(0);
}
int next, x = 0, y = 0, z = 0, sum = 0;
while(inputStream.hasNextInt()) {
next = inputStream.nextInt();
sum = sum + next;
if (next >= 60)
x++;
else if (next >= 19 && next <= 59)
y++;
else
z++;
}
inputStream.close();
System.out.println(x + " customer bigger than 60");
System.out.println(y + " customer between 19 and 59");
System.out.println(z + " customers smaller then 19");
}
}
It reads only numbers. When I write a name and surname to the text file, it doesn't work and I don't use the split() method...
I would recommend testing with the original file:
Ali Aslan 25
Ayse Demir 35
Ahmet Gemici 17
Each line is a name plus age, so you would get a code like:
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("path/to/file" ), "UTF-8"));
String line;
while ((line = reader.readLine()) != null) {
String[] contents = line.split(" ");
// Assume contents is 3 long: name, surname, age
System.out.printf("%s %s is %d", contents[0], contents[1], Integer.parseInt(contents[2]));
}
Yes, this does make use of the split method, which makes it easier in my opinion. You could also use the Scanner by calling it in a loop with next(), next() and nextInt()
Try this code. It works.
import java.io.BufferedReader;
import java.io.FileReader;
public class MyProject {
public static void main(String [] args){
String path = "C:/temp/stack/scores.txt";
processTextFile(path);
}
public static void processTextFile(String filePath) {
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(filePath));
String line = br.readLine();
String [] tokens = null;
int score = 0;
int x = 0;
int y = 0;
int z = 0;
while (line != null) {
tokens = line.split(" ");
score = Integer.parseInt(tokens[tokens.length -1]);
if(score >= 0 && score < 20){
x++;
}
if(score >= 20 && score < 60){
y++;
}
if(score > 60){
z++;
}
line = br.readLine();
}
if (br != null) {
br.close();
}
System.out.println("0-20 = " + x + ", 20-60 = " + y + ", 60+ = " + z);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Having trouble creating a while loop that continues reading users input values, until the value of 0 is entered. Then the average of all the values will be calculated and printed at the end. Here is part of my coding but this is incorrect. Just showing you the way I perceive the problem.
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
String inputValues;
int sum = 0;
double average;
inputValues = input.readLine();
String[] intValues = inputValues.split("\\s+");
// This is incorrect but this is the idea I am looking for
while(intValues != 0) {
sum += Integer.parseInt(intValues[i]);
}
// Here the average is calculated as a double, and printed below.
average = Double.parseDouble(sum / intValues.length);
System.out.print(average);
You might want to try Scanner here.
Scanner scanner = new Scanner(System.in);
while(scanner.hasNextInt()) {
int num = scanner.nextInt();
if (num == 0)
break;
sum += num;
count += 1;
}
System.out.println("Average: " + sum/count);
For BufferedReader case:
int i = 0;
while(intValues[i] != 0) {// assuming all the number were entered in one line with space as delimiter
sum += Integer.parseInt(intValues[i++]);
}
System.out.println("Average: " + sum/intValues.length);
You could start by using a Scanner class, which will allow you to process the input, for example...
Scanner input = new Scanner(System.in);
int sum = 0;
boolean exit = false;
do {
String input = scanner.nextLine();
Scanner check = new Scanner(input);
if (check.hasNextInt()) {
int value = check.nextInt();
if (value == 0) {
exit = true;
} else {
sum += value;
}
}
} while (!exit);
hasNextInt avoids the possible exception that Integer.parseInt will generate if you try and parse a none-numerical value.
You could also use a while (check.hasNextInt()) {... to loop of multiple input values from a single line of input...
You can check the documentation for Scanner here
If you wish to continue using the BufferedReader, you could use the some stye of logic...
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
int sum = 0;
int count = 0;
double average;
try {
boolean exit = false;
do {
System.out.print(">> ");
String inputValues = input.readLine();
String[] intValues = inputValues.split("\\s+");
for (String value : intValues) {
if ("0".equals(value.trim())) {
exit = true;
break;
} else {
count++;
System.out.println(value);
sum += Integer.parseInt(value);
}
}
} while (!exit);
System.out.println(sum + " / " + count);
average = (double) sum / (double) count;
System.out.print(average);
} catch (IOException exp) {
exp.printStackTrace();
} catch (NumberFormatException exp) {
exp.printStackTrace();
}
Try this
Boolean flag=true;
int counte=0;
while(flag)
{
inputValues = input.readLine();
if(Integer.parseInt(inputValues)==0)
{
flag=false;
continue;
}
counter++; // used to take avarage
sum+=Integer.parseInt(inputValues);
}
And After Loop is finished calculate the avarage