Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Star battle #849

Merged
merged 10 commits into from
Aug 9, 2024
53 changes: 53 additions & 0 deletions puzzles files/starbattle/5x5 Star Battle 1 star Normal/050102
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Legup version="2.0.0">
<puzzle name="StarBattle">
<board size="5" puzzle_num="1">
<region>
<cells>
<cell value="0" x="0" y="0"/>
</cells>
</region>
<region>
<cells>
<cell value="0" x="0" y="1"/>
<cell value="0" x="1" y="0"/>
<cell value="0" x="1" y="1"/>
<cell value="0" x="2" y="0"/>
<cell value="0" x="2" y="1"/>
<cell value="0" x="3" y="0"/>
<cell value="0" x="3" y="1"/>
<cell value="0" x="0" y="2"/>
<cell value="0" x="1" y="2"/>
</cells>
</region>
<region>
<cells>
<cell value="0" x="0" y="3"/>
<cell value="0" x="1" y="3"/>
<cell value="0" x="2" y="3"/>
</cells>
</region>
<region>
<cells>
<cell value="0" x="4" y="0"/>
<cell value="0" x="4" y="1"/>
<cell value="0" x="4" y="2"/>
<cell value="0" x="4" y="3"/>
</cells>
</region>
<region>
<cells>
<cell value="0" x="2" y="2"/>
<cell value="0" x="3" y="2"/>
<cell value="0" x="3" y="3"/>
<cell value="0" x="0" y="4"/>
<cell value="0" x="1" y="4"/>
<cell value="0" x="2" y="4"/>
<cell value="0" x="3" y="4"/>
<cell value="0" x="4" y="4"/>
</cells>
</region>
</board>
</puzzle>
<solved isSolved="false" lastSaved="--"/>
</Legup>
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,9 @@
import edu.rpi.legup.puzzle.starbattle.StarBattleBoard;
import edu.rpi.legup.puzzle.starbattle.StarBattleCell;
import edu.rpi.legup.puzzle.starbattle.StarBattleCellType;
import io.opencensus.trace.Link;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.*;

