Skip to content

Commit

Permalink
Allowed Required Direct Rules to work for all general cases instead o…
Browse files Browse the repository at this point in the history
…f needing the remaining unknown cells to all have to be the filled or empty.
  • Loading branch information
ADEPLI committed Dec 6, 2024
1 parent e8fe776 commit 0f024bb
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ 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<KakurasuCell> filledRow = board.getRowCol(loc.y, KakurasuType.FILLED, true);
List<KakurasuCell> filledCol = board.getRowCol(loc.x, KakurasuType.FILLED, false);
Expand All @@ -67,14 +66,16 @@ private boolean isForced(KakurasuBoard board, KakurasuCell cell) {
for(KakurasuCell kc : filledRow) {
rowSum += kc.getLocation().x + 1;
}
if(rowSum == board.getClue(board.getWidth(), loc.y).getData()) return true;
// If setting this cell to filled causes the clue to fail, this cell must be empty
if(rowSum + loc.x + 1 > board.getClue(board.getWidth(), loc.y).getData()) return true;

int colSum = 0;
for(KakurasuCell kc : filledCol) {
colSum += kc.getLocation().y + 1;
}
// Return true if the clue is fulfilled, false if it isn't
return (colSum == board.getClue(loc.x, board.getHeight()).getData());
// Return true if the clue is exceeded if this cell is filled,
// Return false if setting the cell to filled keeps the col total to under the clue value
return (colSum + loc.y + 1> board.getClue(loc.x, board.getHeight()).getData());
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import edu.rpi.legup.puzzle.kakurasu.KakurasuType;

import java.awt.*;
import java.util.ArrayList;
import java.util.List;

public class RequiredFilledDirectRule extends DirectRule {
Expand Down Expand Up @@ -65,24 +66,48 @@ private boolean isForced(KakurasuBoard board, KakurasuCell cell) {
List<KakurasuCell> unknownCol = board.getRowCol(loc.x, KakurasuType.UNKNOWN, false);

// Check if the remaining locations available must be filled to fulfill the clue value
int rowSum = 0;
int rowValueRemaining = board.getClue(board.getWidth(), loc.y).getData();
for(KakurasuCell kc : filledRow) {
rowSum += kc.getLocation().x + 1;
rowValueRemaining -= kc.getLocation().x + 1;
}
ArrayList<Integer> rowValues = new ArrayList<>();
// Add all the unknown row values to the Arraylist except for the one being checked by the function
for(KakurasuCell kc : unknownRow) {
rowSum += kc.getLocation().x + 1;
if(kc.getLocation() != loc) rowValues.add(kc.getLocation().x + 1);
}
if(rowSum == board.getClue(board.getWidth(), loc.y).getData()) return true;
// If the clue is not reachable without the current cell being filled, but is possible with it filled,
// then that means the current cell is a required fill on this board
if(!isReachable(rowValueRemaining, 0, rowValues) &&
isReachable(rowValueRemaining-(loc.x+1), 0, rowValues)) return true;

int colSum = 0;
int colValueRemaining = board.getClue(loc.x, board.getHeight()).getData();
for(KakurasuCell kc : filledCol) {
colSum += kc.getLocation().y + 1;
colValueRemaining -= kc.getLocation().y + 1;
}
ArrayList<Integer> colValues = new ArrayList<>();
// Add all the unknown col values to the Arraylist except for the one being checked by the function
for(KakurasuCell kc : unknownCol) {
colSum += kc.getLocation().y + 1;
if(kc.getLocation() != loc) colValues.add(kc.getLocation().y + 1);
}
// Return true if the clue is fulfilled, false if it isn't
return (colSum == board.getClue(loc.x, board.getHeight()).getData());
return (!isReachable(colValueRemaining, 0, rowValues) &&
isReachable(colValueRemaining-(loc.y+1), 0, colValues));
}

/**
* 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)
*
* @param target The integer that we are trying to add up to, given the values
* @param currentIndex The index of the next value that we are considering
* @param values Values that we are given to try to sum up to the target
* @return If it's possible to sum the values in a way to get the target value
*/
private boolean isReachable(int target, int currentIndex, ArrayList<Integer> 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));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
rowValues.add(kc.getLocation().x + 1);
rowTotal += kc.getLocation().x + 1;
}
// If the remaining unknown cells' values is less than the remaining value,
// If the remaining unknown cells' values is less than the remaining clue value,
// this requires the usage of a different contradiction rule, not this one.
if(rowTotal < rowValueRemaining) return super.getNoContradictionMessage();
rowPossible = isReachable(rowValueRemaining, 0, rowValues);
Expand All @@ -75,7 +75,7 @@ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
colValues.add(kc.getLocation().y + 1);
colTotal += kc.getLocation().y + 1;
}
// If the remaining unknown cells' values is less than the remaining value,
// If the remaining unknown cells' values is less than the remaining clue value,
// this requires the usage of a different contradiction rule, not this one.
if(colTotal < colValueRemaining) return super.getNoContradictionMessage();
colPossible = isReachable(colValueRemaining, 0, colValues);
Expand All @@ -88,8 +88,15 @@ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
}
}

// 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)
/**
* 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)
*
* @param target The integer that we are trying to add up to, given the values
* @param currentIndex The index of the next value that we are considering
* @param values Values that we are given to try to sum up to the target
* @return If it's possible to sum the values in a way to get the target value
*/
private boolean isReachable(int target, int currentIndex, ArrayList<Integer> values) {
if(target == 0) return true;
if(target < 0 || currentIndex >= values.size()) return false;
Expand Down

0 comments on commit 0f024bb

Please sign in to comment.