5

I am developing a heuristic to place 8 queens on 8x8 chessboard. each square has its own elimination number (to indicate how many squares of an empty chessboard are “eliminated” if a queen is placed in that square.) and the each queen should be placed in the square which has the lowest elimination number.

my problem is that I don't know what to do to keep decreasing specific elimination numbers of their appropriate squares, so I'll be thankful if you helped me with that. another problem, I feel that my code is very complicated, so any notes to make it more simple?

here's my code

public class Queen {
private final int SIZE = 8;
private int board[][] = new int[SIZE][SIZE]; // 8x8 board
private int hor[] = new int[SIZE]; // horizontal moves
private int ver[] = new int[SIZE]; // vertical moves
private int lowestValue = 22;
private int[][] queens = new int[SIZE][2]; // 8 queens 

public Queen () {
    // initialize each square with its own elimination number
    for (int row = 0; row < board.length; row++) {
        for (int col = 0; col < board[row].length; col++) {
            if (row == 0 || row == 7 || ((row >= 1 && row <= 6) && (col == 0 || col == 7))) {
                board[row][col] = 22;
            } 
            else if ((row == 1 || row == 6) && (col >= 1 && col <= 6) || (row > 1 && row < 6) && (col == 1 || col == 6)) {
                board[row][col] = 24;
            }
            else if ((row == 2 || row == 5) && (col >= 2 && col <= 5)|| (row > 2 && row < 5) && (col == 2 || col == 5)){
                board[row][col] = 26;
            }
            else if ((row == 3 || row == 4) && (col >= 3 && col <= 4)){
                board[row][col] = 28;
            }

        }
    }// end initializing

    // initialize moves
    //right
    hor[0] = 1;
    ver[0] = 0;
    //left
    hor[1] = -1;
    ver[1] = 0;
    //up
    hor[2] = 0;
    ver[2] = -1;
    //down
    hor[3] = 0;
    ver[3] = 1;
    //up right
    hor[4] = 1;
    ver[4] = -1;
    hor[7] = -1;
    ver[7] = 1;
    //up left
    hor[5] = -1;
    ver[5] = -1;
    //down right
    hor[6] = 1;
    ver[6] = 1;
    // down left

    for (int queen = 0; queen < queens.length; queen++) {
        placeQueens(queen);
    }
    displayBoard();
}// end constructor

// eliminate squares according to the place of the queen
private void eliminate (int queen_row, int queen_col) {

    // eliminate diagonal
    int rowCopy = queen_row;// helper row
    int colCopy = queen_col;// helper column
    try {
        // eliminate up right
        for (int move = 0; move < 8; move++) {
            rowCopy += ver[4];
            colCopy += hor[4];
            if (board[rowCopy][colCopy] > 0) {
                board[rowCopy][colCopy] = 0;
            }
        }
    } 
    catch (ArrayIndexOutOfBoundsException e) {      
    }

    try {
        rowCopy = queen_row;
        colCopy = queen_col;
        // eliminate up left
        for (int move = 0; move < 8; move++) {
            rowCopy += ver[5];
            colCopy += hor[5];
            if (board[rowCopy][colCopy] > 0) {
            board[rowCopy][colCopy] = 0;
            }
        }
    } 
    catch (ArrayIndexOutOfBoundsException e) {
    }

    try {
        rowCopy = queen_row;
        colCopy = queen_col;
        // eliminate down right
        for (int move = 0; move < 8; move++) {
            rowCopy += ver[6];
            colCopy += hor[6];
            if (board[rowCopy][colCopy] > 0) {
            board[rowCopy][colCopy] = 0;
            }
        }
    } 
    catch (ArrayIndexOutOfBoundsException e) {
    }
    try {
        rowCopy = queen_row;
        colCopy = queen_col;
        // eliminate down left
        for (int move = 0; move < 8; move++) {
            rowCopy += ver[7];
            colCopy += hor[7];
            if (board[rowCopy][colCopy] > 0) {
            board[rowCopy][colCopy] = 0;
            }
        }
    } 
    catch (ArrayIndexOutOfBoundsException e) {
    }

    // eliminate row
    for (int col = 0; col < 8;col++) {
        if (board[queen_row][col] > 0) {
        board[queen_row][col] = 0;
        }
    }
    // eliminate col
    for (int row = 0; row < 8; row++) {
        if (board[row][queen_col] > 0) {
        board[row][queen_col] = 0;
        }
    }

}// end elimination

// decrease elimination number of each square
public void decreaseElimination () {


}// end decrease elimination

public void countEliminated () {
    int counter = 0;
    for (int row = 0; row < board.length; row++) {
        for (int col = 0; col < board[row].length; col++) {
            if (board[row][col] == 0) {
                counter++;
            }

        }
    }
    System.out.printf("%d squares eliminated\n", counter);

}

public void placeQueens(int queenNum) {
    int targetRow;
    int targetCol;
    // find lowest elimination number
    for (int row = 0; row < board.length; row++) {
        for (int col = 0; col < board[row].length; col++) {
            if (board[row][col] > 0 && board[row][col] < lowestValue) {
                lowestValue = board[row][col];
                targetRow = row;
                targetCol = col;

                queens[queenNum][0] = targetRow;
                queens[queenNum][1] = targetCol;
            }
        }
    }

    System.out.printf("queen %d has been placed in [%d][%d]\n", queenNum + 1, queens[queenNum][0], queens[queenNum][1]);
    eliminate(queens[queenNum][0], queens[queenNum][1]);
    decreaseElimination();
    countEliminated();

}

// display board
public void displayBoard () {

    for (int row = 0; row < board.length; row++) {
        for (int col = 0; col < board[row].length; col++) {
                System.out.printf("|%2d|", board[row][col]); // display elimination number of each square
        }
        System.out.println();
    }

}// end displayBoard

}

