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

Update from dev #211

Merged
merged 21 commits into from
Jul 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 40 additions & 11 deletions bin/main/edu/rpi/legup/legup/config
Original file line number Diff line number Diff line change
@@ -1,14 +1,43 @@
<Legup version="2.0">
<Legup version="3.0">
<puzzles>
<puzzle name="BattleShip" qualifiedClassName="edu.rpi.legup.puzzle.battleship.Battleship" fileType=".xml"/>
<puzzle name="Fillapix" qualifiedClassName="edu.rpi.legup.puzzle.fillapix.Fillapix" fileType=".xml"/>
<puzzle name="Heyawake" qualifiedClassName="edu.rpi.legup.puzzle.heyawake.Heyawake" fileType=".xml"/>
<puzzle name="LightUp" qualifiedClassName="edu.rpi.legup.puzzle.lightup.LightUp" fileType=".xml"/>
<puzzle name="Masyu" qualifiedClassName="edu.rpi.legup.puzzle.masyu.Masyu" fileType=".xml"/>
<puzzle name="Nurikabe" qualifiedClassName="edu.rpi.legup.puzzle.nurikabe.Nurikabe" fileType=".xml"/>
<puzzle name="ShortTruthTable" qualifiedClassName="edu.rpi.legup.puzzle.shorttruthtable.ShortTruthTable" fileType=".xml"/>
<puzzle name="Sudoku" qualifiedClassName="edu.rpi.legup.puzzle.sudoku.Sudoku" fileType=".xml"/>
<puzzle name="TreeTent" qualifiedClassName="edu.rpi.legup.puzzle.treetent.TreeTent" fileType=".xml"/>
<puzzle name="Skyscrapers" qualifiedClassName="edu.rpi.legup.puzzle.skyscrapers.Skyscrapers" fileType=".xml"/>
<puzzle name="Battleship"
qualifiedClassName="edu.rpi.legup.puzzle.battleship.Battleship"
fileType=".xml"
fileCreationDisabled="true"/>
<puzzle name="Fillapix"
qualifiedClassName="edu.rpi.legup.puzzle.fillapix.Fillapix"
fileType=".xml"
fileCreationDisabled="true"/>
<puzzle name="HeyAwake"
qualifiedClassName="edu.rpi.legup.puzzle.heyawake.Heyawake"
fileType=".xml"
fileCreationDisabled="true"/>
<puzzle name="LightUp"
qualifiedClassName="edu.rpi.legup.puzzle.lightup.LightUp"
fileType=".xml"
fileCreationDisabled="false"/>
<puzzle name="Masyu"
qualifiedClassName="edu.rpi.legup.puzzle.masyu.Masyu"
fileType=".xml"
fileCreationDisabled="true"/>
<puzzle name="Nurikabe"
qualifiedClassName="edu.rpi.legup.puzzle.nurikabe.Nurikabe"
fileType=".xml"
fileCreationDisabled="false"/>
<puzzle name="ShortTruthTable"
qualifiedClassName="edu.rpi.legup.puzzle.shorttruthtable.ShortTruthTable"
fileType=".xml"
fileCreationDisabled="true"/>
<puzzle name="Sudoku" qualifiedClassName="edu.rpi.legup.puzzle.sudoku.Sudoku"
fileType=".xml"
fileCreationDisabled="false"/>
<puzzle name="TreeTent"
qualifiedClassName="edu.rpi.legup.puzzle.treetent.TreeTent"
fileType=".xml"
fileCreationDisabled="false"/>
<puzzle name="Skyscrapers"
qualifiedClassName="edu.rpi.legup.puzzle.skyscrapers.Skyscrapers"
fileType=".xml"
fileCreationDisabled="true"/>
</puzzles>
</Legup>
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ mainClassName = 'edu.rpi.legup.Legup'
sourceCompatibility = 1.8

