protected Point getRegionDimension(BoardState origState, int cellregion) { Vector<CellLocation> cells; CellLocation tempcell; int rheight = 0; int rwidth = 0; int xmin, xmax, ymin, ymax; xmin = ymin = 1000000; xmax = ymax = -1000000; Region region = ((Region[]) origState.getExtraData().get(0))[cellregion]; cells = region.getCells(); for (int c = 0; c < cells.size(); ++c) { if (origState.getCellContents(cells.get(c).getX(), cells.get(c).getY()) == Heyawake.CELL_WHITE) { continue; } if (cells.get(c).getX() < xmin) xmin = cells.get(c).getX(); if (cells.get(c).getY() < ymin) ymin = cells.get(c).getY(); if (cells.get(c).getX() > xmax) xmax = cells.get(c).getX(); if (cells.get(c).getY() > ymax) ymax = cells.get(c).getY(); } rwidth = xmax - xmin; rheight = ymax - ymin; return new Point(rwidth, rheight); }
/** * Checks if the contradiction was applied correctly to this board state * * @param state The board state * @return null if the contradiction was applied correctly, the error String otherwise */ public String checkContradictionRaw(BoardState state) { int height = state.getHeight(); int width = state.getWidth(); int[][] cells = new int[height][width]; for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { cells[y][x] = state.getCellContents(x, y); } } List<Set<Point>> regions = ConnectedRegions.getConnectedRegions(Nurikabe.CELL_BLACK, cells, width, height); for (Set<Point> region : regions) { if (!ConnectedRegions.regionContains(Nurikabe.CELL_WHITE, cells, region)) continue; boolean haveNumber = false; for (Point p : region) { if (state.getCellContents(p.x, p.y) > 10) { haveNumber = true; break; } } if (!haveNumber) return null; } return "No white regions (contains >1 white cell) without a number."; }
protected String checkRuleRaw(BoardState destBoardState) { String error = null; boolean changed = false; int regionNum; BoardState origBoardState = destBoardState.getSingleParentState(); ArrayList<Object> extraData = origBoardState.getExtraData(); Region curRegion; Point tempPoint; // Check for only one branch if (destBoardState.getParents().size() != 1) { error = "This rule only involves having a single branch!"; } else { for (int y = 0; y < origBoardState.getHeight() && error == null; ++y) { for (int x = 0; x < origBoardState.getWidth(); ++x) { int origState = origBoardState.getCellContents(x, y); int newState = destBoardState.getCellContents(x, y); if (origState != newState) { changed = true; if (newState != 2 || origState != 0) { error = "This rule only involves adding black cells!"; break; } if (!checkRegionHasClue( origBoardState, ((int[][]) origBoardState.getExtraData().get(2))[y][x])) { error = "Rule cannot be applied to regions without a designated number."; break; } regionNum = ((int[][]) (extraData.get(2)))[y][x]; curRegion = ((Region[]) extraData.get(0))[regionNum]; if (curRegion.getValue() != 5) { error = "Rule cannot be applied to regions without a value of 5."; } tempPoint = getRegionDimension(origBoardState, regionNum); if (tempPoint.x != 2 || tempPoint.y != 2) { error = "Rule can only be applied to regions with dimension 3x3."; break; } } } } if (error == null && !changed) { error = "You must add a black cell to use this rule!"; } } return error; }
protected Point getRegionLocation(BoardState origState, int cellregion) { Vector<CellLocation> cells; CellLocation tempcell; int xmin, ymin; xmin = ymin = 1000000; Region region = ((Region[]) origState.getExtraData().get(0))[cellregion]; cells = region.getCells(); for (int c = 0; c < cells.size(); ++c) { if (origState.getCellContents(cells.get(c).getX(), cells.get(c).getY()) == Heyawake.CELL_WHITE) { continue; } if (cells.get(c).getX() < xmin) xmin = cells.get(c).getX(); if (cells.get(c).getY() < ymin) ymin = cells.get(c).getY(); } return new Point(xmin, ymin); }
public Dimension getProperSize() { Dimension rv = new Dimension(); BoardState state = curState; if (state != null) { PuzzleModule pz = pm; if (pz != null) { Dimension d = pz.getImageSize(); int w = state.getWidth(); int h = state.getHeight(); rv.width = d.width * (w + 2); rv.height = d.height * (h + 2); } } return rv; }
/** * Checks if the contradiction was applied correctly to this board state * * @param state The board state * @return null if the contradiction was applied correctly, the error String otherwise * <p>protected String checkRuleRaw(BoardState destBoardState) { String error = null; boolean * changed = false; BoardState origBoardState = destBoardState.getSingleParentState(); int * width = destBoardState.getWidth(); int height = destBoardState.getHeight(); boolean * foundvalidblock; boolean[][] litup = new * boolean[origBoardState.getHeight()][origBoardState.getWidth()]; * LightUp.determineLight(origBoardState, litup); * <p>// Check for only one branch if (destBoardState.getTransitionsTo().size() != 1) { error * = "This rule only involves having a single branch!"; } else { for (int y = 0; y < * origBoardState.getHeight() && error == null; ++y) { for (int x = 0; x < * origBoardState.getWidth(); ++x) { int origState = origBoardState.getCellContents(x,y); int * newState = destBoardState.getCellContents(x,y); * <p>if (origState != newState) { changed = true; * <p>if (newState != LightUp.CELL_LIGHT || origState != LightUp.CELL_UNKNOWN) { error = "This * rule only involves adding light bulbs!"; break; } foundvalidblock = false; if(x > 0) * if(destBoardState.getCellContents(x-1,y)>= 10 && destBoardState.getCellContents(x-1,y)< 15) * foundvalidblock = foundvalidblock | * checkBlockCompleted(destBoardState,x-1,y,width,height,litup); if(x < width - 1) * if(destBoardState.getCellContents(x+1,y)>= 10 && destBoardState.getCellContents(x+1,y)< 15) * foundvalidblock = foundvalidblock | * checkBlockCompleted(destBoardState,x+1,y,width,height,litup); if(y > 0) * if(destBoardState.getCellContents(x,y-1)>= 10 && destBoardState.getCellContents(x,y-1)< 15) * foundvalidblock = foundvalidblock | * checkBlockCompleted(destBoardState,x,y-1,width,height,litup); if(y < height - 1) * if(destBoardState.getCellContents(x,y+1)>= 10 && destBoardState.getCellContents(x,y+1)< 15) * foundvalidblock = foundvalidblock | * checkBlockCompleted(destBoardState,x,y+1,width,height,litup); * <p>if(!foundvalidblock) { error = "A bulb cell must be placed to complete a block's * number."; break; } * <p>} } } * <p>if (error == null && !changed) { error = "You must add a bulb to use this rule!"; } } * <p>return error; } * <p>protected boolean doDefaultApplicationRaw(BoardState destBoardState, PuzzleModule pm) { * BoardState origBoardState = destBoardState.getSingleParentState(); boolean changed = false; * int width = destBoardState.getWidth(); int height = destBoardState.getHeight(); int * cellvalue = 0; boolean[][] litup = new * boolean[origBoardState.getHeight()][origBoardState.getWidth()]; * LightUp.determineLight(origBoardState, litup); * <p>if (origBoardState != null && destBoardState.getTransitionsTo().size() == 1) { for (int * y = 0; y < origBoardState.getHeight(); ++y) { for (int x = 0; x < * origBoardState.getWidth(); ++x) { cellvalue = destBoardState.getCellContents(x,y); * if(cellvalue >= 10 && cellvalue < 15) { * if(checkBlockCompletable(destBoardState,x,y,width,height,litup)) { * completeBlock(destBoardState,x,y,width,height, litup); } } } } * <p>String error = checkRuleRaw(destBoardState); * <p>if (error == null) { changed = true; // valid change } } * <p>if(!changed) { destBoardState = origBoardState.copy(); } * <p>LightUp.fillLight(destBoardState); * <p>return changed; } */ protected RuleApplication canApplyAt(BoardState state, Point at) { boolean[][] litup = new boolean[state.getHeight()][state.getWidth()]; LightUp.determineLight(state, litup); if (state.getCellContents(at.x, at.y) != PuzzleModule.CELL_UNKNOWN || litup[at.y][at.x]) return new RuleApplication(at); Vector<Point> numbers = LightUp.findAdjacentNumbers(state, at); boolean found = false; for (Point p : numbers) { if (checkBlockCompletable(state, p.x, p.y, state.getWidth(), state.getHeight(), litup)) { RuleApplication ret = new RuleApplication(at); ret.parentApplication = p; ret.newValue = LightUp.CELL_LIGHT; ret.isValid = true; return ret; } } return new RuleApplication(at); // TODO: Add parent semantics }
private void completeBlock( BoardState destBoardState, int x, int y, int width, int height, boolean[][] litup) { if (x > 0) { if (destBoardState.getCellContents(x - 1, y) == LightUp.CELL_UNKNOWN && !litup[y][x - 1]) destBoardState.setCellContents(x - 1, y, LightUp.CELL_LIGHT); } if (x < width - 1) { if (destBoardState.getCellContents(x + 1, y) == LightUp.CELL_UNKNOWN && !litup[y][x + 1]) destBoardState.setCellContents(x + 1, y, LightUp.CELL_LIGHT); } if (y > 0) { if (destBoardState.getCellContents(x, y - 1) == LightUp.CELL_UNKNOWN && !litup[y - 1][x]) destBoardState.setCellContents(x, y - 1, LightUp.CELL_LIGHT); } if (y < height - 1) { if (destBoardState.getCellContents(x, y + 1) == LightUp.CELL_UNKNOWN && !litup[y + 1][x]) destBoardState.setCellContents(x, y + 1, LightUp.CELL_LIGHT); } }
private boolean checkBlockCompletable( BoardState destBoardState, int x, int y, int width, int height, boolean[][] litup) { int bulbs = 0; int blanks = 0; if (x > 0) { if (destBoardState.getCellContents(x - 1, y) == LightUp.CELL_LIGHT) ++bulbs; if (destBoardState.getCellContents(x - 1, y) == LightUp.CELL_EMPTY || (litup[y][x - 1] && destBoardState.getCellContents(x - 1, y) == LightUp.CELL_UNKNOWN) || destBoardState.getCellContents(x - 1, y) >= 10) ++blanks; } else ++blanks; if (x < width - 1) { if (destBoardState.getCellContents(x + 1, y) == LightUp.CELL_LIGHT) ++bulbs; if (destBoardState.getCellContents(x + 1, y) == LightUp.CELL_EMPTY || (litup[y][x + 1] && destBoardState.getCellContents(x + 1, y) == LightUp.CELL_UNKNOWN) || destBoardState.getCellContents(x + 1, y) >= 10) ++blanks; } else ++blanks; if (y > 0) { if (destBoardState.getCellContents(x, y - 1) == LightUp.CELL_LIGHT) ++bulbs; if (destBoardState.getCellContents(x, y - 1) == LightUp.CELL_EMPTY || (litup[y - 1][x] && destBoardState.getCellContents(x, y - 1) == LightUp.CELL_UNKNOWN) || destBoardState.getCellContents(x, y - 1) >= 10) ++blanks; } else ++blanks; if (y < height - 1) { if (destBoardState.getCellContents(x, y + 1) == LightUp.CELL_LIGHT) ++bulbs; if (destBoardState.getCellContents(x, y + 1) == LightUp.CELL_EMPTY || (litup[y + 1][x] && destBoardState.getCellContents(x, y + 1) == LightUp.CELL_UNKNOWN) || destBoardState.getCellContents(x, y + 1) >= 10) ++blanks; } else ++blanks; return (4 - blanks - bulbs == destBoardState.getCellContents(x, y) - 10 - bulbs); }
protected boolean checkRegionHasClue(BoardState state, int cellregion) { Region region = ((Region[]) state.getExtraData().get(0))[cellregion]; if (region.getValue() < 0) return false; return true; }
protected boolean doDefaultApplicationRaw(BoardState destBoardState) { BoardState origBoardState = destBoardState.getSingleParentState(); boolean changed = false; Point temprSize; Point temprLocation; ArrayList<Object> extraData = origBoardState.getExtraData(); Region curRegion; if (origBoardState != null && destBoardState.getParents().size() == 1) { int regioncount = ((Integer) origBoardState.getExtraData().get(1)).intValue(); for (int r = 0; r < regioncount; r++) { curRegion = ((Region[]) extraData.get(0))[r]; if (curRegion.getValue() == 5) { Point size = getRegionDimension(destBoardState, r); Point location = getRegionLocation(destBoardState, r); if (size.x == 2 && size.y == 2) { if (origBoardState.getCellContents(location.x, location.y) == Heyawake.CELL_UNKNOWN) { changed = true; destBoardState.setCellContents(location.x, location.y, Heyawake.CELL_BLACK); destBoardState.setCellContents(location.x + 2, location.y, Heyawake.CELL_BLACK); destBoardState.setCellContents(location.x + 1, location.y + 1, Heyawake.CELL_BLACK); destBoardState.setCellContents(location.x, location.y + 2, Heyawake.CELL_BLACK); destBoardState.setCellContents(location.x + 2, location.y + 2, Heyawake.CELL_BLACK); } } } } } String error = checkRuleRaw(destBoardState); if (error != null) { System.out.println(error + " " + changed); changed = false; // valid change } if (!changed) { destBoardState = origBoardState.copy(); } return changed; }
protected void paintComponent(Graphics g) { super.paintComponent(g); BoardState state = curState; if (state != null) { PuzzleModule pz = pm; if (pz != null) { Dimension d = pz.getImageSize(); int imW = d.width; int imH = d.height; int w = state.getWidth(); int h = state.getHeight(); for (int y = 0; y < h; ++y) { for (int x = 0; x < w; ++x) { String imagePath = pz.getImageLocation(x, y, state); Image i = new ImageIcon(imagePath).getImage(); g.drawImage(i, imW + x * imW, imH + y * imH, null); } } // do headers setFont(largeFont); for (int x = 0; x < w; ++x) { int val = state.getLabel(BoardState.LABEL_TOP, x); String imagePath = pz.getImageLocation(val); Image i = new ImageIcon(imagePath).getImage(); g.drawImage(i, imW + x * imW, 0, null); val = state.getLabel(BoardState.LABEL_BOTTOM, x); imagePath = pz.getImageLocation(val); i = new ImageIcon(imagePath).getImage(); g.drawImage(i, imW + x * imW, imH * (h + 1), null); } for (int y = 0; y < h; ++y) { int val = state.getLabel(BoardState.LABEL_LEFT, y); String imagePath = pz.getImageLocation(val); Image i = new ImageIcon(imagePath).getImage(); g.drawImage(i, 0, imH * (y + 1), null); val = state.getLabel(BoardState.LABEL_RIGHT, y); imagePath = pz.getImageLocation(val); i = new ImageIcon(imagePath).getImage(); g.drawImage(i, imW * (w + 1), imH * (y + 1), null); } // do grid pz.drawGrid(g, new Rectangle(imW, imH, imW * w, imH * h), w, h); pz.drawExtraData( g, state.getExtraData(), state.extraDataDelta, new Rectangle(imW, imH, imW * w, imH * h), w, h); } } }
public void mousePressed(MouseEvent e) { BoardState state = curState; if (state != null) { PuzzleModule pz = pm; if (pz != null) { Dimension d = pz.getImageSize(); int imW = d.width; int imH = d.height; int w = state.getWidth(); int h = state.getHeight(); Point p = e.getPoint(); p.x /= imW; p.y /= imH; // System.out.println("x = " + p.x + ", y = " + p.y); if ((p.x > 0 && p.y > 0) && (p.x <= w && p.y <= h)) { --p.x; --p.y; if (p.x < w && p.y < h) { // p.x and p.y hold the grid point now! if (e.getButton() == MouseEvent.BUTTON1) { // left click ((Fillapix) pz).directModify(p.x, p.y, state); } else { // right click BoardImage[] ims = pz.getAllCenterImages(); int index = ImageChooserDialog.chooseImage(ims); if (index != -1) { state.setCellContents(p.x, p.y, ims[index].boardIndex); } } repaint(); } } else { boolean[] conditions = { (p.x == 0 && p.y > 0 && p.y <= h), // left (p.x == w + 1 && p.y > 0 && p.y <= h), // right (p.y == 0 && p.x > 0 && p.x <= w), // top (p.y == h + 1 && p.x > 0 && p.x <= w) // bottom }; int[] label_direction = { BoardState.LABEL_LEFT, BoardState.LABEL_RIGHT, BoardState.LABEL_TOP, BoardState.LABEL_BOTTOM }; int[] label_index = {p.y - 1, p.y - 1, p.x - 1, p.x - 1}; for (int x = 0; x < conditions.length; ++x) { if (conditions[x]) { if (e.getButton() == MouseEvent.BUTTON1) { // left click int val = state.getLabel(label_direction[x], label_index[x]); state.setLabel(label_direction[x], label_index[x], pm.getNextLabelValue(val)); } else { BoardImage[] ims = pz.getAllBorderImages(); if (ims.length > 0) { int index = ImageChooserDialog.chooseImage(ims); if (index != -1) { state.setLabel(label_direction[x], label_index[x], ims[index].boardIndex); } } } repaint(); break; } } } } } }