diff --git a/src/main/java/edu/rpi/legup/puzzle/kakurasu/rules/FinishWithEmptyDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/kakurasu/rules/RequiredEmptyDirectRule.java similarity index 96% rename from src/main/java/edu/rpi/legup/puzzle/kakurasu/rules/FinishWithEmptyDirectRule.java rename to src/main/java/edu/rpi/legup/puzzle/kakurasu/rules/RequiredEmptyDirectRule.java index cdaffc082..cf97a1671 100644 --- a/src/main/java/edu/rpi/legup/puzzle/kakurasu/rules/FinishWithEmptyDirectRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/kakurasu/rules/RequiredEmptyDirectRule.java @@ -12,8 +12,8 @@ import java.awt.*; import java.util.List; -public class FinishWithEmptyDirectRule extends DirectRule { - public FinishWithEmptyDirectRule() { +public class RequiredEmptyDirectRule extends DirectRule { + public RequiredEmptyDirectRule() { super( "KAKU-BASC-0002", "Finish with Empty", @@ -57,6 +57,7 @@ public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElem * @return if the cell is forced to be at its position on the board */ private boolean isForced(KakurasuBoard board, KakurasuCell cell) { + // TODO: Fix this so it doesn't only work if all are empty Point loc = cell.getLocation(); List filledRow = board.getRowCol(loc.y, KakurasuType.FILLED, true); List filledCol = board.getRowCol(loc.x, KakurasuType.FILLED, false); diff --git a/src/main/java/edu/rpi/legup/puzzle/kakurasu/rules/FinishWithFilledDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/kakurasu/rules/RequiredFilledDirectRule.java similarity index 95% rename from src/main/java/edu/rpi/legup/puzzle/kakurasu/rules/FinishWithFilledDirectRule.java rename to src/main/java/edu/rpi/legup/puzzle/kakurasu/rules/RequiredFilledDirectRule.java index 3cb6f236f..e34409a6a 100644 --- a/src/main/java/edu/rpi/legup/puzzle/kakurasu/rules/FinishWithFilledDirectRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/kakurasu/rules/RequiredFilledDirectRule.java @@ -7,18 +7,16 @@ import edu.rpi.legup.model.tree.TreeTransition; import edu.rpi.legup.puzzle.kakurasu.KakurasuBoard; import edu.rpi.legup.puzzle.kakurasu.KakurasuCell; -import edu.rpi.legup.puzzle.kakurasu.KakurasuClue; import edu.rpi.legup.puzzle.kakurasu.KakurasuType; import java.awt.*; -import java.util.ArrayList; import java.util.List; -public class FinishWithFilledDirectRule extends DirectRule { - public FinishWithFilledDirectRule() { +public class RequiredFilledDirectRule extends DirectRule { + public RequiredFilledDirectRule() { super( "KAKU-BASC-0001", - "Finish with Filled", + "Required Filled", "The only way to satisfy the clue in a row or column are these filled tiles.", "edu/rpi/legup/images/kakurasu/temp.png"); } @@ -59,6 +57,7 @@ public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElem * @return if the cell is forced to be at its position on the board */ private boolean isForced(KakurasuBoard board, KakurasuCell cell) { + // TODO: Fix this so it doesn't only work if all are filled Point loc = cell.getLocation(); List filledRow = board.getRowCol(loc.y, KakurasuType.FILLED, true); List unknownRow = board.getRowCol(loc.y, KakurasuType.UNKNOWN, true); diff --git a/src/main/java/edu/rpi/legup/puzzle/kakurasu/rules/UnreachableSumContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/kakurasu/rules/UnreachableSumContradictionRule.java index 5cbea72db..4deea2370 100644 --- a/src/main/java/edu/rpi/legup/puzzle/kakurasu/rules/UnreachableSumContradictionRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/kakurasu/rules/UnreachableSumContradictionRule.java @@ -8,6 +8,7 @@ import edu.rpi.legup.puzzle.kakurasu.KakurasuType; import java.awt.*; +import java.util.ArrayList; import java.util.List; public class UnreachableSumContradictionRule extends ContradictionRule { @@ -33,8 +34,6 @@ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) { KakurasuBoard kakurasuBoard = (KakurasuBoard) board; KakurasuCell cell = (KakurasuCell) puzzleElement; - // TODO: Finish this rule - Point loc = cell.getLocation(); List filledRow = kakurasuBoard.getRowCol(loc.y, KakurasuType.FILLED, true); List unknownRow = kakurasuBoard.getRowCol(loc.y, KakurasuType.UNKNOWN, true); @@ -50,10 +49,51 @@ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) { colValueRemaining -= kc.getLocation().y + 1; } - if (true) { + // If the value for either the row or col is already exceeded, this is the wrong rule to call. + if(rowValueRemaining < 0 || colValueRemaining < 0) return super.getNoContradictionMessage(); + + // If either value is already 0, then it is already possible to fulfill + // If it isn't 0, then it's possible for the remaining values to not be able to fulfill it + boolean rowPossible = (rowValueRemaining==0), colPossible = (colValueRemaining==0); + + int rowTotal = 0, colTotal = 0; + // No need to sort the values as the KakurasuCells are given in increasing index order + if(!rowPossible) { + ArrayList rowValues = new ArrayList<>(); + for(KakurasuCell kc : unknownRow) { + rowValues.add(kc.getLocation().x + 1); + rowTotal += kc.getLocation().x + 1; + } + // If the remaining unknown cells' values is less than the remaining value, + // this requires the usage of a different contradiction rule, not this one. + if(rowTotal < rowValueRemaining) return super.getNoContradictionMessage(); + rowPossible = isReachable(rowValueRemaining, 0, rowValues); + } + if(!colPossible) { + ArrayList colValues = new ArrayList<>(); + for(KakurasuCell kc : unknownCol) { + colValues.add(kc.getLocation().y + 1); + colTotal += kc.getLocation().y + 1; + } + // If the remaining unknown cells' values is less than the remaining value, + // this requires the usage of a different contradiction rule, not this one. + if(colTotal < colValueRemaining) return super.getNoContradictionMessage(); + colPossible = isReachable(colValueRemaining, 0, colValues); + } + + if (!rowPossible || !colPossible) { return null; } else { return super.getNoContradictionMessage(); } } + + // Helper function that checks if the target clue is reachable given a list of KakurasuCells + // This function only works if the list of values are given in increasing index order (which it currently is) + private boolean isReachable(int target, int currentIndex, ArrayList values) { + if(target == 0) return true; + if(target < 0 || currentIndex >= values.size()) return false; + return (isReachable(target, currentIndex+1, values) || + isReachable(target - values.get(currentIndex), currentIndex+1, values)); + } } diff --git a/src/main/java/edu/rpi/legup/puzzle/kakurasu/rules/kakurasu_reference_sheet.txt b/src/main/java/edu/rpi/legup/puzzle/kakurasu/rules/kakurasu_reference_sheet.txt index 9f7eb0976..8dfccc616 100644 --- a/src/main/java/edu/rpi/legup/puzzle/kakurasu/rules/kakurasu_reference_sheet.txt +++ b/src/main/java/edu/rpi/legup/puzzle/kakurasu/rules/kakurasu_reference_sheet.txt @@ -1,10 +1,8 @@ -KAKU-BASC-0001 : FinishWithFilledDirectRule -KAKU-BASC-0002 : FinishWithEmptyDirectRule -KAKU-BASC-0003 : RequiredFilledDirectRule - +KAKU-BASC-0001 : RequiredFilledDirectRule +KAKU-BASC-0002 : RequiredEmptyDirectRule KAKU-CONT-0001 : ExceededSumContradictionRule KAKU-CONT-0002 : IncompleteSumContradictionRule KAKU-CONT-0003 : UnreachableSumContradictionRule -KAKU-CASE-0001 : A \ No newline at end of file +KAKU-CASE-0001 : FilledOrEmptyCaseRule \ No newline at end of file