I am writing a recursive program for my intro java class, which is supposed to find a solution to the N-Queens problem (how many times can you fit N amount of queens on an NxN size chess board, without any of them attacking one another (can't be in same diagonal line, same row or same column)). In this particular case, we are solving for 8 queens on an 8x8 board, but in theory it should work for any size.

Anyway, I am getting the following run-time error (there are no errors when it compiles):

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 8
at queenBoard.safeDiag(queenBoard.java:102)
at queenBoard.check(queenBoard.java:50)
at queenBoard.check(queenBoard.java:53)
at queenBoard.check(queenBoard.java:53)
at queenBoard.check(queenBoard.java:53)
at queenBoard.check(queenBoard.java:53)
at queenBoard.check(queenBoard.java:53)
at QueensProblem.main(QueensProblem.java:18)
Here is the code, first for the driver application, and then the actual class itself. I assume that there is really only one line of code thats the problem (102 of queenBoard.java), and that the rest are just the same thing due to the recursion. The code at that line is:

Code:
if (chessBoard[r-i][c-i] || chessBoard[r+i][c-i])

Code:
//************************************************************************
//  QueensProblem.java								Author: Gabriel 
//																	  
//
//  Basic template so you don't have to rewrite all this crap
//*************************************************************************

public class QueensProblem
{
	//---------------------------------------------------
	// Creates a new 8x8 chess board, and attempts to solve
	// the Non-attacking Queens problem, printing out the
	// number of solutions
	//---------------------------------------------------
	public static void main (String[] args)
	{
		queenBoard board = new queenBoard();
		board.check(0);
	}
}
Code:
//************************************************************************
//  queenBoard.java									Author: Gabriel
//																	  
//
// Creates a new n x n chess board, and attempts to solve
// the Non-attacking Queens problem, printing out the first
// solution it finds.
//*************************************************************************

public class queenBoard
{
	private int n=8;
	private int limit;
	
	private String isQueen = "|Q|";
	private String isntQueen = "|-|";
	
	private boolean[] safeRow = new boolean[n];
	private boolean[][] chessBoard = new boolean[n][n];
	
	//---------------------------------------------------
	// Constructor sets up board, sets safeRow and chessBoard
	// all false
	//---------------------------------------------------
	public queenBoard()
	{		
		// Set safeRow all to true initially
		for (int r=0; r < n; r++)
			safeRow[r] = true;
			
		// Sets up an n x n grid, all values initially set to false
		for (int r=0; r < n; r++)
			for (int c=0; c < n; c++)
				chessBoard[r][c] = false;
	}
	
	//---------------------------------------------------------------------------------
	// Heart of recursive algorithm.  check(int startCol) is a boolean method which takes an int,
	// telling it which column to start at.  Then, if the row is safe (safeRow[r] = true)
	// and the diagonals are safe (boolean safeDiag(row, column) returns true), sets a
	// queen at that location.
	//----------------------------------------------------------------------------------
	public void check(int startCol)
	{
		// If we are still within the bounds of our n x n grid
		if (startCol < n && startCol + 1 != n)
		{
			for (int r = 0; r < n; r++)
			{
				if (safeRow[r] && safeDiag(r, startCol))
				{
					goodPosition(r, startCol);
					check(startCol + 1);
					//this.removePosition(r, startCol);
				}
			}
		}
		// We've solved our puzzle, because we have n queens that do not attack eachother
		// thus, we print our table.
		else
		{
			for (int r = 0; r < n; r++)
			{
				for (int c = 0; c < n; c++)
				{
					if (chessBoard[r][c])
						System.out.print(isQueen);
					else
						System.out.print(isntQueen);
				}
				System.out.println();
			}
		}	 
	}
	
	public void goodPosition(int r, int c)
	{
		chessBoard[r][c] = true;
		safeRow[r] = false;
	}
	
	public void badPosition(int r, int c)
	{
		chessBoard[r][c] = false;
		safeRow[r] = true;
	}
	
	public boolean safeDiag(int r, int c)
	{
		// For now, we assume it is safe diagonally.  For loop below will determine if we
		// should set it otherwise.
		boolean returnStatement = true;
		
		// For testing, we only want to test inside the grid, so we use either r or c, whichever is smaller.
		if (r <= c)
			limit = r;
		else
			limit = c;
		
		// [r-i][c-i] is up and too the left.  [r+i][c-i] is down and too the right
		for (int i = 0; i <= limit; i++)
			if (chessBoard[r-i][c-i] || chessBoard[r+i][c-i])
				returnStatement = false;
		
		return returnStatement;
	}
}