I'm making a program of battleship with the user going against the computers random inputs choices in an 8x8 grid.
What I'm having trouble with is that I don't want my program to crash if my user inputs a String, such as "asdfklasdn", "h", etc... It doesn't crash if its an integer, such as 1,5,etc. Is there any way to change this without changing the rows and columns to strings? If I use try catch, it just gives me an error in the if-else statements right after in the userFire method.
Any help will be much appreciated. Thank you!
import java.util.*;
import java.util.Scanner;
public class Battleship
{
Scanner input = new Scanner(System.in);
public static final boolean DEBUG = false;
public static void breakln()
{
System.out.println("─────────────");
}
public static void createBoard(String [][]board)
{
for( int r = 0; r<board.length; r++)
{
for(int c= 0; c<board[0].length; c++)
{
board[r][c] = "-";
}
}
}
public static void showBoard(String[][] board)
{
breakln();
for(int r =0; r<board.length;r++)
{
if(DEBUG == true)
{
for(int c = 0; c<board[0].length;c++)
{
System.out.print(" " +board[r][c]);
}
System.out.println("");
}
else
{
for(int c = 0; c<board[0].length;c++)
{
if(board[r][c].equals("S"))
{
System.out.print(" " + "-");
}
else
{
System.out.print(" " + board[r][c]);
}
}
System.out.println("");
}
}
breakln();
}
public static void createShip(String[][] board, int size)
{
if(Math.random()<0.5)
{
int col = (int)(Math.random()*5);
int row = (int)(Math.random()*7);
for(int i = 0; i<size; i++)
{
board[row][col+i]="S";
}
}
else
{
int col = (int)(Math.random()*7);
int row = (int)(Math.random()*5);
for(int i = 0; i<size; i++)
{
board[row+i][col]="S";
}
}
}
public static int userFire(String[][] board, int hits, int torps)
{
Scanner input = new Scanner(System.in);
int row,col;
System.out.println("You have: " + torps + " torpedos");
System.out.println("Select row to fire in: ");
row = input.nextInt();
while(row>8||row<1)
{
System.out.println("Invalid. Enter a valid row (1-8)");
row = input.nextInt();
}
System.out.println("Select column to fire in: ");
col = input.nextInt();
while(col>8 || col<1)
{
System.out.println("Invalid. Enter a valid column (1-8)");
col = input.nextInt();
}
if(board[row-1][col-1].equals("S"))
{
hits++;
System.out.println("HIT ");
board[row-1][col-1] = "×";
}
else
{
System.out.println("MISS");
board[row-1][col-1] = "Ø";
}
return hits;
}
public static void endOfGame(int hits, int torps)
{
if(hits<4)
System.out.println(" LOSE ");
if(torps<1)
System.out.println("You have lost all your torpedos.");
else
if(hits>=4)
{
System.out.println("WINNER");
}
System.out.println("");
}
public static void main(String[] args)
{
System.out.println(" BATTLESHIP ");
System.out.println("");
String[][] board = new String[8][8];
createBoard(board);
createShip(board,4);
int torps = 25;
int hits = 0;
while(torps>0 && hits<4)
{
showBoard(board);
hits = userFire(board,hits,torps);
torps--;
}
endOfGame(hits, torps);
}
}
I've tried everyone's answers, but I received errors in this code.
if(board[row-1][col-1].equals("S"))
{
hits++;
System.out.println("╠══ HIT ══╣");
board[row-1][col-1] = "×";
}
else
{
System.out.println("╠══ MISS ══╣");
board[row-1][col-1] = "Ø";
}
return hits;
Add try/catch block inside row=input.nextInt() or every variable who receives input;
Here's sample code
try{
row = input.nextInt();
}
catch(Exception)
{
}
Just catch the exception, e.g.
try {
row = input.nextInt();
} catch (InputMismatchException e) {
System.err.println("Input is not an integer"); // or do some error handling
}
Try this out:
System.out.println("Invalid. Enter a valid row (1-8)");
String userInput = input.next();
try {
row = Integer.parseInt(userInput);
} catch (NumberFormatException exp) {
// Failed : Invalid input. Take actions if required.
// May be prompt user for correct input
}
You can use while(input.hasNextInt()) and println a message saying you only want ints?
Or a catch block as BroSlow said.
try {
xxx = input.nextInt();
} catch(NumberFormatException nfe) {
doXXXLoop();
}
// ....
public void doXXXLoop() {
System.out.println("Not a valid number. Enter another:");
try {
xxx = input.nextInt();
} catch(NumberFormatException nfe) {
doXXXLoop();
}
}
Unlike other code, this will easy repeat until a valid int is entered. Replace XXX with Row or Col or whatever you want.
Related
So my professor had us do an assignment that asks the user for 5 numbers that are valid (51-99) and unique (non-repeating). I just can't figure out why my nested for loop inside the while loop is not incrementing the i, I suspect it is the break; but without that the for loop keeps looping. Any help would be awesome. Thank you.
public static void main(String[] args) {
int[] userArray;
userArray = new int[5];
int real = 0;
System.out.println("Please print out 5 numbers between 50 and 100. ");
Scanner entry = new Scanner(System.in);
while (real < 5) {
int count = entry.nextInt();
boolean aCount = isValid(count);
if (aCount == true) {
for (int i =0; i < userArray.length; i++) {
userArray[i] = count;
real++;
break;
}
} else {
System.out.println("That is not a valid number.");
}
}
}
public static boolean isValid(int a) {
if (a > 50 && a < 100) {
return true;
} else {
return false;
}
}
I got it guys! I just had to remove the for loop and put this in:
userArray[i] = count;
i++;
real++;
Thank you schmidt73 and everyone that helped!
int i=0;
while (real < 5) {
int count = entry.nextInt();
boolean aCount = isValid(count);
if (aCount == true) {
userArray[i++] = count;
real++;
} else {
System.out.println("That is not a valid number.");
}
}
I guess this is what you are trying to do.
First, you also need to test if the array contains the value you are trying to add (in validate). You could do something like
public static boolean isValid(int[] arr, int real, int a) {
if (a > 50 && a < 100) {
for (int i = 0; i < real; i++) {
if (arr[i] == a) {
return false;
}
}
return true;
}
return false;
}
Then your main method might be written like
int[] userArray = new int[5];
int real = 0;
System.out.println("Please print out 5 numbers between 50 and 100. ");
Scanner entry = new Scanner(System.in);
while (real < 5) {
int count = entry.nextInt();
if (isValid(userArray, real, count)) {
userArray[real++] = count;
} else {
System.out.println("That is not a valid number.");
}
}
System.out.println("The array contains: " + Arrays.toString(userArray));
I have this method and it works fine. I need to put a try/catch statement so
the method can continue if the user puts in a letter. I don't know where to put the statement, It seems everywhere I put it it get's wrong. Could somebody please show me where to put this statement?
public void myMethod() {
Scanner in = new Scanner(System.in);
int array[] = new int[21];
int number;
boolean end = false;
while (!end) {
System.out.println("Please give an number between 0-20: ");
number = in.nextInt();
for (int i = 1; i < array.length; i++) {
if (i == number) {
System.out.println(array[number]);
end = true;
}
}
if (!end) {
System.out.println("I cant find number " + number
+ " in the array, please try again ");
}
}
}
Your for loop I can't explain, you need only check values between 0 and 20,
And when you call try catch, you have to skip loop after exception
public static void myMethod() {
Scanner in = new Scanner(System.in);
int array[] = new int[21];
int number=0;
boolean end = false;
while (!end) {
System.out.println("Please give an number between 0-20: ");
//check symbol
try{
number = Integer.valueOf(in.next());
}catch(Exception e)
{
System.out.println("It's not a number! ");
continue; //skip loop
}
if((number>=0)&&(number<=20))
{
System.out.println(array[number]);
end=true;
}
else
System.out.println("I cant find number " + number
+ " in the array, please try again ");
/* why do you use loop here???
* u need to check if number between 0-20
for (int i = 1; i < array.length; i++) {
if (i == number) {
System.out.println(array[number]);
end = true;
}
}*/
}
}
public static void main(String[] args) {
Test test = new Test();
Scanner in = new Scanner(System.in);
int array[] = new int[21];
int number;
System.out.println("Please give an number between 0-20: ");
do{
try{
number = Integer.parseInt(in.next());
}
catch(Exception e){
System.out.println("Please give an number between 0-20: ");
number = -1;
}
}
while(!(number <= 20 && number >=0 ));
System.out.println(array[number]);
}
System.out.println("Please give an number between 0-20: ");
try{
number = in.nextInt();
}catch(Exception e){
number = 1; //Put random number of default number here
}
Im trying to find the lonely integer in an array. My output is correct, but still getting the extra message. Please have a look at the code. I’m using Java to write the program.
Code:
import java.util.InputMismatchException;
import java.util.Scanner;
public class LonelyInteger {
private static int inputArray[];
private static int inputLength;
private static final Scanner scanner = new Scanner(System.in);;
public static void main(String[] args) {
try {
if (getInput()) {
sortAndPrintArray();
findLonelyInteger();
} else {
System.out.println("OOPS, something is not right! Try again!");
}
} catch (NumberFormatException | InputMismatchException nfime) {
System.out.print("Number Format Exception or Input Mismatch Exception Occured: " + nfime);
} catch (Exception e) {
System.out.print("Exception Occured: " + e.getMessage());
}
}
private static boolean getInput() throws NumberFormatException, InputMismatchException, Exception {
System.out.print("Enter the array length: ");
inputLength = scanner.nextInt();
if (inputLength <= 0) {
return false;
}
inputArray = new int[inputLength];
System.out.println("Enter the array:");
for (int i = 0; i < inputLength; i++) {
inputArray[i] = scanner.nextInt();
}
return true;
}
private static void sortAndPrintArray() {
sortArray();
printSortedArray();
}
private static void sortArray() {
int temp = 0;
for (int i = 0; i < inputLength; i++) {
for (int j = 0; j < i; j++) {
if (inputArray[i] < inputArray[j]) {
temp = inputArray[i];
inputArray[i] = inputArray[j];
inputArray[j] = temp;
}
}
}
}
private static void printSortedArray() {
System.out.println("Sorted Array:");
for (int i = 0; i < inputLength; i++) {
System.out.print(inputArray[i] + " ");
}
System.out.println();
}
private static void findLonelyInteger() {
boolean foundLonelyInteger = false;
for (int i = 0; i < inputLength; i++) {
if ((i+1) == inputLength) {
System.out.println("Lonely Integer: " + inputArray[i]);
break;
}
if (inputArray[i] == inputArray[++i]) {
continue;
} else {
System.out.println("Lonely Integer: " + inputArray[i-1]);
foundLonelyInteger = true;
i--;
}
}
if (!foundLonelyInteger) {
System.out.println("Lonely integer not available!");
}
}
}
Here is my output, which is seen in Command Prompt:
Output:
Enter the array length: 5
Enter the array:
1
2
2
1
2
Sorted Array:
1 1 2 2 2
Lonely Integer: 2
Lonely integer not available!
You did not set the flag, in your findLonelyInteger() method's first if condition!
if ((i+1) == inputLength) {
System.out.println("Lonely Integer: " + inputArray[i]);
foundLonelyInteger = true; // --> HERE
break;
}
Command Prompt? Start using Eclipse! And learn debugging!
Set your foundLonelyInteger = true; while you are checking for if((i+1) == inputLength)
I made this java code to input a number:
public static void main(String[] args)
{
int temp;
do{
Scanner scan = new Scanner(in);
out.print("enter number ");
temp = scan.nextInt();
if(temp >= 5 && temp <= 40){
int x = (temp-1)*2 +1;
int y = x/2;
int z = 1;
for(int i=0; i<temp-1; i++)
{
for(int j=0; j<=y; j++)
{
out.print(" ");
}
for(int k = 0; k<z; k++)
{
out.print("|");
}
out.println();
y--;
z+=2;
}
for(int c = 0; c < 1 + temp/10; c++) {
for (int i = 0; i <= x / 2; i++)
{
System.out.print(" ");
}
System.out.println("|");
}
}else{
out.print("enter a number between 5 and 40");
}
}while(temp != 0);
}
}
However, this will return an error if I enter for example a letter or an invalid character. I would like to know how to, instead of making the program crash, make it display an error message and then asking again the question until the entry is correct?
import java.io.*;
import java.util.*;
public class Main
{
public static void main(String[] args)
{
int temp=0;
boolean error=false;
do{
error=false;
try
{
Scanner scan = new Scanner(System.in);
System.out.print("enter number ");
temp = scan.nextInt();
if(temp==0)
break;
if(temp >= 5 && temp <= 40)
{
int x = (temp-1)*2 +1;
int y = x/2;
int z = 1;
for(int i=0; i<temp-1; i++)
{
for(int j=0; j<=y; j++)
{
System.out.print(" ");
}
for(int k = 0; k<z; k++)
{
System.out.print("|");
}
System.out.println();
y--;
z+=2;
}
for(int c = 0; c < 1 + temp/10; c++)
{
for (int i = 0; i <= x / 2; i++)
{
System.out.print(" ");
}
System.out.println("|");
}
}
else
{
System.out.println("enter a number between 5 and 40");
}
}catch(Exception e)
{
System.out.println("Enter a valid number..try again");
error=true;
}
}while(temp != 0 || error);
}
}
When the error or exception occurs i.e. in scan.nextInt() an Exception is thrown and as you have not caught the exception the JVM stops executing the program.
So always write statements which can throw Exceptions within a try{ } block and immediately follow it with a catch(Exception e) {} block to catch the exception. If no exception occurs then catch block will not execute. If any error occurs inside try{} block : control jumps to catch block and it is executed and all other statements in try{} (after the erroneous line) are ignored.
try
{
..
error
.. // skipped
..
}
catch(Exception e)
{
...
...// handle exception
}
// control comes here after executing catch block
Read in the value from the user as a string and then try to parse it to a number in a try {} catch{} block, if an exception is thrown parsing it, tell the user only numbers are acceptable. if not continue processing with the number they gave you.
The Scanner has a method to check if the next token is an integer: hasNextInt.
You could do this:
package com.sandbox;
import java.util.Scanner;
public class Sandbox {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter an integer:");
while (!scanner.hasNextInt()) {
System.err.println("Wrong! Enter an integer");
scanner.next();
}
System.out.println("Your integer was: " + scanner.nextInt());
}
}
This worked as you'd want on a windows console. I'm a little concerned it'll work incorrectly on Linux/Mac. Anyone mind testing it out for me? If this works, I like it best because there's no try/catch.
Extending from #Shouvik Roy's answer..
import java.util.Scanner;
public class Bingo {
public static void main(String[] args){
boolean isInt = false;
int temp;
System.out.print("enter a number ");
do{
Scanner scan = new Scanner(System.in);
try
{
temp = scan.nextInt();
isInt = true;
}
catch(Exception e)
{
System.out.println("Couldn't read number. Reason - "+e.getMessage());
System.out.println("Enter a valid number ");
}
}while(!isInt);
}
}
------------------Edit-------------------
boolean isInt = false;
System.out.print("enter a number ");
do{
try
{
Scanner scan = new Scanner(in);
temp = scan.nextInt();
isInt = true;
}
catch(Exception e)
{
System.out.println("Couldn't read number. Reason - "+e.getMessage());
System.out.println("Enter a valid number ");
}
}while(!isInt)
I am supposed to write a program that will prompt the user to enter the hotel rooms that are occupied. Once that is done the user enters -1 and is prompted to enter a random hotel number. If the hotel room is occupied, it prints occupied. If the room is unoccupied, it printer unoccupied. I can't seem to figure out why the unoccupied won't print. Suggestions?
import java.util.Arrays;
import java.util.Scanner;
public class GoughAndreaChapter9
{
public static void main(String[] args)
{
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
int [] arr=new int[100];
int counter=0;
int currval=0;
System.out.println("Please enter an occupied hotel room number, -1 to quit ");
do
{
currval = sc.nextInt();
if(currval==-1)
break;
if(currval>0)
arr[counter++]=currval;
}
while(currval !=-1);
// sort using java API
int [] temparr=new int[counter];
for(int i = 0; i<counter; i++)
{
temparr[i] = arr[i];
}
arr = temparr;
Arrays.sort(arr);
//binary search.
int low=0;
int high = counter-1;
System.out.println("Please enter a room to search for: ");
currval = sc.nextInt();
int status=0;
int mid;
while(low<high)
{
if(arr[low]==currval)
{
System.out.println("Occupied");
status=1;
break;
}
else if(arr[high]==currval)
{
System.out.println("Occupied");
status=1;
break;
}
mid = low+high/2;
if(arr[mid]==currval)
{
System.out.println("Occupied");
status=1;
break;
}
else if(arr[mid]<currval)
{
low=mid;
}
else if(arr[mid]<currval)
{
high = mid;
}
}
if(status==0)
System.out.println("Unoccupied");
}
}
Don't ofuscate! Do this:
Room.java
public class Room {
private boolean isOccupied;
public Room() {
this.isOccupied = false;
}
public boolean obtainTheRoom() {
if(!isOccupied) this.isOccupied = true;
return !isOccupied;
}
}
Main.java
import java.util.Scanner;
public final class Main {
private static final int ROOM_AMOUNT = 50;
private static int actualRoom;
private static Scanner cmdin = new Scanner(System.in);
public static void main(String[] args) {
Room[] rooms = new Room[ROOM_AMOUNT];
// Select some random, but static rooms to be occupied
for(int i = 1; i <= ROOM_AMOUNT; i++) {
if(i % 3 - 1 == 0 || i * 2 % i + 10 - 2 == 2) {
rooms[i - 1].obtainTheRoom();
}
}
for(;;) {
System.out.print("Enter a room number:\t");
try {
actualRoom = Integer.parseInt(cmdin.next());
} catch(NumberFormatException nfe) {
loopRoomNumber();
}
if(rooms[actualRoom - 1].obtainTheRoom()) {
System.out.println("Got the room " + actualRoom + "! Now it's occupied -_-");
} else {
System.out.println("Room Occupied!");
}
}
}
private static void loopRoomNumber() {
System.out.print("That's not a valid room number!\n\n");
try {
actualRoom = Integer.parseInteger(cmdin.next());
} catch(NumberFormatException nfe) {
loopRoomNumber();
}
}
}
That should work. Good luck!
I would change your last else if statements as follows. This will work. Because otherwise you will go in an endless loop;
else if (arr[mid] < currval)
{
low = mid;
--high;
}
else if (arr[mid] > currval)
{
high = mid;
++low;
}
Note that i have decremented the high when the mid value is less than the current value, and incremented the low value when the mid value is greater than the current value