Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 15 - java

I cannot find my exception although the errors are at
at puzzle.Puzzle.isSafe(Puzzle.java:97)
at puzzle.Puzzle.main(Puzzle.java:49)
Java Result: 1
I need to print a 15x 15 grid with random words in 6 directions and starts in empty spaces.
My java code is as follows.
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package puzzle;
//import java.util.Arrays;
import java.util.Random;
/**
*
* #author sony
*/
public class Puzzle {
static char[][] grid;
//class solve= new Puzzle();
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
grid =new char[15][15];
String[] words={"hello","coward","heartbeat","beautiful","kind"};
String[] direction = {"horizontal","horizontalBack","vertical","varticalUp",
"diagonal","diagonalBack"};
int i,j,x,y,dir;
Random randGen = new Random();
for(i=0; i<15 ;i++)
{
for(j=0;j<15;j++)
grid[i][j]='*';
}
for(i=0;i< words.length;i++)
{
int set=0;
while(set!=1)
{
x = randGen.nextInt(15);
y = randGen.nextInt(15);
dir = randGen.nextInt(6);
if((isSafe(x,y,words[i],direction[dir])))
{
place(x,y,words[i],direction[dir]);
set=1;
}
}
}
for(i=0; i<15; i++)
{
for(j=0;j<15;j++)
System.out.print(grid[i][j]);
System.out.println("");
}
}
static boolean isSafe(int x,int y, String word, String d)
{ int len=word.length();
int i,k,j;
if(d.equals("horizontal"))
for(i=y,k=0;i< (y+len);i++,k++)
{
if((grid[x][i]!='*')&& (grid[x][i]!=word.charAt(k)) && ((y+len) >15) )
return false;
}
if(d.equals("horizontalBack"))
for(i=y,k=0;i >(y-len);i--,k++)
{
if((grid[x][i]!='*')&& (grid[x][i]!=word.charAt(k)) && ((y-len) <0) )
return false;
}
if(d.equals("vertical"))
for(i=x,k=0;i <(x+len);i++,k++)
{
if((grid[i][y]!='*')&& (grid[i][y]!=word.charAt(k)) && ((x+len) >15) )
return false;
}
if(d.equals("verticalUp"))
for(i=x,k=0;i >(x+len);i++,k++)
{
if((grid[i][y]!='*')&& (grid[i][y]!=word.charAt(k)) && ((x-len) <0) )
return false;
}
if(d.equals("diagonal"))
{ k=0;i=y;j=x;
while((i< (y+len)) && (j< x+len)) {
if((grid[i][j]!='*')&& (grid[i][j]!=word.charAt(k)) && ((x+len) >15) && ((y+len)>15) )
{return false;}
i++;j++;k++;
}
}
if(d.equals("diagonalBack"))
{ k=0;i=y;j=x;
while((i> (y-len)) && (j>x-len)) {
if((grid[i][j]!='*')&& (grid[i][j]!=word.charAt(k)) && ((x-len)<0) && ((y-len)<0) )
{return false;}
i--;j--;k++;
}
}
return true;
}
static void place(int x, int y, String word, String d)
{ int len = word.length();
int i,k,j;
if(d.equals("horizontal"))
for( i=y, k=0;i< (y+len);i++,k++)
{
grid[x][i]=word.charAt(k);
}
if(d.equals("horizontalBack"))
for( i=y,k=0;i> (y-len);i--,k++)
{
grid[x][i]=word.charAt(k);
}
if(d.equals("vertical"))
for( i=x,k=0;i< (x+len);i++,k++)
{
grid[i][y]=word.charAt(k);
}
if(d.equals("verticalUp"))
for( i=x,k=0;i> (x-len);i--,k++)
{
grid[i][y]=word.charAt(k);
}
if(d.equals("diagonal"))
{ i=y;j=x;k=0;
while((i< (y+len)) && (j< (x+len)))
{
grid[i][j]=word.charAt(k);
i++;j++;k++;
}
}
if(d.equals("diagonalUp"))
{ i=y;j=x;k=0;
while((i> (y-len)) && (j> (x-len)))
{
grid[i][j]=word.charAt(k);
i--;j--;k++;
}
}
}
}

