diff --git a/diuf/sudoku/Cell.java b/diuf/sudoku/Cell.java
index 11a800d..8fa5dd8 100644
--- a/diuf/sudoku/Cell.java
+++ b/diuf/sudoku/Cell.java
@@ -92,6 +92,21 @@ public CellSet getVisibleCells() {
return Grid.visibleCellsSet[index];
}
+ public boolean canSeeCell(Cell other) {
+ return Grid.visibleCellsSet[index].contains(other);
+ }
+
+ public boolean canSeeAnyOfCells(CellSet cellSet) {
+ CellSet currentSet = new CellSet(Grid.visibleCellsSet[index]);
+ currentSet.retainAll(cellSet);
+ int currentSetSize = currentSet.size();
+ if (currentSetSize > 0)
+ return true;
+ return false;
+ }
+
+
+
/**
* Get the cells that form the "house" of this cell. The
* cell indexes have to be greater than this cell index. The "house"
diff --git a/diuf/sudoku/Grid.java b/diuf/sudoku/Grid.java
index 21b0400..c6b97a4 100644
--- a/diuf/sudoku/Grid.java
+++ b/diuf/sudoku/Grid.java
@@ -77,9 +77,9 @@ public class Grid {
public static final int[][] cellRegions;
public static final int[][] visibleCellIndex;
public static final int[][] forwardVisibleCellIndex;
- private static final Block[] blocks;
- private static final Row[] rows;
- private static final Column[] columns;
+ public static final Block[] blocks;
+ public static final Row[] rows;
+ public static final Column[] columns;
public static final Region[][] regions;
public static final CellSet[] visibleCellsSet;
public static final CellSet[] forwardVisibleCellsSet;
@@ -670,7 +670,7 @@ public String toString() {
public String toFullString() {
Settings settings = Settings.getInstance();
if (settings.isRCNotation())
- return toString() + " R" + (rowNum + 1);
+ return toString() + " " + (rowNum + 1);
else
return toString() + " " + (rowNum + 1);
}
@@ -714,7 +714,7 @@ public String toString() {
public String toFullString() {
Settings settings = Settings.getInstance();
if (settings.isRCNotation())
- return toString() + " C" + (columnNum + 1);
+ return toString() + " " + (columnNum + 1);
else
return toString() + " " + (char)('A' + columnNum);
}
diff --git a/diuf/sudoku/Settings.java b/diuf/sudoku/Settings.java
index 95ec1f9..839bcb6 100644
--- a/diuf/sudoku/Settings.java
+++ b/diuf/sudoku/Settings.java
@@ -17,9 +17,9 @@
public class Settings {
public final static int VERSION = 1;
- public final static int REVISION = 4;
+ public final static int REVISION = 6;
public final static String SUBREV = ".1";
- public final static String releaseDate = "2019-09-22";
+ public final static String releaseDate = "2019-10-15";
public final static String releaseYear = "2019";
public final static String releaseLicence = "Lesser General Public License";
public final static String releaseLicenceMini = "LGPL";
diff --git a/diuf/sudoku/SolvingTechnique.java b/diuf/sudoku/SolvingTechnique.java
index ee98583..0deca20 100644
--- a/diuf/sudoku/SolvingTechnique.java
+++ b/diuf/sudoku/SolvingTechnique.java
@@ -19,6 +19,7 @@ public enum SolvingTechnique {
NakedTriplet("Naked Triplet"),
Swordfish("Swordfish"),
HiddenTriplet("Hidden Triplet"),
+ TurbotFish("Scraper, Kite, Turbot"),
XYWing("XY-Wing"),
XYZWing("XYZ-Wing"),
// WWing("W-Wing"),
@@ -27,6 +28,7 @@ public enum SolvingTechnique {
NakedQuad("Naked Quad"),
Jellyfish("Jellyfish"),
HiddenQuad("Hidden Quad"),
+ ThreeStrongLinks("3 Strong-linked Fishes"),
//VWXYZWing4("VWXYZ-Wing 4"),
//VWXYZWing5("VWXYZ-Wing 5"),
VWXYZWing("VWXYZ-Wing"),
diff --git a/diuf/sudoku/gui/GenerateDialog.java b/diuf/sudoku/gui/GenerateDialog.java
index 223359f..17e78d4 100644
--- a/diuf/sudoku/gui/GenerateDialog.java
+++ b/diuf/sudoku/gui/GenerateDialog.java
@@ -527,6 +527,168 @@ public String getnotMaxTechnique2() {
public String getnotMaxTechnique3() {
return "";
}
+ },
+ TwoStringKite {
+
+ @Override
+ public double getMinDifficulty() {
+ return 4.1;
+ }
+
+ @Override
+ public double getMaxDifficulty() {
+ return 4.1;
+ }
+ @Override
+ public double getincludeDifficulty1() {
+ return 0.0;
+ }
+ @Override
+ public double getincludeDifficulty2() {
+ return 0.0;
+ }
+ @Override
+ public double getincludeDifficulty3() {
+ return 0.0;
+ }
+ @Override
+ public double getexcludeDifficulty1() {
+ return 0.0;
+ }
+ @Override
+ public double getexcludeDifficulty2() {
+ return 0.0;
+ }
+ @Override
+ public double getexcludeDifficulty3() {
+ return 0.0;
+ }
+ @Override
+ public double getnotMaxDifficulty1() {
+ return 0.0;
+ }
+ @Override
+ public double getnotMaxDifficulty2() {
+ return 0.0;
+ }
+ @Override
+ public double getnotMaxDifficulty3() {
+ return 0.0;
+ }
+ public String getexcludeTechnique1() {
+ return "Skyscraper";
+ }
+ @Override
+ public String getexcludeTechnique2() {
+ return "";
+ }
+ @Override
+ public String getexcludeTechnique3() {
+ return "";
+ }
+ public String getincludeTechnique1() {
+ return "";
+ }
+ @Override
+ public String getincludeTechnique2() {
+ return "";
+ }
+ @Override
+ public String getincludeTechnique3() {
+ return "";
+ }
+ public String getnotMaxTechnique1() {
+ return "";
+ }
+ @Override
+ public String getnotMaxTechnique2() {
+ return "";
+ }
+ @Override
+ public String getnotMaxTechnique3() {
+ return "";
+ }
+ },
+ ThreeStrongLinks {
+
+ @Override
+ public double getMinDifficulty() {
+ return 5.4;
+ }
+
+ @Override
+ public double getMaxDifficulty() {
+ return 5.6;
+ }
+ @Override
+ public double getincludeDifficulty1() {
+ return 0.0;
+ }
+ @Override
+ public double getincludeDifficulty2() {
+ return 0.0;
+ }
+ @Override
+ public double getincludeDifficulty3() {
+ return 0.0;
+ }
+ @Override
+ public double getexcludeDifficulty1() {
+ return 0.0;
+ }
+ @Override
+ public double getexcludeDifficulty2() {
+ return 0.0;
+ }
+ @Override
+ public double getexcludeDifficulty3() {
+ return 0.0;
+ }
+ @Override
+ public double getnotMaxDifficulty1() {
+ return 0.0;
+ }
+ @Override
+ public double getnotMaxDifficulty2() {
+ return 0.0;
+ }
+ @Override
+ public double getnotMaxDifficulty3() {
+ return 0.0;
+ }
+ public String getexcludeTechnique1() {
+ return "";
+ }
+ @Override
+ public String getexcludeTechnique2() {
+ return "";
+ }
+ @Override
+ public String getexcludeTechnique3() {
+ return "";
+ }
+ public String getincludeTechnique1() {
+ return " 10";
+ }
+ @Override
+ public String getincludeTechnique2() {
+ return "";
+ }
+ @Override
+ public String getincludeTechnique3() {
+ return "";
+ }
+ public String getnotMaxTechnique1() {
+ return "";
+ }
+ @Override
+ public String getnotMaxTechnique2() {
+ return "";
+ }
+ @Override
+ public String getnotMaxTechnique3() {
+ return "";
+ }
},
WXYZ {
@@ -923,7 +1085,7 @@ public String getexcludeTechnique3() {
return "";
}
public String getincludeTechnique1() {
- return "";
+ return "ligned";
}
@Override
public String getincludeTechnique2() {
diff --git a/diuf/sudoku/gui/ThreeStrongLinks.html b/diuf/sudoku/gui/ThreeStrongLinks.html
new file mode 100644
index 0000000..c0724dc
--- /dev/null
+++ b/diuf/sudoku/gui/ThreeStrongLinks.html
@@ -0,0 +1,6 @@
+
+
+ 3 strong links: Requires a fish with 3 strong links (101 or 102 formation)
+ Rating: 5.5-5.6
+
+
\ No newline at end of file
diff --git a/diuf/sudoku/gui/TwoStringKite.html b/diuf/sudoku/gui/TwoStringKite.html
new file mode 100644
index 0000000..5c80500
--- /dev/null
+++ b/diuf/sudoku/gui/TwoStringKite.html
@@ -0,0 +1,6 @@
+
+
+ 2-String Kite: The Sudoku requires a 2-String Kite to solve.
+ Rating: 4.1
+
+
\ No newline at end of file
diff --git a/diuf/sudoku/solver/Rule.java b/diuf/sudoku/solver/Rule.java
index 29a355c..011ed1e 100644
--- a/diuf/sudoku/solver/Rule.java
+++ b/diuf/sudoku/solver/Rule.java
@@ -44,10 +44,12 @@ public interface Rule {
*
+ This technique relies on Conjugate Pairs.
+ The value {1} in {8}, {9} and {10} forms
+ 3 strong links (conjugate pairs). The 1st set of bridge cells
+ {3} and {4} share the same region ({11}),
+ therefore forming a weak link. The 2nd set of bridge cells
+ {5} and {6} share the same region ({12}) which
+ means that they also form a weak link. The 3 strong links therfore
+ are joined with these weak links.
+
+
+ Any occurrence of the value {1} can therefore be
+ removed from any cells sharing a row, column or block
+ with both start cells {2} and {7}.
+
+
+ This technique is similar to a 2x2x2 Finned Sashimi Swordfish technique logic.
+
+ This technique relies on Conjugate Pairs.
+ The value {1} in {6} and {7} forms
+ 2 strong links (conjugate pairs). The bridge cells
+ {3} and {4} share the same region ({8}),
+ therefore forming a weak link.
+
+
+ Any occurrence of the value {1} can therefore be
+ removed from any cells sharing a row, column or block
+ with both start cells {2} and {5}.
+
+
+ This technique is similar to a 2x2 Finned Sashimi X-Wing technique logic.
+
+
+
\ No newline at end of file
diff --git a/diuf/sudoku/solver/rules/TurbotFishHint.java b/diuf/sudoku/solver/rules/TurbotFishHint.java
new file mode 100644
index 0000000..2efcd2e
--- /dev/null
+++ b/diuf/sudoku/solver/rules/TurbotFishHint.java
@@ -0,0 +1,211 @@
+package diuf.sudoku.solver.rules;
+
+import java.util.*;
+import diuf.sudoku.*;
+import diuf.sudoku.solver.*;
+import diuf.sudoku.solver.rules.chaining.*;
+import diuf.sudoku.tools.*;
+
+
+/**
+ * Turbot Fish hints
+ */
+public class TurbotFishHint extends IndirectHint implements Rule, HasParentPotentialHint {
+
+ private final int value;
+ private final Cell startCell;
+ private final Cell endCell;
+ private final Cell bridgeCell1;
+ private final Cell bridgeCell2;
+ private final Grid.Region baseSet;
+ private final Grid.Region coverSet;
+ private final Grid.Region shareRegion;
+
+ public TurbotFishHint(IndirectHintProducer rule, Map removablePotentials,
+ Cell startCell, Cell endCell, Cell bridgeCell1, Cell bridgeCell2,
+ int value, Grid.Region base, Grid.Region cover, Grid.Region shareRegion) {
+ super(rule, removablePotentials);
+ this.value = value;
+ this.startCell = startCell;
+ this.endCell = endCell;
+ this.bridgeCell1 = bridgeCell1;
+ this.bridgeCell2 = bridgeCell2;
+ this.baseSet = base;
+ this.coverSet = cover;
+ this.shareRegion = shareRegion;
+ }
+
+ @Override
+ public int getViewCount() {
+ return 1;
+ }
+
+ @Override
+ public Cell[] getSelectedCells() {
+ return new Cell[] { startCell, endCell };
+ }
+
+ @Override
+ public Map getGreenPotentials(Grid grid, int viewNum) {
+ Map result = new HashMap<>();
+ BitSet fishDigitSet = SingletonBitSet.create(value);
+ result.put(startCell, fishDigitSet); // orange
+ result.put(bridgeCell1, fishDigitSet);
+ result.put(bridgeCell2, fishDigitSet); // orange
+ result.put(endCell, fishDigitSet);
+ return result;
+ }
+
+ @Override
+ public Map getRedPotentials(Grid grid, int viewNum) {
+ Map result = new HashMap<>(super.getRemovablePotentials());
+ BitSet fishDigitSet = SingletonBitSet.create(value);
+ result.put(startCell, fishDigitSet);
+ result.put(bridgeCell2, fishDigitSet);
+ return result;
+ }
+
+ @Override
+ public Collection getLinks(Grid grid, int viewNum) {
+ Collection result = new ArrayList<>();
+ result.add(new Link(startCell, value, bridgeCell1, value));
+ result.add(new Link(bridgeCell1, value, bridgeCell2, value));
+ result.add(new Link(bridgeCell2, value, endCell, value));
+ return result;
+ }
+
+ @Override
+ public Grid.Region[] getRegions() {
+ //return new Grid.Region[] { shareRegion };
+ return null;
+ }
+
+ @Override
+ public String toString() {
+ return getName() +
+ ": " +
+ Cell.toFullString(startCell, bridgeCell1, bridgeCell2, endCell) +
+ " on value " +
+ value;
+ }
+
+ @Override
+ public String toHtml(Grid grid) {
+ String result = HtmlLoader.loadHtml(this, "TurbotFishHint.html");
+ String name = getName();
+ String base = this.baseSet.toFullString();
+ String cover = this.coverSet.toFullString();
+ String shared = this.shareRegion.toFullString();
+ String value = Integer.toString(this.value);
+ String cell1 = startCell.toString();
+ String cell2 = bridgeCell1.toString();
+ String cell3 = bridgeCell2.toString();
+ String cell4 = endCell.toString();
+ result = HtmlLoader.format(result, name, value, cell1, cell2, cell3, cell4, base, cover, shared);
+ return result;
+ }
+
+ @Override
+ public String getName() {
+ Class extends Grid.Region> region1 = baseSet.getClass();
+ Class extends Grid.Region> region2 = coverSet.getClass();
+ if (region1 == Grid.Row.class) {
+ if (region2 == Grid.Row.class)
+ return "Skyscraper";
+ else
+ if (region2 == Grid.Column.class)
+ return "Two-string Kite";
+ else
+ return "Turbot Fish";
+ }
+ else {
+ if (region1 == Grid.Column.class)
+ if (region2 == Grid.Row.class)
+ return "Two-string Kite";
+ else
+ if (region2 == Grid.Column.class)
+ return "Skyscraper";
+ else
+ return "Turbot Fish";
+ else
+ return "Turbot Fish";
+ }
+ }
+
+ @Override
+ public String getShortName() {
+ Class extends Grid.Region> region1 = baseSet.getClass();
+ Class extends Grid.Region> region2 = coverSet.getClass();
+ if (region1 == Grid.Row.class) {
+ if (region2 == Grid.Row.class)
+ return "Sky";
+ else
+ if (region2 == Grid.Column.class)
+ return "2SK";
+ else
+ return "TF";
+ }
+ else {
+ if (region1 == Grid.Column.class)
+ if (region2 == Grid.Row.class)
+ return "2SK";
+ else
+ if (region2 == Grid.Column.class)
+ return "Sky";
+ else
+ return "TF";
+ else
+ if (region2 == Grid.Block.class)
+ return "GXW";
+ else
+ return "TF";
+ }
+ }
+
+ @Override
+ public double getDifficulty() {
+ String name = getName();
+ if (name.equals("Skyscraper")) {
+ return 4.0;
+ } else if (name.equals("Two-string Kite")) {
+ return 4.1;
+ } else {
+ return 4.2;
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return startCell.hashCode() ^ endCell.hashCode() ^
+ bridgeCell1.hashCode() ^ bridgeCell2.hashCode() ^ value;
+ }
+
+
+ public String getClueHtml(Grid grid, boolean isBig) {
+ if (isBig) {
+ return "Look for a " + getName() + " on the value " + value;
+ } else {
+ return "Look for a " + getName();
+ }
+ }
+
+
+
+ @Override
+ public Collection getRuleParents(Grid initialGrid, Grid currentGrid) {
+ Collection result = new ArrayList<>();
+ Cell startCell = Grid.getCell(this.startCell.getIndex());
+ Cell endCell = Grid.getCell(this.endCell.getIndex());
+ Cell bridgeCell1 = Grid.getCell(this.bridgeCell1.getIndex());
+ Cell bridgeCell2 = Grid.getCell(this.bridgeCell2.getIndex());
+ if (initialGrid.hasCellPotentialValue(startCell.getIndex(), value) && !initialGrid.hasCellPotentialValue(this.startCell.getIndex(), value))
+ result.add(new Potential(this.startCell, value, false));
+ if (initialGrid.hasCellPotentialValue(bridgeCell1.getIndex(), value) && !initialGrid.hasCellPotentialValue(this.bridgeCell1.getIndex(), value))
+ result.add(new Potential(this.bridgeCell1, value, false));
+ if (initialGrid.hasCellPotentialValue(bridgeCell2.getIndex(), value) && !initialGrid.hasCellPotentialValue(this.bridgeCell2.getIndex(), value))
+ result.add(new Potential(this.bridgeCell2, value, false));
+ if (initialGrid.hasCellPotentialValue(endCell.getIndex(), value) && !initialGrid.hasCellPotentialValue(this.endCell.getIndex(), value))
+ result.add(new Potential(this.endCell, value, false));
+ return result;
+ }
+}
diff --git a/diuf/sudoku/solver/rules/VWXYZWing.java b/diuf/sudoku/solver/rules/VWXYZWing.java
index 21cc29c..b4855e5 100644
--- a/diuf/sudoku/solver/rules/VWXYZWing.java
+++ b/diuf/sudoku/solver/rules/VWXYZWing.java
@@ -25,19 +25,19 @@ public class VWXYZWing implements IndirectHintProducer {
private boolean isVWXYZWing(BitSet vwxyzValues,BitSet vzValues, BitSet wzValues, BitSet xzValues, BitSet aBit, Cell yzCell, Cell xzCell, Cell wzCell, Cell vzCell, Cell vwxyzCell) {
BitSet inter = (BitSet)aBit.clone();
inter.and(xzValues);
- if (inter.cardinality() == 1 && !(yzCell.getX() == xzCell.getX() || yzCell.getY() == xzCell.getY() || yzCell.getB() == xzCell.getB()))
+ if (inter.cardinality() == 1 && !yzCell.canSeeCell(xzCell))
return false;
inter = (BitSet)aBit.clone();
inter.and(wzValues);
- if (inter.cardinality() == 1 && !(yzCell.getX() == wzCell.getX() || yzCell.getY() == wzCell.getY() || yzCell.getB() == wzCell.getB()))
+ if (inter.cardinality() == 1 && !yzCell.canSeeCell(wzCell))
return false;
inter = (BitSet)aBit.clone();
inter.and(vzValues);
- if (inter.cardinality() == 1 && !(yzCell.getX() == vzCell.getX() || yzCell.getY() == vzCell.getY() || yzCell.getB() == vzCell.getB()))
+ if (inter.cardinality() == 1 && !yzCell.canSeeCell(vzCell))
return false;
inter = (BitSet)aBit.clone();
inter.and(vwxyzValues);
- if (inter.cardinality() == 1 && !(yzCell.getX() == vwxyzCell.getX() || yzCell.getY() == vwxyzCell.getY() || yzCell.getB() == vwxyzCell.getB()))
+ if (inter.cardinality() == 1 && !yzCell.canSeeCell(vwxyzCell))
return false;
return true;
}
@@ -103,13 +103,10 @@ public void getHints(Grid grid, HintsAccumulator accu) throws InterruptedExcepti
biggestCardinality4 = xzValues.cardinality();
wingSize = vwxyzValues.cardinality() + vzValues.cardinality() + wzValues.cardinality() + xzValues.cardinality();
//Restrict potential yzCell to Grid Cells that are visible by one or more of the other cells
- CellSet noYZ = new CellSet(new int[]{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80});
- noYZ.removeAll(vwxyzCell.getVisibleCells());
- noYZ.removeAll(vzCell.getVisibleCells());
- noYZ.removeAll(wzCell.getVisibleCells());
- noYZ.removeAll(xzCell.getVisibleCells());
- CellSet yzCellRange = new CellSet(new int[]{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80});
- yzCellRange.removeAll(noYZ);
+ CellSet yzCellRange = new CellSet(vwxyzCell.getVisibleCells());
+ yzCellRange.addAll(vzCell.getVisibleCells());
+ yzCellRange.addAll(wzCell.getVisibleCells());
+ yzCellRange.addAll(xzCell.getVisibleCells());
yzCellRange.remove(vwxyzCell);
yzCellRange.remove(vzCell);
yzCellRange.remove(wzCell);
diff --git a/diuf/sudoku/solver/rules/WXYZWing.java b/diuf/sudoku/solver/rules/WXYZWing.java
index 7ea8188..47d4082 100644
--- a/diuf/sudoku/solver/rules/WXYZWing.java
+++ b/diuf/sudoku/solver/rules/WXYZWing.java
@@ -25,15 +25,15 @@ public class WXYZWing implements IndirectHintProducer {
private boolean isWXYZWing(BitSet wxyzValues,BitSet wzValues, BitSet xzValues, BitSet aBit, Cell yzCell, Cell xzCell, Cell wzCell, Cell wxyzCell) {
BitSet inter = (BitSet)aBit.clone();
inter.and(xzValues);
- if (inter.cardinality() == 1 && !(yzCell.getX() == xzCell.getX() || yzCell.getY() == xzCell.getY() || yzCell.getB() == xzCell.getB()))
+ if (inter.cardinality() == 1 && !yzCell.canSeeCell(xzCell))
return false;
inter = (BitSet)aBit.clone();
inter.and(wzValues);
- if (inter.cardinality() == 1 && !(yzCell.getX() == wzCell.getX() || yzCell.getY() == wzCell.getY() || yzCell.getB() == wzCell.getB()))
+ if (inter.cardinality() == 1 && !yzCell.canSeeCell(wzCell))
return false;
inter = (BitSet)aBit.clone();
inter.and(wxyzValues);
- if (inter.cardinality() == 1 && !(yzCell.getX() == wxyzCell.getX() || yzCell.getY() == wxyzCell.getY() || yzCell.getB() == wxyzCell.getB()))
+ if (inter.cardinality() == 1 && !yzCell.canSeeCell(wxyzCell))
return false;
return true;
}
@@ -81,12 +81,9 @@ public void getHints(Grid grid, HintsAccumulator accu) throws InterruptedExcepti
biggestCardinality3 = xzValues.cardinality();
wingSize = wxyzValues.cardinality() + wzValues.cardinality() + xzValues.cardinality();
//Restrict potential yzCell to Grid Cells that are visible by one or more of the other cells
- CellSet noYZ = new CellSet(new int[]{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80});
- noYZ.removeAll(wxyzCell.getVisibleCells());
- noYZ.removeAll(wzCell.getVisibleCells());
- noYZ.removeAll(xzCell.getVisibleCells());
- CellSet yzCellRange = new CellSet(new int[]{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80});
- yzCellRange.removeAll(noYZ);
+ CellSet yzCellRange = new CellSet(wxyzCell.getVisibleCells());
+ yzCellRange.addAll(wzCell.getVisibleCells());
+ yzCellRange.addAll(xzCell.getVisibleCells());
yzCellRange.remove(wxyzCell);
yzCellRange.remove(wzCell);
yzCellRange.remove(xzCell);