Решающий тур рыцарей, использующий warndorffs heurisiti c для первых 32 ходов, и возвращение грубой силы, используя стек для следующего - PullRequest
0 голосов
/ 20 февраля 2020

Это моя основная функция для запуска тура рыцарей, идея состоит в том, что, пока счетчик равен 32, он выбирает точку, используя heurisiti c, и в то время как его значение больше 32, он случайным образом выбирает точку, и если эта точка работает плохо сделайте объект рыцаря, передайте ему координаты x, y и установите для этой точки на доске значение счетчика

, если он не найдет ход, он выскочит из коня на вершину стека и продолжит попытки до Он найдет решение, но в настоящее время дает мне исключение за пределами границ, и я не уверен, почему.

public static void FindKnightsTour()
    {
        int board[][] = new int[N][N];
        int count = 0;

        for (int x = 0; x < N; x++) //Making my chess board filling it with -1's as the place holder for not having a knight on it
                for (int y = 0; y < N; y++) 
                    board[x][y] = -1; 



        KnightPiece KnightS = new KnightPiece(5,3); //the "starting" position for the knight passed to it by the user

        stackOfKnights.push(KnightS);



        int startX = stackOfKnights.peek().getX();

        int startY = stackOfKnights.peek().getY();

        board[startX][startY] = count;


        //System.out.println(stackOfKnights.peek().getX());

    while( count < 63)
        {   

        if(count < 31) // for the first 32 knights use warndorffs heuristic in order to choose coordinates for the knight piece
        {



            KnightPiece Knight = Heurisitic(board, stackOfKnights.peek());

            stackOfKnights.push(Knight);

            int x = stackOfKnights.peek().getX();

            int y = stackOfKnights.peek().getY();

            count++;

            board[x][y] = count;

            //System.out.println(stackOfKnights.peek().getX());
            //System.out.println(stackOfKnights.peek().getY());

            //System.out.println("hi");
        }





            //System.out.println("hi");

            int rand = getRandomNumber();

            int random_X_move = xMoves[rand];

            //System.out.println(random_X_move);

            int random_Y_move = yMoves[rand];

            int currentXspot = stackOfKnights.peek().getX();

            //System.out.println(currentXspot);

            int currentYspot = stackOfKnights.peek().getY();

            int newXmove = currentXspot + random_X_move;

            int newYmove = currentYspot + random_Y_move;

            //System.out.println(newXmove + "," + newYmove);


            if (validMove(newXmove, newYmove, board))
            {
                //System.out.println("hi");
                //System.out.println(newXmove + "," + newYmove);
                count++;
                KnightPiece Knight = new KnightPiece(newXmove,newYmove);
                stackOfKnights.push(Knight);
                board[newXmove][newYmove] = count;

            }
            else
            {
                //System.out.println("hi");
                count--;
                int removeX = stackOfKnights.peek().getX();
                int removeY = stackOfKnights.peek().getY();

                board[removeX][removeY] = -1;


                stackOfKnights.pop();

            }

        }

        printSolvedBoard(board);

    }

это методы, которые я использую для этого проекта

public static int N = 8;

    static Stack<KnightPiece> stackOfKnights = new Stack<KnightPiece>();

    public static int xMoves[] = {1, 1, 2, 2, -1, -1, -2, -2}; //these two arrays reflect the moves that are possible from the knight by subtracting or adding the value 
    public static int yMoves[] = {2, -2, 1, -1, 2, -2, 1, -1};


    static boolean validMove(int x, int y, int sol[][]) //Need to check if the possible spot im putting a knight on is inside the matrix and is not equal to -1
    { 
            return (x >= 0 && x < N && y >= 0 && 
                    y < N && sol[x][y] == -1); 
        } 

    static void printSolvedBoard(int sol[][]) // to easily print the solved board
    { 
        for (int x = 0; x < N; x++)  
            for (int y = 0; y < N; y++) 
            {
                System.out.print(sol[x][y] + " "); 
            }
            System.out.println(); 
        } 




    static int getDegree(int board[][], int x, int y) 
    { 
        int count = 0; 
        for (int i = 0; i < N; i++) 
            if (validMove((x + xMoves[i]),(y + yMoves[i]), board))
            {
                count++; 
            }
        return count; 
    } 



    public static int getRandomNumber() //random number between 0 and 7
    {
        double min = 0.0;

        double max = 7.0;


        double x = (Math.random()*((max-min)+1))+min;
        return (int) x;
    }
    static KnightPiece Heurisitic(int board[][], KnightPiece knight)

    {

        int min_deg_idx = -1, c, min_deg = (N + 1), nx, ny; 


            int start = ThreadLocalRandom.current().nextInt(1000) % N; 
            for (int count = 0; count < N; ++count) 
            { 
                int i = (start + count) % N; 
                nx = knight.x + xMoves[i]; 
                ny = knight.y + yMoves[i]; 
                if ((validMove(nx, ny, board)) && 
                    (c = getDegree(board, nx, ny)) < min_deg) 
                { 
                    min_deg_idx = i; 
                    min_deg = c; 
                } 
            } 



            // Store coordinates of next point 
            nx = knight.x + xMoves[min_deg_idx]; 
            ny = knight.y + yMoves[min_deg_idx]; 

            // Mark next move 

            board[nx][ny] = board[knight.x][knight.y];

            // Update next point 
            knight.x = nx; 
            knight.y = ny; 

            return knight; 
    }

это мой рыцарь объект

 static class KnightPiece //Knight object, has an x,y cordinate to reflect its spot on the board
{

    int x;
    int y;

    public KnightPiece(int x, int y)
    {
        this.x = x;
        this.y = y;
    }

    int getX()
    {
        return this.x;
    }
    int getY()
    {
        return this.y;
    }


}
...