/** * This is used when a copy of the puzzle is needed, such that updates to the returned puzzle will * not affect the original. * * @return An exact copy of this Puzzle. */ public Puzzle clone() { Puzzle clonedPuzzle = new Puzzle(); for (int r = 0; r < 9; r++) { for (int c = 0; c < 9; c++) { Cell thisCell = this.getCell(r, c).clone(); clonedPuzzle.rows.get(r).setCell(c, thisCell); clonedPuzzle.cols.get(c).setCell(r, thisCell); clonedPuzzle.boxes.get(this.boxNumber(r, c)).setCell(this.boxPosition(r, c), thisCell); } } clonedPuzzle.cardinality = this.cardinality; return clonedPuzzle; }
/** * Returns <tt>true</tt> if and only if this state is considered equal to the given object. In * particular, equality is defined to hold if the given object is also a <tt>State</tt> object, if * it is associated with the same <tt>Puzzle</tt> object, and if the cars in both states are in * the identical positions. This method overrides <tt>Object.equals</tt>. */ public boolean equals(Object o) { State s; try { s = (State) o; } catch (ClassCastException e) { return false; } if (hashcode != s.hashcode || !puzzle.equals(s.puzzle)) return false; for (int i = 0; i < varPos.length; i++) if (varPos[i] != s.varPos[i]) return false; return true; }
/** * Computes a grid representation of the state. In particular, an nxn two-dimensional integer * array is computed and returned, where n is the size of the puzzle grid. The <tt>(i,j)</tt> * element of this grid is equal to -1 if square <tt>(i,j)</tt> is unoccupied, and otherwise * contains the index of the car occupying this square. Note that the grid is recomputed each time * this method is called. */ public int[][] getGrid() { int gridsize = puzzle.getGridSize(); int grid[][] = new int[gridsize][gridsize]; for (int i = 0; i < gridsize; i++) for (int j = 0; j < gridsize; j++) grid[i][j] = -1; int num_cars = puzzle.getNumCars(); for (int v = 0; v < num_cars; v++) { boolean orient = puzzle.getCarOrient(v); int size = puzzle.getCarSize(v); int fp = puzzle.getFixedPosition(v); if (v == 0 && varPos[v] + size > gridsize) size--; if (orient) { for (int d = 0; d < size; d++) grid[fp][varPos[v] + d] = v; } else { for (int d = 0; d < size; d++) grid[varPos[v] + d][fp] = v; } } return grid; }
/** * Computes all of the states immediately reachable from this state and returns them as an array * of states. You probably will not need to use this method directly, since ordinarily you will be * expanding <tt>Node</tt>s, not <tt>State</tt>s. */ public State[] expand() { int gridsize = puzzle.getGridSize(); int grid[][] = getGrid(); int num_cars = puzzle.getNumCars(); ArrayList<State> new_states = new ArrayList<State>(); for (int v = 0; v < num_cars; v++) { int p = varPos[v]; int fp = puzzle.getFixedPosition(v); boolean orient = puzzle.getCarOrient(v); for (int np = p - 1; np >= 0 && (orient ? grid[fp][np] : grid[np][fp]) < 0; np--) { int[] newVarPos = (int[]) varPos.clone(); newVarPos[v] = np; new_states.add(new State(puzzle, newVarPos)); } int carsize = puzzle.getCarSize(v); for (int np = p + carsize; (np < gridsize && (orient ? grid[fp][np] : grid[np][fp]) < 0) || (v == 0 && np == gridsize); np++) { int[] newVarPos = (int[]) varPos.clone(); newVarPos[v] = np - carsize + 1; new_states.add(new State(puzzle, newVarPos)); } } puzzle.incrementSearchCount(new_states.size()); return (State[]) new_states.toArray(new State[0]); }
public Generator(int width, int height, double countrySize, String pathSolver) { this.width = width; this.height = height; this.countrySize = countrySize; int countryID = 1; puzzle = new Puzzle(width, height, pathSolver); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { if (puzzle.getCountry(x, y) == -1) { settingBoarders(new Pair(x, y), countryID); countryID++; } } } shuffled = new Shuffler(puzzle, width, height); puzzle.print(); Puzzle copy = puzzle.clonePuzzle(); copy.generateSMTPiping(); }
/** Prints to standard output a primitive text representation of the state. */ public void print() { int grid[][] = getGrid(); int gridsize = puzzle.getGridSize(); System.out.print("+-"); for (int x = 0; x < gridsize; x++) { System.out.print("--"); } System.out.println("+"); for (int y = 0; y < gridsize; y++) { System.out.print("| "); for (int x = 0; x < gridsize; x++) { int v = grid[x][y]; if (v < 0) { System.out.print(". "); } else { int size = puzzle.getCarSize(v); if (puzzle.getCarOrient(v)) { System.out.print((y == varPos[v] ? "^ " : ((y == varPos[v] + size - 1) ? "v " : "| "))); } else { System.out.print(x == varPos[v] ? "< " : ((x == varPos[v] + size - 1) ? "> " : "- ")); } } } System.out.println( (puzzle.getCarOrient(0) || y != puzzle.getFixedPosition(0)) ? "|" : (isGoal() ? ">" : " ")); } System.out.print("+-"); for (int x = 0; x < gridsize; x++) { System.out.print( (!puzzle.getCarOrient(0) || x != puzzle.getFixedPosition(0)) ? "--" : (isGoal() ? "v-" : " -")); } System.out.println("+"); }
/** Returns true if and only if this state is a goal state. */ public boolean isGoal() { return (varPos[0] == puzzle.getGridSize() - 1); }
private void computeHashCode() { hashcode = puzzle.hashCode(); for (int i = 0; i < varPos.length; i++) hashcode = 31 * hashcode + varPos[i]; }
public void settingBoarders(Pair pair, int countryID) { OwnList activeFields = new OwnList(); OwnList aboutToAdd = new OwnList(); OwnList countryPairs = new OwnList(); double probability = this.countrySize; Random rand = new Random(); activeFields.add(pair); countryPairs.add(pair); while (!activeFields.isEmpty()) { ListIterator<Pair> activeFieldIterator = activeFields.listIterator(); Pair nextPair; while (activeFieldIterator.hasNext()) { nextPair = activeFieldIterator.next(); activeFieldIterator.remove(); // checking up, down, left, right for possible neighbours // up int x = nextPair.getElement0(); int y = nextPair.getElement1() - 1; if (x >= 0 && y >= 0 && x < this.width && y < this.height && puzzle.getCountry(x, y) < 0) { if (rand.nextDouble() <= probability) { aboutToAdd.add(new Pair(x, y)); if (!countryPairs.contains(new Pair(x, y))) { countryPairs.add(new Pair(x, y)); } } } // down x = nextPair.getElement0(); y = nextPair.getElement1() + 1; if (x >= 0 && y >= 0 && x < this.width && y < this.height && puzzle.getCountry(x, y) < 0) { if (rand.nextDouble() <= probability) { aboutToAdd.add(new Pair(x, y)); if (!countryPairs.contains(new Pair(x, y))) { countryPairs.add(new Pair(x, y)); } } } // left x = nextPair.getElement0() - 1; y = nextPair.getElement1(); if (x >= 0 && y >= 0 && x < this.width && y < this.height && puzzle.getCountry(x, y) < 0) { if (rand.nextDouble() <= probability) { aboutToAdd.add(new Pair(x, y)); if (!countryPairs.contains(new Pair(x, y))) { countryPairs.add(new Pair(x, y)); } } } // right x = nextPair.getElement0() + 1; y = nextPair.getElement1(); if (x >= 0 && y >= 0 && x < this.width && y < this.height && puzzle.getCountry(x, y) < 0) { if (rand.nextDouble() <= probability) { aboutToAdd.add(new Pair(x, y)); if (!countryPairs.contains(new Pair(x, y))) { countryPairs.add(new Pair(x, y)); } } } activeFields.remove(nextPair); } // reducing the probability of adding a field for the next iteration probability = probability * probability; ListIterator<Pair> addIterator = aboutToAdd.listIterator(); while (addIterator.hasNext()) { activeFields.add(addIterator.next()); addIterator.remove(); } aboutToAdd.clear(); } // Adding the new country with its ID to the Puzzle Pair[] countryPairsArray = countryPairs.toArray(); puzzle.setCountry(countryPairsArray, countryID); // Randomly pick a Field in the country to define the circle there. The CircleID equals the // CountryID. Value is not set yet. puzzle.setCircle(countryPairsArray[rand.nextInt(countryPairsArray.length)], -1, countryID); }