Files
BH2023-Minesweeper/references/Minesweeper/MineSweeperSolver/src/minesweeper/solver/BoardStateCache.java
2023-09-28 20:24:18 +08:00

135 lines
3.3 KiB
Java

package minesweeper.solver;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import minesweeper.structure.Location;
public class BoardStateCache {
private final static int[] DX = {0, 1, 1, 1, 0, -1, -1, -1};
private final static int[] DY = {-1, -1, 0, 1, 1, 1, 0, -1};
protected class Cache {
private int width;
private int height;
protected Location[][] locations;
protected AdjacentSquares[][] adjacentLocations1;
protected AdjacentSquares[][] adjacentLocations2;
protected Location getLocation(int x, int y) {
return locations[x][y];
}
}
// iterator for adjacent squares
protected class AdjacentSquares implements Iterable<Location> {
private Location loc;
private final int size;
private List<Location> locations;
AdjacentSquares(Cache cache, Location l, int width, int height, int size) {
this.loc = l;
this.size = size;
if (size == 1) {
locations = new ArrayList<>(8);
for (int i=0; i < DX.length; i++) {
if (loc.x + DX[i] >= 0 && loc.x + DX[i] < width && loc.y + DY[i] >= 0 && loc.y + DY[i] < height) {
locations.add(cache.getLocation(loc.x + DX[i], loc.y + DY[i]));
}
}
} else {
int startX = Math.max(0, loc.x - this.size);
int endX = Math.min(width - 1, loc.x + this.size);
int startY = Math.max(0, loc.y - this.size);
int endY = Math.min(height - 1, loc.y + this.size);
locations = new ArrayList<>((this.size * 2 - 1) * (this.size * 2 - 1));
for (int i=startX; i <= endX; i++) {
for (int j=startY; j <= endY; j++) {
if (i == loc.x && j == loc.y) {
// don't send back the central location
} else {
locations.add(cache.getLocation(i,j));
}
}
}
}
}
@Override
public Iterator<Location> iterator() {
return locations.iterator();
}
}
private static List<Cache> cacheAdjSqu = new ArrayList<>();
private static BoardStateCache me;
public synchronized Cache getAdjacentSquares1(int width, int height) {
for (Cache cache: cacheAdjSqu) {
if (cache.height == height && cache.width == width) {
return cache;
}
}
Cache cache = new Cache();
cache.height = height;
cache.width = width;
cache.locations = new Location[width][height];
// Create a Location for each entry yon the board
for (int x=0; x < width; x++) {
for (int y=0; y < height; y++) {
cache.locations[x][y] = new Location(x,y);
}
}
cache.adjacentLocations1 = new AdjacentSquares[width][height];
cache.adjacentLocations2 = new AdjacentSquares[width][height];
// set up how many adjacent locations there are to each square - they are all unrevealed to start with
for (int x=0; x < width; x++) {
for (int y=0; y < height; y++) {
cache.adjacentLocations1[x][y] = new AdjacentSquares(cache, cache.getLocation(x,y), width, height, 1);
cache.adjacentLocations2[x][y] = new AdjacentSquares(cache, cache.getLocation(x,y), width, height, 2);
}
}
cacheAdjSqu.add(cache);
return cache;
}
public static synchronized BoardStateCache getInstance() {
if (me == null) {
me = new BoardStateCache();
}
return me;
}
}