public class ColumnsWithinRegionsDirectRule extends DirectRule {
public ColumnsWithinRegionsDirectRule() {
Expand All @@ -23,6 +21,25 @@ public ColumnsWithinRegionsDirectRule() {
"edu/rpi/legup/images/starbattle/rules/ColumnsWithinRegionsDirectRule.png");
}

private void generateSubsets(List<List<Integer>> subsets, int current, int skip, int size) {
if (current == size) {
return;
}
List<List<Integer>> newSubsets = new LinkedList<List<Integer>>();
if (current != skip) {
for (List<Integer> subset: subsets) {
List<Integer> copy = new LinkedList<Integer>(subset);
copy.add(current);
newSubsets.add(copy);
}
subsets.addAll(newSubsets);
List<Integer> oneMember = new LinkedList<Integer>();
oneMember.add(current);
subsets.add(oneMember);
}
generateSubsets(subsets, current + 1 == skip ? current + 2 : current + 1, skip, size);
}

/**
* Checks whether the child node logically follows from the parent node at the specific
* puzzleElement index using this rule
Expand All @@ -34,67 +51,45 @@ public ColumnsWithinRegionsDirectRule() {
*/
@Override
public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
// assumption: the rule has been applied to its fullest extent and the rows and regions
// are now mutually encompassing

StarBattleBoard board = (StarBattleBoard) transition.getBoard();
StarBattleBoard origBoard = (StarBattleBoard) transition.getParents().get(0).getBoard();
StarBattleCell cell = (StarBattleCell) board.getPuzzleElement(puzzleElement);
int dim = board.getSize();
int region = cell.getGroupIndex();
int column = cell.getLocation().x;

if (cell.getType() != StarBattleCellType.BLACK) {
return "Only black cells are allowed for this rule!";
}
// the columns that are contained
Set<Integer> columns = new HashSet<Integer>();
// the regions that contain them
Set<Integer> regions = new HashSet<Integer>();
// columns and regions to process
List<Integer> columnsToCheck = new ArrayList<Integer>();
List<Integer> regionsToCheck = new ArrayList<Integer>();
int columnStars = 0;
int regionStars = 0;
regions.add(cell.getGroupIndex());
regionsToCheck.add(cell.getGroupIndex());

while (!columnsToCheck.isEmpty() || !regionsToCheck.isEmpty()) {
for (int i = 0; i < regionsToCheck.size(); ++i) {
int r = regionsToCheck.get(i);
regionStars += board.getRegion(r).numStars();
for (StarBattleCell c : board.getRegion(r).getCells()) {
int column = ((StarBattleCell) c).getLocation().x;
if (column != cell.getLocation().x && c.getType() == StarBattleCellType.UNKNOWN && columns.add(column)) {
columnsToCheck.add(column);
}
}
regionsToCheck.remove(i);
--i;
}
for (int j = 0; j < columnsToCheck.size(); ++j) {
int c = columnsToCheck.get(j);
columnStars += board.columnStars(c);
for (int i = 0; i < board.getSize(); ++i) {
int region = board.getCell(c, i).getGroupIndex();
if (board.getCell(c,i).getType() == StarBattleCellType.UNKNOWN && regions.add(region)) {
regionsToCheck.add(region);
List<List<Integer>> subsets = new LinkedList<List<Integer>>();
generateSubsets(subsets,0, column, dim);

for (List<Integer> columnSubset: subsets) {
Set<Integer> regions = new HashSet<Integer>();
boolean containsRegion = false;
int columnStars = 0;
int regionStars = 0;
for (int c: columnSubset) {
columnStars += origBoard.columnStars(c);
for (StarBattleCell ce: origBoard.getCol(c)) {
if (ce.getType() == StarBattleCellType.UNKNOWN) {
if (regions.add(ce.getGroupIndex())) {
regionStars += origBoard.getRegion(ce.getGroupIndex()).numStars();
}
if (ce.getGroupIndex() == region) {
containsRegion = true;
}
}
}
columnsToCheck.remove(j);
--j;
}
}
// are the columns and regions missing an equal amount of stars
if (board.getPuzzleNumber() * columns.size() - columnStars
!= board.getPuzzleNumber() * regions.size() - regionStars) {
return "The number of missing stars in the columns and regions must be equal and every extraneous cell must be black!";
}
if (columns.contains(cell.getLocation().x)) {
return "Only black out cells outside the column(s)!";
}
/*
for (int c: columns) {
if (c == cell.getLocation().x) {
return "Only black out cells outside the column(s)!";
if (containsRegion && board.getPuzzleNumber() * columnSubset.size() - columnStars
>= board.getPuzzleNumber() * regions.size() - regionStars) {
return null;
}
}
*/
return null;
return "The columns must fully fit within regions with the same number of stars missing!";
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@
import edu.rpi.legup.puzzle.starbattle.StarBattleCell;
import edu.rpi.legup.puzzle.starbattle.StarBattleCellType;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.*;

public class ColumnsWithinRowsDirectRule extends DirectRule {

Expand All @@ -24,6 +21,25 @@ public ColumnsWithinRowsDirectRule() {
"edu/rpi/legup/images/starbattle/rules/ColumnsWithinRowsDirectRule.png");
}

private void generateSubsets(List<List<Integer>> subsets, int current, int skip, int size) {
if (current == size) {
return;
}
List<List<Integer>> newSubsets = new LinkedList<List<Integer>>();
if (current != skip) {
for (List<Integer> subset: subsets) {
List<Integer> copy = new LinkedList<Integer>(subset);
copy.add(current);
newSubsets.add(copy);
}
subsets.addAll(newSubsets);
List<Integer> oneMember = new LinkedList<Integer>();
oneMember.add(current);
subsets.add(oneMember);
}
generateSubsets(subsets, current + 1 == skip ? current + 2 : current + 1, skip, size);
}

/**
* Checks whether the child node logically follows from the parent node at the specific
* puzzleElement index using this rule
Expand All @@ -39,59 +55,43 @@ public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElem
// assumption: the rule has been applied to its fullest extent and the rows and columns
// are now mutually encompassing
StarBattleBoard board = (StarBattleBoard) transition.getBoard();
StarBattleBoard origBoard = (StarBattleBoard) transition.getParents().get(0).getBoard();
StarBattleCell cell = (StarBattleCell) board.getPuzzleElement(puzzleElement);
int dim = board.getSize();
int row = cell.getLocation().y;
int column = cell.getLocation().x;

if (cell.getType() != StarBattleCellType.BLACK) {
return "Only black cells are allowed for this rule!";
}

// the columns that are contained
Set<Integer> columns = new HashSet<Integer>();
// the rows that contain them
Set<Integer> rows = new HashSet<Integer>();
// columns and rows to process
List<Integer> columnsToCheck = new ArrayList<Integer>();
List<Integer> rowsToCheck = new ArrayList<Integer>();
int columnStars = 0;
int rowStars = 0;
int firstRow = cell.getLocation().y;
rows.add(firstRow);
rowsToCheck.add(firstRow);
List<List<Integer>> subsets = new LinkedList<List<Integer>>();
generateSubsets(subsets,0, column, dim);

while (!columnsToCheck.isEmpty() || !rowsToCheck.isEmpty()) {
for (int i = 0; i < rowsToCheck.size(); ++i) {
int r = rowsToCheck.get(i);
rowStars += board.rowStars(r);
for (StarBattleCell c : board.getRow(r)) {
int column = c.getLocation().x;
if (c.getType() == StarBattleCellType.UNKNOWN && columns.add(column)) {
columnsToCheck.add(column);
for (List<Integer> columnSubset: subsets) {
Set<Integer> rows = new HashSet<Integer>();
boolean containsRow = false;
int columnStars = 0;
int rowStars = 0;
for (int c: columnSubset) {
columnStars += origBoard.columnStars(c);
for (StarBattleCell ce: origBoard.getCol(c)) {
if (ce.getType() == StarBattleCellType.UNKNOWN) {
if (rows.add(ce.getLocation().y)) {
rowStars += origBoard.rowStars(ce.getLocation().y);
}
if (ce.getLocation().y == row) {
containsRow = true;
}
}
}
rowsToCheck.remove(i);
--i;
}
for (int i = 0; i < columnsToCheck.size(); ++i) {
int c = columnsToCheck.get(i);
columnStars += board.columnStars(c);
for (StarBattleCell r : board.getCol(c)) {
int row = r.getLocation().y;
if (r.getType() == StarBattleCellType.UNKNOWN && rows.add(row)) {
rowsToCheck.add(row);
}
}
columnsToCheck.remove(i);
--i;
if (containsRow && board.getPuzzleNumber() * columnSubset.size() - columnStars
>= board.getPuzzleNumber() * rows.size() - rowStars) {
return null;
}
}
// are the columns and regions missing an equal amount of stars
if (board.getPuzzleNumber() * columns.size() - columnStars
!= board.getPuzzleNumber() * rows.size() - rowStars) {
return "The number of missing stars in the columns and rows must be equal and every extraneous cell must be black!";
}
if (columns.contains(cell.getLocation().x)) {
return "Only black out cells outside the column(s)!";
}
return null;
return "The columns must fully fit within rows with the same number of stars missing!";
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElem
StarBattleCell temp = adjacent[i];

if (temp != null && temp.getType() == StarBattleCellType.UNKNOWN) {
temp.setData(StarBattleCellType.BLACK.value);
//temp.setData(StarBattleCellType.BLACK.value);
int X = temp.getLocation().x;
int Y = temp.getLocation().y;
modified.getCell(X,Y).setData(StarBattleCellType.BLACK.value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ public RegionsWithinColumnsDirectRule() {
public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
ColumnsWithinRegionsDirectRule correspondingRule = new ColumnsWithinRegionsDirectRule();
String result = correspondingRule.checkRuleRawAt(transition, puzzleElement);
if (result != null && result.equals("Only black out cells outside the column(s)!")) {
return "Only black out cells outside the region(s)!";
if (result != null && result.equals("The columns must fully fit within regions with the same number of stars missing!")) {
return "The regions must fully fit within columns with the same number of stars missing!";
}
return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElem

RowsWithinRegionsDirectRule correspondingRule = new RowsWithinRegionsDirectRule();
String result = correspondingRule.checkRuleRawAt(transition, puzzleElement);
if (result != null && result.equals("Only black out cells outside the row(s)!")) {
return "Only black out cells outside the region(s)!";
if (result != null && result.equals("The rows must fully fit within regions with the same number of stars missing!")) {
return "The regions must fully fit within rows with the same number of stars missing!";
}
return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElem

ColumnsWithinRowsDirectRule correspondingRule = new ColumnsWithinRowsDirectRule();
String result = correspondingRule.checkRuleRawAt(transition, puzzleElement);
if (result != null && result.equals("Only black out cells outside the column(s)!")) {
return "Only black out cells outside the row(s)!";
if (result != null && result.equals("The columns must fully fit within rows with the same number of stars missing!")) {
return "The rows must fully fit within columns with the same number of stars missing!";
}
return result;
}
Expand Down
Loading
Loading