Instead of telling you how to fix your code, I'll help you understand the error.
Log
at puzzle.Puzzle.isSafe(Puzzle.java:97)
at puzzle.Puzzle.main(Puzzle.java:49)
Java Result: 1
Puzzle.java:97
if (grid[i][j]!='*' && grid[i][j]!=word.charAt(k) && (x+len)>15 && (y+len)>15)
Exception
Exception java.lang.ArrayIndexOutOfBoundsException means that either:
i >= grid.length
j >= grid[i].length
Detail
grid.length and grid[i].length are determined when the array is created:
grid = new char[15][15];
grid.length is 15
grid[i].length is 15
Moreover
Also, there is the string word:
for (i=y, k=0; i < (y+len); i++, k++)
word.charAt(k);
This will cause an issue too, when k at some point becomes k >= word.length() so that loop should be like this:
for (i=y, k=0; i < (y+len) && k < word.length(); i++, k++)
word.charAt(k);

I can see two bugs.
(1) The line that reads
for(i=x,k=0;i >(x+len);i++,k++)
should read
for(i=x,k=0;i >(x-len);i--,k++)
I think it's line 89.
(2) The bug that's causing this exception is the fact that every time you've got a whole lot of conditions separated by &&, the first one should be && and the subsequent ones should be ||.
For example,
if((grid[x][i]!='*')&& (grid[x][i]!=word.charAt(k)) && ((y+len) >15)) {
should read
if((grid[x][i]!='*')&& (grid[x][i]!=word.charAt(k)) || ((y+len) >15)) {
because you need to return that this square is an unsafe place to start the word if y + len > 15 regardless of what is found at each of the grid squares that you're checking. Similarly, with all the other conditions that look like this.

Please note the typo. varticalUp in the array declaration and verticalUp in the if condition. Although this is not the cause of the problem but its worth noting it.

I just quickly went through your code and it seems that the problem is in your variable len. See the statement int len=word.length(); on line 68. In fact it should be int len=word.length()-1; because the array index starts from 0. I have not tested it, but you can give it a try.

Related

Java: Error in code for a Recursive Maze for using Java

this code below is for a maze via recursion and is supposed to solve the maze. There are three different txt files that it reads from S is the start, G is the goal, X is a barrier and O is a free space
GOOOOXO //maze1
XXOXOOX
OXOOOXX
XXXOOXO
XXXXOXX
SOOOOOX
XXXXXXX
XOOOOXO //maze2
XXOXOOG
OXOOOXX
XXXOOOX
XXXXOXX
SOOOOOX
XXXXXXX
XOOOOXO //maze3
XXOXOXG
OXOOOXX
XXXOOOX
XXXXOXX
SOOOOOX
XXXXXXX
These are the mazes. maze1 and maze2 have a solution but every time I run it, it returns "unsolvable". I'm not sure where the error is. Here is the full code:
import java.util.ArrayList;
import java.util.Scanner;
import java.io.File;
import java.io.IOException;
public class Maze2
{
private static char[][] maze;
private static int startrow, startcol, finishrow, finishcol;
private static ArrayList<String> mazeBuffer;
public static void initializeMaze(String fileName)
{
startrow = startcol = finishrow = finishcol = -1;
mazeBuffer = new ArrayList<String>();
int numcols = 0;
try
{
Scanner file = new Scanner(new File(fileName));
while(file.hasNext())
{
String nextLine = file.nextLine();
mazeBuffer.add(nextLine);
if (nextLine.length() > numcols)
numcols = nextLine.length();
}
}
catch(Exception e)
{
System.out.println(fileName + " has an issue");
}
int numrows = mazeBuffer.size();
maze = new char[numrows][numcols];
for (int r = 0; r < numrows; r ++)
{
String row = mazeBuffer.get(r);
for (int c = 0; c < numcols; c++)
{
if(row.length() >= c)
maze[r][c]=row.charAt(c);
else
maze[r][c]='*';
if (maze[r][c] == 'S')
{
startrow = r;
startcol = c;
}
if (maze[r][c] == 'G')
{
finishrow = r;
finishcol = c;
}
}
}
System.out.println("Maze loaded");
}
public static void printMaze()
{
for (char[] row: maze)
{
for (char c: row)
System.out.print(c);
System.out.println();
}
System.out.println();
}
public static void main (String[] args)
{
initializeMaze("maze3.txt");
printMaze();
if (solveMaze(startrow, startcol))
printMaze();
else
System.out.println("Unsolvable.");
}
public static boolean solveMaze(int r, int c)
{
if(r < 0 || c < 0 || r >= maze.length || c >= maze[0].length)
return false;
if(maze[r][c]=='G')
return true;
if (maze[r][c] != '0'|| maze[r][c] != 'S')
return false;
maze[r][c]='A';
if(solveMaze(r-1,c))
{
maze[r][c]= '#';
return true;
}
if(solveMaze(r+1,c))
{
maze[r][c]='#';
return true;
}
if(solveMaze(r,c-1))
{
maze[r][c]='#';
return true;
}
if(solveMaze(r,c+1))
{
maze[r][c]='#';
return true;
}
else{
return false;
}
}
}
If all is correct, mazes 1 and 2 should be solvable but as of now they are not for some reason. plz help it's a project due soon and I can't figure it out.
The problem lies in the condition if you are on a valid path.
The first error is, that you are checking for the number 0 instead of the capital letter O.
The second error is the combination of the two conditions. If you start at 'S' you are obviously not at an 'O'. So your condition tells you, that you are not on a valid path. The check should be:
if(!(maze[r][c] == 'O'|| maze[r][c] == 'S'))
If you fix this, everything should be working fine.

Can't seem to get my method (in Java) to compile correctly

I am trying to figure out exactly what is wrong with my winorTie method in this little tictacttoe game I am trying to create. Would anyone be able to help? Thanks
package tictactoegame;
/**
*
* #author Douglas Boulden
*/
public class tictactoegame {
static int [][] gameboard;
static final int EMPTY = 0;
static final int NOUGHT = -1;
static final int CROSS = 1;
static void set (int val, int row) throws IllegalArgumentException {
int col = 0;
if (gameboard[row][col] == EMPTY)
gameboard[row][col] = val;
else throw new
IllegalArgumentException("Player already there!");
}
static void displayBoard () {
for (int[] gameboard1 : gameboard) {
System.out.print("|");
for (int c = 0; c < gameboard1.length; c++) {
switch (gameboard1[c]) {
case NOUGHT:
System.out.print("0");
break;
case CROSS:
System.out.print("X");
break;
default: //Empty
System.out.print(" ");
}
System.out.print("|");
}
System.out.println("\n------\n");
}
}
static void createBoard(int rows, int cols) {
gameboard = new int [rows] [cols];
}
static int winOrTie() {
if (gameboard [0][0] == NOUGHT && gameboard [0][-1])
return NOUGHT;
} else if (gameboard [0][0] == && CROSS) [0][1] {
return CROSS;
} else if (gameboard [0][0]== && " "()) [0][0] {
return 0;
} else {
return false;
}
/**
* #param args the command line arguments
*/ /**
* #param args the command line arguments
*/
public static void main(String[] args) {
createBoard(3,3);
int turn = 0;
int playerVal;
int outcome;
java.util.Scanner scan = new
java.util.Scanner(System.in);
do {
displayBoard();
playerVal = (turn % 2 == 0)? NOUGHT : CROSS;
if (playerVal == NOUGHT) {
System.out.println ("\n-0's turn-");
} else {
System.out.println("\n-X's turn-");
}
System.out.print("Enter row and Column:");
try {
set(playerVal, scan.nextInt());
} catch (IllegalArgumentException ex)
{System.err.println(ex);}
turn ++;
outcome = winOrTie();
} while ( outcome == -2 );
displayBoard();
switch (outcome) {
case NOUGHT:
System.out.println("0 wins!");
break;
case CROSS:
System.out.println("X wins!");
break;
case 0:
System.out.println("Tie.");
break;
}
}
}
Some of this was mentioned in the comments, but these conditions fundamentally don't make sense:
if (gameboard [0][0] == NOUGHT && gameboard [0][-1])
return NOUGHT;
} else if (gameboard [0][0] == && CROSS) [0][1] {
return CROSS;
} else if (gameboard [0][0]== && " "()) [0][0] {
return 0;
For example, what do you think that if (gameboard [0][0] == && CROSS) [0][1] is supposed to do? What exactly is " "() supposed to be? And what do you think that == && does? It's difficult to know exactly what you were actually trying to achieve here.
Also, consider gameboard [0][-1]. There are two problems here. First, you do realize that -1 isn't actually a valid array index in Java, right? (That's allowable in Python, but not Java). Also, gameboard [0][-1] is an integer, not a bool, so && gameboard [0][-1] doesn't make sense. If you have something like A && B, both A and B must evaluate to some kind of boolean value (i.e. true or false).
Also, I'd encourage you not to do indentation like you have here. I'd recommend putting each "else if" on its own line.

Why is this Array getting modified? [duplicate]

This question already has answers here:
How to clone a multidimensional array in java? [duplicate]
(2 answers)
Closed 8 years ago.
I have an array called maze which in, theory, should get modified only in the updateMaze() method. This is because that is the final result I want to output to the console. The problem is when tempMaze gets modified maze is modified as well. This is not supposed to happen. My first thought was that they are pointing to same reference in memory however I checked and that is false. I do have to mention I used clone() at initialization to make their contents similar, and I am not sure if this could be a issue or not. (Even though I think I understand what clone() does I am not familiar enough to know if it is the problem or not.) My code:
public class ThreadTheMaze {
ArrayList<Cell> result = new ArrayList<Cell>();
private String[][] maze;
private String[][] tempMaze;
private int initRowPosition;
private int initColPosition;
private int amtOfRows;
private int amtOfCols;
public ThreadTheMaze(int initRow, int initCol){
initRowPosition = initRow;
initColPosition = initCol;
result.add(new Cell(initRowPosition, initColPosition));
}
public void loadMaze(){
try{
Scanner in = new Scanner(new File("mazeData.txt"));
while (in.hasNextLine()){
amtOfCols = in.nextLine().length();
amtOfRows++;
}
in.close();
maze = new String[amtOfRows][amtOfCols];
in = new Scanner(new File("mazeData.txt"));
for (int r = 0; r < amtOfRows; r++){
String line = in.nextLine();
for (int c = 0; c < amtOfCols; c++){
maze[r][c] = line.substring(0,1);
line = line.substring(1);
}
}
tempMaze = maze.clone();
}catch (FileNotFoundException e){
System.err.print(e);
}
}
public void printMaze(){
for (int r = 0; r < amtOfRows; r++){
for (int c = 0; c < amtOfCols; c++){
System.out.print(maze[r][c]);
}
System.out.println();
}
}
public void updateMaze(){
for (int i = 0; i < result.size(); i++){
maze[result.get(i).getRow()][result.get(i).getColumn()] = "!";
}
}
/**
#return ArrayList of objects 'Cell' that are the solution to the maze. (Note: if no solution then returns empty ArrayList)
*/
public void solve(Cell cell){
tempMaze[cell.getRow()][cell.getColumn()] = "!";
ArrayList<Cell> neighbors = getNeighbors(cell);
if ((cell.getRow() == 0 || cell.getRow() == tempMaze.length-1) || (cell.getColumn() == 0 || cell.getColumn() == tempMaze[0].length-1)){
return;
}
if ((cell.getColumn() == initColPosition && cell.getRow() == initRowPosition) && neighbors.size() < 1){
return;
}
// If not in init position and has no neighbors then backtrack
if ((cell.getColumn() != initColPosition || cell.getRow() != initRowPosition) && neighbors.size() < 1){
result.remove(result.size()-1);
solve(result.get(result.size()-1));
}else if (neighbors.size() >= 1){ // If has neighbors then choose one and call the method again
result.add(neighbors.get(0));
solve(neighbors.get(0));
}
}
/**
#return ArrayList of objects 'Cell' that are empty and available to move to.
*/
private ArrayList<Cell> getNeighbors(Cell cell){
ArrayList<Cell> neighbors = new ArrayList<Cell>();
int row = cell.getRow();
int column = cell.getColumn();
int[][] moveLocs = {{row-1, column}, {row+1, column}, {row, column+1}, {row, column-1}};
for (int r = 0; r < moveLocs.length; r++){
int tRow = moveLocs[r][0];
int tCol = moveLocs[r][1];
if (isValid(tRow, tCol)){
Cell neighbor = new Cell(tRow, tCol);
neighbors.add(neighbor);
}
}
return neighbors;
}
public boolean isValid(int row, int col){
if(row < 0 || row >= amtOfRows){
return false;
}
if (col < 0 || col >= amtOfCols){
return false;
}
if (!tempMaze[row][col].equals(" ")){
return false;
}
return true;
}
}
The class Cell is a simple class with some simple get and set method.
I know this isn't the most concise way to present you my question, but really I can't spot a place were the problem could exist. Thanks.
clone() is shallow. This means that the following:
tempMaze = maze.clone();
only clones the first level of the 2D array. In other words, you get a new array containing the same String[] references as the original array.
For suggestions on how to fix this, see How do I do a deep copy of a 2d array in Java?

Fixing checkstyle error

I need help with the checkstyle errors i keep getting in eclipse. I have tried everything the error is in my boolean method. It is stating that my nested if else is at 1 when it is supposed to be at zero. This is for all my if statements. Another error i had was that my method has 3 returns and checkstyle says the max is 2. I just want to rid myself of these errors can someone please help me.
public class Password {
private String potentialpassword;
private static final String SPECIAL_CHARACTERS = "!##$%^&*()~`-=_+[]{}|:\";',./<>?";
/**
* initializes the potential password and takes it as a string.
*
* #param potentialpassword
* takes in the potential password
*
*/
public Password(String potentialpassword) {
super();
this.potentialpassword = potentialpassword;
}
/**
* The purpose of this method is to validate whether the password meets the
* criteria that was given
*
* #param potentialpassword
* allows a string potential password to be accepted.
* #return true or false if the method fits a certain guideline.
* #precondition password has to be greater than 6 characters long. password
* also cannot contain any whitespace and the digits cannot be
* less than one.
*/
public static boolean isValid(String potentialpassword) {
if (potentialpassword.length() < 6) {
return false;
} else {
char x;
int count = 0;
for (int i = 0; i < potentialpassword.length(); i++) {
x = potentialpassword.charAt(i);
if (SPECIAL_CHARACTERS.indexOf(String.valueOf(x)) >= 1) {
return true;
}
if (Character.isWhitespace(x)) {
return false;
}
if (Character.isDigit(x)) {
count++;
} else if (count < 1) {
return false;
}
}
return true;
}
}
/**
* Print the potential string characters on a separate line.
*
* #return the potential password characters on each line.
*
*
*/
public String toString() {
String potentialpassword = "w0lf#UWG";
for (int i = 0; i < potentialpassword.length(); i++) {
System.out.println(potentialpassword.charAt(i));
}
return potentialpassword;
}
}
Style checkers can complain a lot. You can quiet it down by changing its settings to not be so picky, or you can work on some of its suggestions. In your case it does not like too much nesting and it does not like multiple returns.
The else after a return might be an issue, so you could say
if (potentialpassword.length() < 6) {
return false;
}
char x;
int count = 0;
for (int i = 0; i < potentialpassword.length(); i++) {
.
.
.
to reduce nesting. If the multiple return statements is more of a problem you can try:
// NOTE I am just copying over your code and not worrying about the algorithm's correctness
boolean valid = true;
if (potentialpassword.length() < 6) {
valid = false;
} else {
char x;
int count = 0;
for (int i = 0; i < potentialpassword.length(); i++) {
x = potentialpassword.charAt(i);
if (SPECIAL_CHARACTERS.indexOf(String.valueOf(x)) >= 1) {
valid = true;
break;
}
if (Character.isWhitespace(x)) {
valid = false;
break;
}
if (Character.isDigit(x)) {
count++;
} else if (count < 1) {
valid = false;
break;
}
}
return valid;
}
which reduces the number of return statements, but the nesting level stays high. Perhaps breaking your code into smaller methods may help:
public static boolean isValid(String potentialpassword) {
return potentialpassword.length >= 6 &&
containsAtLeastOneSpecialCharacter(potentialpassword) &&
!containsWhitespace(potentialpassword) &&
startsWithADigit(potentialpassword);
}
Then you have no nesting here, but the code is a little less efficient because you run each test on the whole string. And you will have quite a few more lines of code. I would imagine checkstyle would be quieter, though.

a method always returns false even if i enter valid values

in this method i have tried to set row =0 , row =1 row =2 row =3 row =4 and the result is always false. i think its something considering the initilization of the variable valid but if i do not initialize the compiler comes up with error
public static boolean isValidMove(int row,int col){
boolean valid=false;
if(row>=0&&row<3&&col>=0&&col<3){
if (takenSquare[row][col]==false) {
valid= true;
}
}
Seems like your condition is never evaluated at all
public static boolean isValidMove( int nRow,int nCol ) {
boolean blValid = false;
if( ( nRow >= 0 && nRow < 3 ) && ( nCol >= 0 && nCol < 3 ) ) {
if ( arTakenSquare[ nRow ][ nCol ] == false ) {
blValid = true;
}
}
return blValid;
}
May be this would help.
Your code is valid (for values from 0 to 2). Of course you need a return statment. The only thing that can be wrong is takenSquare[row][col]==false. Is that a array of boolean values?
This is not an answer, but an extension to my comment suggesting an SSCCE. I have taken the code from the question, and wrapped it in a simple test program. To complete the isValidMove method I added a return of valid and a }.
It prints row=0, col=0: true. This confirms the bug is not in the code quoted in the question.
The next step is for the OP to either modify this until it reproduces the problem, or simplify the rest of the OP's program until it is about this long. Either way, the objective is a short, simple program that compiles, runs, and demonstrates the problem. Often, the attempt write such a thing will bring out the bug. If it does not, posting the SSCCE will certainly get a useful answer.
public class Test
{
private static boolean[][] takenSquare = new boolean[3][3];
public static void main(String[] args) {
System.out.println("row=0, col=0: "+isValidMove(0,0));
}
public static boolean isValidMove(int row, int col) {
boolean valid = false;
if (row >= 0 && row < 3 && col >= 0 && col < 3) {
if (takenSquare[row][col] == false) {
valid = true;
}
}
return valid;
}
}
================================================================
Here's a revised version of my test program that demonstrates instrumenting isValidMove so that it is clear what arguments it was passed, what it is returning, and why it is returning false any time it does so.
public class Test
{
private static boolean[][] takenSquare = new boolean[3][3];
public static void main(String[] args) {
takenSquare[1][1] = true;
test(0,0);
test(0,-1);
test(1,1);
}
private static void test(int row, int col){
System.out.println("Test result: row="+row+", col="+col+", valid="+isValidMove(row, col));
}
public static boolean isValidMove(int row, int col) {
boolean valid = false;
if (row >= 0 && row < 3 && col >= 0 && col < 3) {
if (takenSquare[row][col] == false) {
valid = true;
} else {
System.out.println("isValidMove square already taken for row="+row+", col="+col);
}
} else {
System.out.println("isValidMove out of range argument row="+row+" col="+col);
}
System.out.println("Returning "+valid+" from isValidMove("+row+","+col+")");
return valid;
}
}

Categories