dependencies {
implementation 'org.jetbrains:annotations:20.1.0'
implementation 'org.jetbrains:annotations:20.1.0'
compile project(':legup-update')
compile 'com.google.firebase:firebase-admin:6.3.0'
compile 'org.apache.httpcomponents:httpclient:4.5.1'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,35 +35,43 @@ public void initializeBoard(int rows, int columns) {
public void initializeBoard(Node node) throws InvalidFileFormatException {
try {
if (!node.getNodeName().equalsIgnoreCase("board")) {
throw new InvalidFileFormatException("BattleShip Importer: cannot find board puzzleElement");
throw new InvalidFileFormatException("BattleShip Importer: " +
"cannot find board puzzleElement");
}
Element boardElement = (Element) node;
if (boardElement.getElementsByTagName("cells").getLength() == 0) {
throw new InvalidFileFormatException("BattleShip Importer: no puzzleElement found for board");
throw new InvalidFileFormatException("BattleShip Importer: " +
"no puzzleElement found for board");
}
Element dataElement = (Element) boardElement.getElementsByTagName("cells").item(0);
Element dataElement = (Element) boardElement.getElementsByTagName(
"cells").item(0);
NodeList elementDataList = dataElement.getElementsByTagName("cell");

BattleshipBoard battleShipBoard = null;
if (!boardElement.getAttribute("size").isEmpty()) {
int size = Integer.valueOf(boardElement.getAttribute("size"));
int size = Integer.valueOf(boardElement.getAttribute(
"size"));
battleShipBoard = new BattleshipBoard(size);
} else if (!boardElement.getAttribute("width").isEmpty() && !boardElement.getAttribute("height").isEmpty()) {
int width = Integer.valueOf(boardElement.getAttribute("width"));
int height = Integer.valueOf(boardElement.getAttribute("height"));
} else if (!boardElement.getAttribute("width").isEmpty()
&& !boardElement.getAttribute("height").isEmpty()) {
int width = Integer.valueOf(boardElement.getAttribute(
"width"));
int height = Integer.valueOf(boardElement.getAttribute(
"height"));
battleShipBoard = new BattleshipBoard(width, height);
}

if (battleShipBoard == null) {
throw new InvalidFileFormatException("BattleShip Importer: invalid board dimensions");
throw new InvalidFileFormatException("BattleShip Importer: " +
"invalid board dimensions");
}

int width = battleShipBoard.getWidth();
int height = battleShipBoard.getHeight();

for (int i = 0; i < elementDataList.getLength(); i++) {
BattleshipCell cell = (BattleshipCell) puzzle.getFactory().importCell(
elementDataList.item(i), battleShipBoard);
BattleshipCell cell = (BattleshipCell) puzzle.getFactory()
.importCell(elementDataList.item(i), battleShipBoard);
Point loc = cell.getLocation();
if (cell.getData() != BattleshipType.getType(0)) {
cell.setModifiable(false);
Expand All @@ -75,7 +83,8 @@ public void initializeBoard(Node node) throws InvalidFileFormatException {
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
if (battleShipBoard.getCell(x, y) == null) {
BattleshipCell cell = new BattleshipCell(BattleshipType.UNKNOWN, new Point(x, y));
BattleshipCell cell = new BattleshipCell(
BattleshipType.UNKNOWN, new Point(x, y));
cell.setIndex(y * height + x);
cell.setModifiable(true);
battleShipBoard.setCell(x, y, cell);
Expand All @@ -85,41 +94,59 @@ public void initializeBoard(Node node) throws InvalidFileFormatException {

NodeList axes = boardElement.getElementsByTagName("axis");
if (axes.getLength() != 2) {
throw new InvalidFileFormatException("BattleShip Importer: cannot find axes");
throw new InvalidFileFormatException("BattleShip Importer: " +
"cannot find axes");
}

Element axis1 = (Element) axes.item(0);
Element axis2 = (Element) axes.item(1);

if (!axis1.hasAttribute("side") || !axis1.hasAttribute("side")) {
throw new InvalidFileFormatException("BattleShip Importer: side attribute of axis not specified");
if (!axis1.hasAttribute("side") || !axis2.hasAttribute(
"side")) {
throw new InvalidFileFormatException("BattleShip Importer: " +
"side attribute of axis not specified");
}
String side1 = axis1.getAttribute("side");
String side2 = axis2.getAttribute("side");
if (side1.equalsIgnoreCase(side2) || !(side1.equalsIgnoreCase("east") || side1.equalsIgnoreCase("south")) ||
!(side2.equalsIgnoreCase("east") || side2.equalsIgnoreCase("south"))) {
throw new InvalidFileFormatException("BattleShip Importer: axes must be different and be {east | south}");
if (side1.equalsIgnoreCase(side2)
|| !(side1.equalsIgnoreCase("east")
|| side1.equalsIgnoreCase("south"))
|| !(side2.equalsIgnoreCase("east")
|| side2.equalsIgnoreCase("south"))) {
throw new InvalidFileFormatException("BattleShip Importer: " +
"axes must be different and be {east | south}");
}
NodeList eastClues = side1.equalsIgnoreCase("east") ? axis1.getElementsByTagName("clue") : axis2.getElementsByTagName("clue");
NodeList southClues = side1.equalsIgnoreCase("south") ? axis1.getElementsByTagName("clue") : axis2.getElementsByTagName("clue");

if (eastClues.getLength() != battleShipBoard.getHeight() || southClues.getLength() != battleShipBoard.getWidth()) {
throw new InvalidFileFormatException("BattleShip Importer: there must be same number of clues as the dimension of the board");
NodeList eastClues = side1.equalsIgnoreCase("east")
? axis1.getElementsByTagName("clue") :
axis2.getElementsByTagName("clue");
NodeList southClues = side1.equalsIgnoreCase("south")
? axis1.getElementsByTagName("clue") :
axis2.getElementsByTagName("clue");

if (eastClues.getLength() != battleShipBoard.getHeight()
|| southClues.getLength() != battleShipBoard.getWidth()) {
throw new InvalidFileFormatException("BattleShip Importer: " +
"there must be same number of clues as the dimension " +
"of the board");
}

for (int i = 0; i < eastClues.getLength(); i++) {
Element clue = (Element) eastClues.item(i);
int value = Integer.valueOf(clue.getAttribute("value"));
int index = BattleshipClue.colStringToColNum(clue.getAttribute("index"));
int index = BattleshipClue.colStringToColNum(
clue.getAttribute("index"));

if (index - 1 < 0 || index - 1 > battleShipBoard.getHeight()) {
throw new InvalidFileFormatException("BattleShip Importer: clue index out of bounds");
throw new InvalidFileFormatException("BattleShip Importer: " +
"clue index out of bounds");
}

if (battleShipBoard.getEast().get(index - 1) != null) {
throw new InvalidFileFormatException("BattleShip Importer: duplicate clue index");
throw new InvalidFileFormatException("BattleShip Importer: " +
"duplicate clue index");
}
battleShipBoard.getEast().set(index - 1, new BattleshipClue(value, index, BattleshipType.CLUE_EAST));
battleShipBoard.getEast().set(index - 1, new BattleshipClue(
value, index, BattleshipType.CLUE_EAST));
}

for (int i = 0; i < southClues.getLength(); i++) {
Expand All @@ -128,18 +155,22 @@ public void initializeBoard(Node node) throws InvalidFileFormatException {
int index = Integer.valueOf(clue.getAttribute("index"));

if (index - 1 < 0 || index - 1 > battleShipBoard.getWidth()) {
throw new InvalidFileFormatException("BattleShip Importer: clue index out of bounds");
throw new InvalidFileFormatException("BattleShip Importer: " +
"clue index out of bounds");
}

if (battleShipBoard.getSouth().get(index - 1) != null) {
throw new InvalidFileFormatException("BattleShip Importer: duplicate clue index");
throw new InvalidFileFormatException("BattleShip Importer: " +
"duplicate clue index");
}
battleShipBoard.getSouth().set(index - 1, new BattleshipClue(value, index, BattleshipType.CLUE_SOUTH));
battleShipBoard.getSouth().set(index - 1, new BattleshipClue(
value, index, BattleshipType.CLUE_SOUTH));
}

puzzle.setCurrentBoard(battleShipBoard);
} catch (NumberFormatException e) {
throw new InvalidFileFormatException("BattleShip Importer: unknown value where integer expected");
throw new InvalidFileFormatException("BattleShip Importer: " +
"unknown value where integer expected");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
import edu.rpi.legup.puzzle.treetent.TreeTentBoard;
import edu.rpi.legup.puzzle.treetent.TreeTentCell;
import edu.rpi.legup.puzzle.treetent.TreeTentType;
import edu.rpi.legup.puzzle.treetent.TreeTentLine;

import java.util.List;
import java.util.Iterator;

public class NoTentForTreeContradictionRule extends ContradictionRule {

Expand Down Expand Up @@ -35,6 +39,28 @@ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
if (adjTent == 0 && adjUnknown == 0) {
return null;
} else {
if(adjTent != 0)
{
List<TreeTentLine> lines = treeTentBoard.getLines();
List<TreeTentCell> adjTents = treeTentBoard.getAdjacent(cell, TreeTentType.TENT);
for(TreeTentLine l : lines)
{
Iterator<TreeTentCell> i = adjTents.iterator();
while(i.hasNext())
{
TreeTentCell t = i.next();
if (t.getLocation().equals(l.getC1().getLocation()) && !(cell.getLocation().equals(l.getC2().getLocation())))
{
i.remove();
}
if (t.getLocation().equals(l.getC2().getLocation()) && !(cell.getLocation().equals(l.getC2().getLocation())))
{
i.remove();
}
}
}
if(adjTents.size() == 0) {return null;}
}
return super.getNoContradictionMessage();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import edu.rpi.legup.puzzle.treetent.TreeTentCell;
import edu.rpi.legup.puzzle.treetent.TreeTentLine;
import edu.rpi.legup.puzzle.treetent.TreeTentType;
import java.util.ArrayList;

import java.util.List;

Expand All @@ -34,31 +35,66 @@ public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElem
if (!(puzzleElement instanceof TreeTentLine)) {
return super.getInvalidUseOfRuleMessage() + ": Lines must be created for this rule.";
}
TreeTentBoard initialBoard = (TreeTentBoard) transition.getParents().get(0).getBoard();
TreeTentLine initLine = (TreeTentLine) initialBoard.getPuzzleElement(puzzleElement);
TreeTentBoard finalBoard = (TreeTentBoard) transition.getBoard();
TreeTentLine finalLine = (TreeTentLine) finalBoard.getPuzzleElement(puzzleElement);
TreeTentCell tree, tent;
if (finalLine.getC1().getType() == TreeTentType.TREE || finalLine.getC2().getType() == TreeTentType.TENT) {
tree = finalLine.getC1();
tent = finalLine.getC2();
} else if (finalLine.getC2().getType() == TreeTentType.TREE || finalLine.getC1().getType() == TreeTentType.TENT) {
tree = finalLine.getC2();
tent = finalLine.getC1();
TreeTentBoard board = (TreeTentBoard)transition.getBoard();
TreeTentLine line = (TreeTentLine)board.getPuzzleElement(puzzleElement);
TreeTentCell tree,tent;
if (line.getC1().getType() == TreeTentType.TREE && line.getC2().getType() == TreeTentType.TENT) {
tree = line.getC1();
tent = line.getC2();
} else if (line.getC2().getType() == TreeTentType.TREE && line.getC1().getType() == TreeTentType.TENT) {
tree = line.getC2();
tent = line.getC1();
} else {
return super.getInvalidUseOfRuleMessage() + ": This line must connect a tree to a tent.";
}

if (isForced(initialBoard, tree, tent)) {
int forced = isForced(board, tree, tent, line);
if(forced == 1)
{
return null;
} else {
return super.getInvalidUseOfRuleMessage() + ": This cell is not forced to be tent.";
}
else if (forced == -1)
{
return super.getInvalidUseOfRuleMessage() + ": This tree already has a link";
}
else if (forced == -2)
{
return super.getInvalidUseOfRuleMessage() + ": This tent already has a link";
}
else
{
return super.getInvalidUseOfRuleMessage() + ": This tree and tent don't need to be linked.";
}
}

private boolean isForced(TreeTentBoard board, TreeTentCell tree, TreeTentCell tent) {
List<TreeTentCell> tents = board.getAdjacent(tree, TreeTentType.TENT);
return !tents.isEmpty();
private Integer isForced(TreeTentBoard board, TreeTentCell tree, TreeTentCell tent, TreeTentLine line)
{
List<TreeTentCell> adjTents = board.getAdjacent(tree, TreeTentType.TENT);
adjTents.remove(tent);
List<TreeTentLine> lines = board.getLines();
lines.remove(line);
for(TreeTentLine l : lines)
{
ArrayList<TreeTentCell> toRemove = new ArrayList<>();
if(l.getC1().getLocation().equals(tree.getLocation()) || l.getC2().getLocation().equals(tree.getLocation())) {return -2;}
for(TreeTentCell c : adjTents)
{
if(l.getC1().getLocation().equals(c.getLocation()))
{
if(l.getC2().getLocation().equals(tree.getLocation())) {return -1;}
toRemove.add(c);

}
else if(l.getC2().getLocation().equals(c.getLocation()))
{
if(l.getC1().getLocation().equals(tree.getLocation())) {return -1;}
toRemove.add(c);
}
}
for(TreeTentCell c : toRemove) {adjTents.remove(c);}
toRemove.clear();
}
if(adjTents.size() == 0) {return 1;}
else {return 0;}
}

/**
Expand Down
Loading