/** * Description of calculate(Puzzle puzzle). This method finds conflicting numbers which are they * own row or column but reversed order. Every conflict adds +2 to counter. Why? Every conflict * needs two extra movements to solution. Manhattan Distance value is added to Linear Conflict * value at before it is returned. * * @return amount of conflicts * 2 + Manhattan Distance */ @Override public int calculate(Puzzle puzzle) { this.puzzle = puzzle; rows = puzzle.getNumberOfRows(); columns = puzzle.getNumberOfColumns(); int lc = 0; for (int row = 0; row < rows; row++) { lc += calHorizontal(row); } for (int col = 0; col < columns; col++) { lc += calVertical(col); } return lc + md.calculate(puzzle); }
/** * Description of calHorizontal(int row). This method returns linear conflicts in certain column. * * @param row row which conflicts are checked * @return amount of conflicts * 2 */ private int calHorizontal(int row) { int lc = 0; int max = -1; for (int col = 0; col < columns; col++) { int num = puzzle.getNumberInCell(row, col); if (num != puzzle.getEmpty() && num / rows == row) { if (num > max) { max = num; } else { lc += 2; } } } return lc; }
/** * Description of calVertical(int col). This method returns linear conflicts in certain row. * * @param col column which conflict are checked * @return amount of conflicts * 2 */ private int calVertical(int col) { int lc = 0; int max = -1; for (int row = 0; row < rows; row++) { int num = puzzle.getNumberInCell(row, col); if (num != puzzle.getEmpty() && num % columns == col) { if (num > max) { max = num; } else { lc += 2; } } } return lc; }
/** * Description of update(int h, int dRow, int dCol). This method calculates change in Manhattan * distance and Linear Conflict. * * <p>THIS METHOD IS TOO LONG IN CLEAN CODE SENSE. FOR EFFICIENCY REASONS I HAVE NOT SPLIT IT. * SORRY!!! * * @param dRow change in row * @param dCol change in col * @return change in estimation value compared previous situation */ @Override public int update(int h, int dRow, int dCol) { int now = 0; int old = 0; if (dCol == 0) { int numOwnRow = puzzle.lastMove / 4; if (puzzle.getEmptyRow() == numOwnRow) { now = calHorizontal(numOwnRow); puzzle.setCell(numOwnRow, puzzle.getEmptyCol(), puzzle.getLastMove()); old = calHorizontal(numOwnRow); puzzle.setCell(numOwnRow, puzzle.getEmptyCol(), puzzle.getEmpty()); } else { if (puzzle.getEmptyRow() - dRow == numOwnRow) { now = calHorizontal(numOwnRow); puzzle.setCell(numOwnRow, puzzle.getEmptyCol(), puzzle.getEmpty()); old = calHorizontal(numOwnRow); puzzle.setCell(numOwnRow, puzzle.getEmptyCol(), puzzle.getLastMove()); } } } else { int numOwnCol = puzzle.lastMove % 4; if (puzzle.getEmptyCol() == numOwnCol) { now = calVertical(numOwnCol); puzzle.setCell(puzzle.getEmptyRow(), numOwnCol, puzzle.getLastMove()); old = calVertical(numOwnCol); puzzle.setCell(puzzle.getEmptyRow(), numOwnCol, puzzle.getEmpty()); } else { if (puzzle.getEmptyCol() - dCol == numOwnCol) { now = calVertical(numOwnCol); puzzle.setCell(puzzle.getEmptyRow(), numOwnCol, puzzle.getEmpty()); old = calVertical(numOwnCol); puzzle.setCell(puzzle.getEmptyRow(), numOwnCol, puzzle.getLastMove()); } } } return h + md.update(0, dRow, dCol) + now - old; }