Search code examples
javaarraysindexoutofboundsexceptionwordsearch

How Should I Deal with ArrayIndexOutOfBound Exceptions?


For a word search program, I input twenty words into an Array List, and then this Array List of words is transformed into a 1 dimensional array. I have a method called createWordSearch(words), where words is the 1 dimensional array.

There are a few other methods that help create the whole word search in this method such as location(wordArr, word, dir, pos), placeWord(wordArr, word), placeMessage(wordArr, message). I am having a ArrayIndexOutOfBound Exception in the location method, specifically at: if ((DIRECTIONS[dir][0] == 1 && (word.length() + c) > cols).

Where for (int dir = 0; dir < DIRECTIONS.length; dir++) { dir = ( (dir) + (randDirection) % DIRECTIONS.length);, int randDirection = rand.nextInt(DIRECTIONS.length); and public static final int[][] DIRECTIONS = {{1,0}, {0,1}, {1,1}, {1,-1}, {-1,0}, {0,-1}, {-1,-1}, {-1,1}};

I am trying to understand why I am having this exception, but I cant pinpoint exactly where, which is why I am having trouble fixing my code. I am assuming the error happens because of that for loop fordirlisted above, but Im not too sure.

// Create a method that places the word letters at a certain location
	
	public static int location (WordArray wordArr, String word, int dir, int pos) {    		
		int r = ( (pos) / (cols)); // Where r = row
		int c = ( (pos) / (cols)); // Where c = column    		
		// Checking the bounds...    	
		if ((DIRECTIONS[dir][0] == 1 && (word.length() + c) > cols)
				|| (DIRECTIONS[dir][0] == -1 && (word.length() - 1) > c)
				|| (DIRECTIONS[dir][1] == 1 && (word.length() + r) > rows)
				|| (DIRECTIONS[dir][1] == -1 && (word.length() - 1) > r)    				
				)     			
			return 0;    			
			int i, cc, rr, overLaps = 0;    			
			// Checking the cells...    			
			for (i = 0, rr = r, cc = c; i < word.length(); i++) {    				
				if (rr < rows && cc < cols && i < word.length()) {    					
					return 0;    					
				}//end of if    				
				cc += DIRECTIONS[dir][0];
				rr += DIRECTIONS[dir][1];    				
			}//end of for loop   			
			// Placing the word...    			
			for (i = 0, rr = r, cc = c; i < word.length(); i++) {    				
				if (rr < rows && cc < cols && i < word.length()) {    					
					overLaps++;    					
				}//end of if    				
				if (i < word.length() - 1) {    					
					cc += DIRECTIONS[dir][0];
					rr += DIRECTIONS[dir][1];    					
				}//end of inner if    				
			}//end of for loop 2    			
			int lettersPlaced = ( (word.length()) - (overLaps));    			
			if (lettersPlaced > 0)     				
				wordArr.solutions.add(String.format("%-10s (%d,%d)(%d,%d)", word, c, r, cc, rr));
			return lettersPlaced;    		
	}//end of location(wordArr,word,dir,pos)


Solution

  • My guess would be that its cause you do modulo operation on only a part of assigned value and not whole:

    for (int dir = 0; dir < DIRECTIONS.length; dir++) 
    { 
        dir = ( (dir) + (randDirection) % DIRECTIONS.length);
    }
    

    Should probably be:

    for (int dir = 0; dir < DIRECTIONS.length; dir++) 
    { 
        dir = ( (dir) + (randDirection) ) % DIRECTIONS.length;
    }
    

    A few key notes, the formatting in your question isn't great - the formatting should split the question into key parts, providing us with easy way of understanding exactly what you're asking us and should format all code parts to distinguish them from the rest.

    You should probably read up about refactoring too - in this day of compilers formatting our code and showing us exactly where each block begins and ends - there is really no need to comment on each bracket end.

    Give your variables meaningful names having r, rr, c, cc is quite confusing for someone who doesn't know whats your code supposed to do.

    You can also extract parts of your code into separate methods to give it more clarity.

    On end point

    for (i = 0, rr = r, cc = c; i < word.length(); i++) {                   
        if (rr < rows && cc < cols && i < word.length()) { 
    

    This check is redundant and could change to

    for (i = 0, rr = r, cc = c; i < word.length(); i++) {                   
        if (rr < rows && cc < cols) {