Skip to content

Commit

Permalink
Merge pull request #849 from summerhenson/star-battle
Browse files Browse the repository at this point in the history
Star battle
  • Loading branch information
summerhenson authored Aug 9, 2024
2 parents 9abd9c0 + 9e9d8b2 commit 9935e3b
Show file tree
Hide file tree
Showing 30 changed files with 1,434 additions and 119 deletions.
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

0 comments on commit 9935e3b

Please sign in to comment.