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 { private Location loc; private final int size; private List 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 iterator() { return locations.iterator(); } } private static List 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; } }