1

I am receiving a StackOverflow error when ever I run the program instead of finding the Knights Tour. Any idea what is causing this and how I can change my code around to actually find the Knights Tour and get rid of this error. Project is for my CS280 class and is due on Friday please help. Thanks!!

public class KnightsTourDriver {
    public static void main (String[]args) {
        KnightsTour tour1 = new KnightsTour;
        tour1.findTour(1);
        tour1.displayTour();
    }
}  



import java.util.Arrays;
class KnightsTour
{

    static int the_board[][] = new int[8][8];
    int the_tour[][] = new int [8][8];
    int k,moves = 0;
    int x = 0, y = 0; 
    int z, j = 1;
    boolean tour_found, isSafe;

        //fills 2D array with 0's
        public KnightsTour()
        {
            for (int i = 0; i < 8; i++) 
                {
                 for (int r = 0; r < 8; r++) 
                    {
                            the_board[i][r] = 0;
                        }
                }
        }
        /*recursive method, checks how many moves were made if 16 were made tour finished, 
        else if not moves knight checks if the move is valid if not back tracks*/
        public void findTour(int q)
        {

            if(moves == 64)
                {
                    tour_found = true;
                }

            else 
                move(q); 

            if(isSafe == true)
                    {
                        findTour(q++);
                        moves++;
                    }
            else
                if(isSafe == false)
                    {
                        findTour(q*(-1));
                        moves--;
                    }
        }
        //used to keep prevent arrayindexoutofbounds error
        public boolean arrayInBounds(int x, int y)
        { 
        if(x < 8 && y < 8 && x >= 0 && y >= 0)
                {
                    return true;
                }
            else return false;
        }
        /*move method uses switch statement to decide which move the knight should make
        based on a case number, negative case numbers back track knight. if statement checks
        if the current array element is empty and the index is inbounds*/
        public void move(int a)
        {

            switch (a)
            {
               case 1:
                if(arrayInBounds(x+2, y+1) == true){
                   if(the_board[x+2][y+1] != 0){                          
                        the_board[x+2][y+1]=j;
                            j++;
                            break;
                        }
                        else isSafe = false;
                        break;
                    }
                else isSafe = false;
               case 2:
                if (arrayInBounds(x+1, y+2) == true){
                    if(the_board[x+1][y+2] != 0){               
                            the_board[x+1][y+2]=j;
                            j++;
                            break;
                        }
                        else isSafe = false;
                        break;
                }
                else isSafe = false;
               case 3:
                 if(arrayInBounds(x-1, y+2) == true){
                   if(the_board[x-1][y+2] != 0){           
                            the_board[x-1][y+2]=j;
                            j++;
                            break;
                        }
                        else isSafe = false;
                        break;
                 }
                else isSafe = false;
               case 4:
                if (arrayInBounds(x-2, y+1) == true){
                    if(the_board[x-2][y+1] != 0){           
                            the_board[x-2][y+1]=j;
                            j++;
                            break;
                        }
                        else isSafe = false;
                        break;
                }
                else isSafe = false;
               case 5:
                if(arrayInBounds(x-2, y-1) == true){
                    if(the_board[x-2][y-1] != 0){           
                            the_board[x-2][y-1]=j;
                            j++;
                            break;
                        }
                        else isSafe = false;
                        break;
                }
                else isSafe = false;
               case 6:
                if(arrayInBounds(x-1, y-2) == true){
                        if(the_board[x-1][y-2] != 0){                    
                            the_board[x-1][y-2]=j;
                            j++;
                            break;
                        }
                        else isSafe = false;
                        break;
            }
                else isSafe = false;
               case 7:
                 if(arrayInBounds(x+1, y-2) == true){
                    if(the_board[x+1][y-2] != 0){          
                            the_board[x+1][y-2]=j;
                            j++;
                            break;
                        }
                        else isSafe = false;
                        break;
                 }
                 else isSafe = false;
               case 8:
                if(arrayInBounds(x+2, y-1) == true){
                 if(the_board[x+2][y-1] != 0){
                            the_board[x+2][y-1]=j;
                            j++;
                            break;
                        }
                        else isSafe = false;
                        break;
                }
                else isSafe = false;
               case -1:
                      j--;
                      tryNextMove(a);
                      break;
                    case -2:
                        j--;
                        tryNextMove(a);
                        break;
                    case -3:
                      j--;
                      tryNextMove(a);
                      break;
                    case -4:
                      j--;
                      tryNextMove(a);
                      break;
                  case -5:
                     j--;
                      tryNextMove(a);
                      break;
                    case -6:
                      j--;
                      tryNextMove(a);
                      break;
                    case -7:
                      j--;
                      tryNextMove(a);
                      break;
                   case -8:
                      j--;
                      tryNextMove(a);
                      break;
             }
        }
        public void tryNextMove(int m)
        {
            move(m++);
        }
        //for loop to display tour once found//         
        public void displayTour()
        {
            int v = 1;
            for (int i = 0; i < 8; i++) 
                {
                 for (int e = 0; e < 8; e++) 
                    {               
                                if(v % 8 == 0)
                                {
                                    System.out.print(the_board[i][e] + "\t");
                                    System.out.println("\n");
                                } 
                        else    
                            System.out.print(the_board[i][e] + "\t");
                            v++;                
                        }
                }
        }
}
false
  • 10,264
  • 13
  • 101
  • 209

2 Answers2

1

If your algorithm really requires a large depth of recursive calls, you can pass an argument to the JVM on startup to increase the limit for the stack size : -Xss4m

Of course, this will only delay the problem if your algorithm recurses without limit.

Community
  • 1
  • 1
Graham Griffiths
  • 2,196
  • 1
  • 12
  • 15
0

You need some breaks in your case statements in the switch, otherwise it'll fall through.

pecks
  • 318
  • 1
  • 2
  • 9
  • I implemented the break statements and still getting this error – user2612136 Feb 25 '14 at 15:34
  • Exception in thread "main" java.lang.StackOverflowError at KnightsTour.tryNextMove(KnightsTour.java:189) at KnightsTour.move(KnightsTour.java:155) ---jGRASP wedge2: exit code for process is 1. ----jGRASP: operation complete. – user2612136 Feb 25 '14 at 15:35
  • The breaks in cases with if/elses don't look correct to me. And you need to include line numbers so that we can see where line 189 is. – pecks Feb 25 '14 at 15:48
  • KnightsTour tour1 = new KnightsTour; is wrong for a start! – pecks Feb 26 '14 at 09:23
  • Well I'm not going to debug it for you, but I ran it. It looks like it just never terminates. You need to think about the termination conditions, and why they are not being met. – pecks Feb 26 '14 at 09:32