my main method is in seperate class.

Mat
  • 202,337
  • 40
  • 393
  • 406
kzidane
  • 753
  • 3
  • 11
  • 29
  • You dont need to develop for your own google it and you will find it. – Bhavik Ambani Nov 04 '12 at 11:07
  • actually I am trying to solve an exercise in Java how to program 9th edition – kzidane Nov 04 '12 at 11:10
  • Meta-question: does the exercise revolve around the heuristic or around he 8 queen problem in general? Because it is not the best way to solve it.. – Vitaliy Nov 04 '12 at 11:19
  • @BhavikAmbani: please read the homework tag wiki. – Mat Nov 04 '12 at 11:26
  • @Mat As Kareem said this is homework – Bhavik Ambani Nov 04 '12 at 11:28
  • @BhavikAmbani: I know. Please read the tag wiki though. Don't add the homework tag. – Mat Nov 04 '12 at 11:32
  • You could just use brute force. I did just that about 25 years ago on a piece of crap IBM mainframe (power of a pocket calculator) and it took not long to find a solution using brute force in the [ReXX scripting language](http://en.wikipedia.org/wiki/Rexx), which again is not built for speed. In java with modern CPUs this should take seconds to smash. – Bohemian Nov 04 '12 at 11:32
  • @Bohemian using the brute force approach is another exercise that I've to solve later. – kzidane Nov 04 '12 at 11:48
  • As a note on general code quality, you should not catch `ArrayIndexOutOfBoundsException`. You should compute the correct indices and discard invalid ones before accessing the array. Not only will catching this exception blindly make it harder to understand the code, it will hide unintentional errors alongside the intentional. And in extreme cases it can severely impact performance (throwing an exception is relatively expensive.) – Steven Schlansker Feb 15 '13 at 05:40

1 Answers1

6

This piece of code is inherently flawed:

for (int queen = 0; queen < queens.length; queen++) {
    placeQueens(queen);
}

You can't decide where to put queen 0 without deciding where to put queen 1 to 8 at the exact same time. You've implemented "First Fit":

First Fit

And First Fit does not result in a feasible solution as you can see in the example above. More info in this manual (including algorithms that do work).

Here's an algorithm that does work (but scales horribly): Backtracking

Community
  • 1
  • 1
Geoffrey De Smet
  • 26,223
  • 11
  • 73
  • 120
  • 1
    I did this with a student of mine a while back. A straight up backtracking solution as well as a parallelized approach using multiple machines and Terracotta. The code is here: http://code.google.com/p/x-converter/source/browse/#svn%2Ftrunk%2Fsrc%2Fmain%2Fjava%2Fxcon%2Fqueens for you to take a peek at. – Adriaan Koster Nov 04 '12 at 14:07